Proxy ND (RFC4389 - or a sub-set thereof). This allows the 'emulation' of bridging...
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/l2/l2_input.h>
26 #include <vnet/l2tp/l2tp.h>
27 #include <vnet/vxlan/vxlan.h>
28 #include <vnet/gre/gre.h>
29 #include <vnet/vxlan-gpe/vxlan_gpe.h>
30 #include <vnet/lisp-gpe/lisp_gpe.h>
31
32 #include <vpp/api/vpe_msg_enum.h>
33 #include <vnet/l2/l2_classify.h>
34 #include <vnet/l2/l2_vtr.h>
35 #include <vnet/classify/input_acl.h>
36 #include <vnet/classify/policer_classify.h>
37 #include <vnet/classify/flow_classify.h>
38 #include <vnet/mpls/mpls.h>
39 #include <vnet/ipsec/ipsec.h>
40 #include <vnet/ipsec/ikev2.h>
41 #include <inttypes.h>
42 #include <vnet/map/map.h>
43 #include <vnet/cop/cop.h>
44 #include <vnet/ip/ip6_hop_by_hop.h>
45 #include <vnet/ip/ip_source_and_port_range_check.h>
46 #include <vnet/policer/xlate.h>
47 #include <vnet/span/span.h>
48 #include <vnet/policer/policer.h>
49 #include <vnet/policer/police.h>
50 #include <vnet/mfib/mfib_types.h>
51
52 #include "vat/json_format.h"
53
54 #include <inttypes.h>
55 #include <sys/stat.h>
56
57 #define vl_typedefs             /* define message structures */
58 #include <vpp/api/vpe_all_api_h.h>
59 #undef vl_typedefs
60
61 /* declare message handlers for each api */
62
63 #define vl_endianfun            /* define message structures */
64 #include <vpp/api/vpe_all_api_h.h>
65 #undef vl_endianfun
66
67 /* instantiate all the print functions we know about */
68 #define vl_print(handle, ...)
69 #define vl_printfun
70 #include <vpp/api/vpe_all_api_h.h>
71 #undef vl_printfun
72
73 #define __plugin_msg_base 0
74 #include <vlibapi/vat_helper_macros.h>
75
76 f64
77 vat_time_now (vat_main_t * vam)
78 {
79 #if VPP_API_TEST_BUILTIN
80   return vlib_time_now (vam->vlib_main);
81 #else
82   return clib_time_now (&vam->clib_time);
83 #endif
84 }
85
86 void
87 errmsg (char *fmt, ...)
88 {
89   vat_main_t *vam = &vat_main;
90   va_list va;
91   u8 *s;
92
93   va_start (va, fmt);
94   s = va_format (0, fmt, &va);
95   va_end (va);
96
97   vec_add1 (s, 0);
98
99 #if VPP_API_TEST_BUILTIN
100   vlib_cli_output (vam->vlib_main, (char *) s);
101 #else
102   {
103     if (vam->ifp != stdin)
104       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
105                vam->input_line_number);
106     fformat (vam->ofp, (char *) s);
107     fflush (vam->ofp);
108   }
109 #endif
110
111   vec_free (s);
112 }
113
114 #if VPP_API_TEST_BUILTIN == 0
115 static uword
116 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
117 {
118   vat_main_t *vam = va_arg (*args, vat_main_t *);
119   u32 *result = va_arg (*args, u32 *);
120   u8 *if_name;
121   uword *p;
122
123   if (!unformat (input, "%s", &if_name))
124     return 0;
125
126   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
127   if (p == 0)
128     return 0;
129   *result = p[0];
130   return 1;
131 }
132
133 /* Parse an IP4 address %d.%d.%d.%d. */
134 uword
135 unformat_ip4_address (unformat_input_t * input, va_list * args)
136 {
137   u8 *result = va_arg (*args, u8 *);
138   unsigned a[4];
139
140   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
141     return 0;
142
143   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
144     return 0;
145
146   result[0] = a[0];
147   result[1] = a[1];
148   result[2] = a[2];
149   result[3] = a[3];
150
151   return 1;
152 }
153
154 uword
155 unformat_ethernet_address (unformat_input_t * input, va_list * args)
156 {
157   u8 *result = va_arg (*args, u8 *);
158   u32 i, a[6];
159
160   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
161                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
162     return 0;
163
164   /* Check range. */
165   for (i = 0; i < 6; i++)
166     if (a[i] >= (1 << 8))
167       return 0;
168
169   for (i = 0; i < 6; i++)
170     result[i] = a[i];
171
172   return 1;
173 }
174
175 /* Returns ethernet type as an int in host byte order. */
176 uword
177 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
178                                         va_list * args)
179 {
180   u16 *result = va_arg (*args, u16 *);
181   int type;
182
183   /* Numeric type. */
184   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
185     {
186       if (type >= (1 << 16))
187         return 0;
188       *result = type;
189       return 1;
190     }
191   return 0;
192 }
193
194 /* Parse an IP6 address. */
195 uword
196 unformat_ip6_address (unformat_input_t * input, va_list * args)
197 {
198   ip6_address_t *result = va_arg (*args, ip6_address_t *);
199   u16 hex_quads[8];
200   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
201   uword c, n_colon, double_colon_index;
202
203   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
204   double_colon_index = ARRAY_LEN (hex_quads);
205   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
206     {
207       hex_digit = 16;
208       if (c >= '0' && c <= '9')
209         hex_digit = c - '0';
210       else if (c >= 'a' && c <= 'f')
211         hex_digit = c + 10 - 'a';
212       else if (c >= 'A' && c <= 'F')
213         hex_digit = c + 10 - 'A';
214       else if (c == ':' && n_colon < 2)
215         n_colon++;
216       else
217         {
218           unformat_put_input (input);
219           break;
220         }
221
222       /* Too many hex quads. */
223       if (n_hex_quads >= ARRAY_LEN (hex_quads))
224         return 0;
225
226       if (hex_digit < 16)
227         {
228           hex_quad = (hex_quad << 4) | hex_digit;
229
230           /* Hex quad must fit in 16 bits. */
231           if (n_hex_digits >= 4)
232             return 0;
233
234           n_colon = 0;
235           n_hex_digits++;
236         }
237
238       /* Save position of :: */
239       if (n_colon == 2)
240         {
241           /* More than one :: ? */
242           if (double_colon_index < ARRAY_LEN (hex_quads))
243             return 0;
244           double_colon_index = n_hex_quads;
245         }
246
247       if (n_colon > 0 && n_hex_digits > 0)
248         {
249           hex_quads[n_hex_quads++] = hex_quad;
250           hex_quad = 0;
251           n_hex_digits = 0;
252         }
253     }
254
255   if (n_hex_digits > 0)
256     hex_quads[n_hex_quads++] = hex_quad;
257
258   {
259     word i;
260
261     /* Expand :: to appropriate number of zero hex quads. */
262     if (double_colon_index < ARRAY_LEN (hex_quads))
263       {
264         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
265
266         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
267           hex_quads[n_zero + i] = hex_quads[i];
268
269         for (i = 0; i < n_zero; i++)
270           hex_quads[double_colon_index + i] = 0;
271
272         n_hex_quads = ARRAY_LEN (hex_quads);
273       }
274
275     /* Too few hex quads given. */
276     if (n_hex_quads < ARRAY_LEN (hex_quads))
277       return 0;
278
279     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
280       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
281
282     return 1;
283   }
284 }
285
286 uword
287 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
288 {
289   u32 *r = va_arg (*args, u32 *);
290
291   if (0);
292 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
293   foreach_ipsec_policy_action
294 #undef _
295     else
296     return 0;
297   return 1;
298 }
299
300 uword
301 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
302 {
303   u32 *r = va_arg (*args, u32 *);
304
305   if (0);
306 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
307   foreach_ipsec_crypto_alg
308 #undef _
309     else
310     return 0;
311   return 1;
312 }
313
314 u8 *
315 format_ipsec_crypto_alg (u8 * s, va_list * args)
316 {
317   u32 i = va_arg (*args, u32);
318   u8 *t = 0;
319
320   switch (i)
321     {
322 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
323       foreach_ipsec_crypto_alg
324 #undef _
325     default:
326       return format (s, "unknown");
327     }
328   return format (s, "%s", t);
329 }
330
331 uword
332 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
333 {
334   u32 *r = va_arg (*args, u32 *);
335
336   if (0);
337 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
338   foreach_ipsec_integ_alg
339 #undef _
340     else
341     return 0;
342   return 1;
343 }
344
345 u8 *
346 format_ipsec_integ_alg (u8 * s, va_list * args)
347 {
348   u32 i = va_arg (*args, u32);
349   u8 *t = 0;
350
351   switch (i)
352     {
353 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
354       foreach_ipsec_integ_alg
355 #undef _
356     default:
357       return format (s, "unknown");
358     }
359   return format (s, "%s", t);
360 }
361
362 uword
363 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
364 {
365   u32 *r = va_arg (*args, u32 *);
366
367   if (0);
368 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
369   foreach_ikev2_auth_method
370 #undef _
371     else
372     return 0;
373   return 1;
374 }
375
376 uword
377 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
378 {
379   u32 *r = va_arg (*args, u32 *);
380
381   if (0);
382 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
383   foreach_ikev2_id_type
384 #undef _
385     else
386     return 0;
387   return 1;
388 }
389 #else /* VPP_API_TEST_BUILTIN == 1 */
390 static uword
391 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
392 {
393   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
394   vnet_main_t *vnm = vnet_get_main ();
395   u32 *result = va_arg (*args, u32 *);
396   u32 sw_if_index;
397
398   if (!unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
399     return 0;
400
401   *result = sw_if_index;
402   return 1;
403 }
404 #endif /* VPP_API_TEST_BUILTIN */
405
406 static uword
407 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
408 {
409   u8 *r = va_arg (*args, u8 *);
410
411   if (unformat (input, "kbps"))
412     *r = SSE2_QOS_RATE_KBPS;
413   else if (unformat (input, "pps"))
414     *r = SSE2_QOS_RATE_PPS;
415   else
416     return 0;
417   return 1;
418 }
419
420 static uword
421 unformat_policer_round_type (unformat_input_t * input, va_list * args)
422 {
423   u8 *r = va_arg (*args, u8 *);
424
425   if (unformat (input, "closest"))
426     *r = SSE2_QOS_ROUND_TO_CLOSEST;
427   else if (unformat (input, "up"))
428     *r = SSE2_QOS_ROUND_TO_UP;
429   else if (unformat (input, "down"))
430     *r = SSE2_QOS_ROUND_TO_DOWN;
431   else
432     return 0;
433   return 1;
434 }
435
436 static uword
437 unformat_policer_type (unformat_input_t * input, va_list * args)
438 {
439   u8 *r = va_arg (*args, u8 *);
440
441   if (unformat (input, "1r2c"))
442     *r = SSE2_QOS_POLICER_TYPE_1R2C;
443   else if (unformat (input, "1r3c"))
444     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
445   else if (unformat (input, "2r3c-2698"))
446     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
447   else if (unformat (input, "2r3c-4115"))
448     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
449   else if (unformat (input, "2r3c-mef5cf1"))
450     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
451   else
452     return 0;
453   return 1;
454 }
455
456 static uword
457 unformat_dscp (unformat_input_t * input, va_list * va)
458 {
459   u8 *r = va_arg (*va, u8 *);
460
461   if (0);
462 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
463   foreach_vnet_dscp
464 #undef _
465     else
466     return 0;
467   return 1;
468 }
469
470 static uword
471 unformat_policer_action_type (unformat_input_t * input, va_list * va)
472 {
473   sse2_qos_pol_action_params_st *a
474     = va_arg (*va, sse2_qos_pol_action_params_st *);
475
476   if (unformat (input, "drop"))
477     a->action_type = SSE2_QOS_ACTION_DROP;
478   else if (unformat (input, "transmit"))
479     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
480   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
481     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
482   else
483     return 0;
484   return 1;
485 }
486
487 static uword
488 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
489 {
490   u32 *r = va_arg (*va, u32 *);
491   u32 tid;
492
493   if (unformat (input, "ip4"))
494     tid = POLICER_CLASSIFY_TABLE_IP4;
495   else if (unformat (input, "ip6"))
496     tid = POLICER_CLASSIFY_TABLE_IP6;
497   else if (unformat (input, "l2"))
498     tid = POLICER_CLASSIFY_TABLE_L2;
499   else
500     return 0;
501
502   *r = tid;
503   return 1;
504 }
505
506 static uword
507 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
508 {
509   u32 *r = va_arg (*va, u32 *);
510   u32 tid;
511
512   if (unformat (input, "ip4"))
513     tid = FLOW_CLASSIFY_TABLE_IP4;
514   else if (unformat (input, "ip6"))
515     tid = FLOW_CLASSIFY_TABLE_IP6;
516   else
517     return 0;
518
519   *r = tid;
520   return 1;
521 }
522
523 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
524 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
525 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
526 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
527
528 #if (VPP_API_TEST_BUILTIN==0)
529 uword
530 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
531 {
532   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
533   mfib_itf_attribute_t attr;
534
535   old = *iflags;
536   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
537   {
538     if (unformat (input, mfib_itf_flag_long_names[attr]))
539       *iflags |= (1 << attr);
540   }
541   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
542   {
543     if (unformat (input, mfib_itf_flag_names[attr]))
544       *iflags |= (1 << attr);
545   }
546
547   return (old == *iflags ? 0 : 1);
548 }
549
550 uword
551 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
552 {
553   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
554   mfib_entry_attribute_t attr;
555
556   old = *eflags;
557   FOR_EACH_MFIB_ATTRIBUTE (attr)
558   {
559     if (unformat (input, mfib_flag_long_names[attr]))
560       *eflags |= (1 << attr);
561   }
562   FOR_EACH_MFIB_ATTRIBUTE (attr)
563   {
564     if (unformat (input, mfib_flag_names[attr]))
565       *eflags |= (1 << attr);
566   }
567
568   return (old == *eflags ? 0 : 1);
569 }
570
571 u8 *
572 format_ip4_address (u8 * s, va_list * args)
573 {
574   u8 *a = va_arg (*args, u8 *);
575   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
576 }
577
578 u8 *
579 format_ip6_address (u8 * s, va_list * args)
580 {
581   ip6_address_t *a = va_arg (*args, ip6_address_t *);
582   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
583
584   i_max_n_zero = ARRAY_LEN (a->as_u16);
585   max_n_zeros = 0;
586   i_first_zero = i_max_n_zero;
587   n_zeros = 0;
588   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
589     {
590       u32 is_zero = a->as_u16[i] == 0;
591       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
592         {
593           i_first_zero = i;
594           n_zeros = 0;
595         }
596       n_zeros += is_zero;
597       if ((!is_zero && n_zeros > max_n_zeros)
598           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
599         {
600           i_max_n_zero = i_first_zero;
601           max_n_zeros = n_zeros;
602           i_first_zero = ARRAY_LEN (a->as_u16);
603           n_zeros = 0;
604         }
605     }
606
607   last_double_colon = 0;
608   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
609     {
610       if (i == i_max_n_zero && max_n_zeros > 1)
611         {
612           s = format (s, "::");
613           i += max_n_zeros - 1;
614           last_double_colon = 1;
615         }
616       else
617         {
618           s = format (s, "%s%x",
619                       (last_double_colon || i == 0) ? "" : ":",
620                       clib_net_to_host_u16 (a->as_u16[i]));
621           last_double_colon = 0;
622         }
623     }
624
625   return s;
626 }
627
628 /* Format an IP46 address. */
629 u8 *
630 format_ip46_address (u8 * s, va_list * args)
631 {
632   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
633   ip46_type_t type = va_arg (*args, ip46_type_t);
634   int is_ip4 = 1;
635
636   switch (type)
637     {
638     case IP46_TYPE_ANY:
639       is_ip4 = ip46_address_is_ip4 (ip46);
640       break;
641     case IP46_TYPE_IP4:
642       is_ip4 = 1;
643       break;
644     case IP46_TYPE_IP6:
645       is_ip4 = 0;
646       break;
647     }
648
649   return is_ip4 ?
650     format (s, "%U", format_ip4_address, &ip46->ip4) :
651     format (s, "%U", format_ip6_address, &ip46->ip6);
652 }
653
654 u8 *
655 format_ethernet_address (u8 * s, va_list * args)
656 {
657   u8 *a = va_arg (*args, u8 *);
658
659   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
660                  a[0], a[1], a[2], a[3], a[4], a[5]);
661 }
662 #endif
663
664 static void
665 increment_v4_address (ip4_address_t * a)
666 {
667   u32 v;
668
669   v = ntohl (a->as_u32) + 1;
670   a->as_u32 = ntohl (v);
671 }
672
673 static void
674 increment_v6_address (ip6_address_t * a)
675 {
676   u64 v0, v1;
677
678   v0 = clib_net_to_host_u64 (a->as_u64[0]);
679   v1 = clib_net_to_host_u64 (a->as_u64[1]);
680
681   v1 += 1;
682   if (v1 == 0)
683     v0 += 1;
684   a->as_u64[0] = clib_net_to_host_u64 (v0);
685   a->as_u64[1] = clib_net_to_host_u64 (v1);
686 }
687
688 static void
689 increment_mac_address (u64 * mac)
690 {
691   u64 tmp = *mac;
692
693   tmp = clib_net_to_host_u64 (tmp);
694   tmp += 1 << 16;               /* skip unused (least significant) octets */
695   tmp = clib_host_to_net_u64 (tmp);
696   *mac = tmp;
697 }
698
699 static void vl_api_create_loopback_reply_t_handler
700   (vl_api_create_loopback_reply_t * mp)
701 {
702   vat_main_t *vam = &vat_main;
703   i32 retval = ntohl (mp->retval);
704
705   vam->retval = retval;
706   vam->regenerate_interface_table = 1;
707   vam->sw_if_index = ntohl (mp->sw_if_index);
708   vam->result_ready = 1;
709 }
710
711 static void vl_api_create_loopback_reply_t_handler_json
712   (vl_api_create_loopback_reply_t * mp)
713 {
714   vat_main_t *vam = &vat_main;
715   vat_json_node_t node;
716
717   vat_json_init_object (&node);
718   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
719   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
720
721   vat_json_print (vam->ofp, &node);
722   vat_json_free (&node);
723   vam->retval = ntohl (mp->retval);
724   vam->result_ready = 1;
725 }
726
727 static void vl_api_create_loopback_instance_reply_t_handler
728   (vl_api_create_loopback_instance_reply_t * mp)
729 {
730   vat_main_t *vam = &vat_main;
731   i32 retval = ntohl (mp->retval);
732
733   vam->retval = retval;
734   vam->regenerate_interface_table = 1;
735   vam->sw_if_index = ntohl (mp->sw_if_index);
736   vam->result_ready = 1;
737 }
738
739 static void vl_api_create_loopback_instance_reply_t_handler_json
740   (vl_api_create_loopback_instance_reply_t * mp)
741 {
742   vat_main_t *vam = &vat_main;
743   vat_json_node_t node;
744
745   vat_json_init_object (&node);
746   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
747   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
748
749   vat_json_print (vam->ofp, &node);
750   vat_json_free (&node);
751   vam->retval = ntohl (mp->retval);
752   vam->result_ready = 1;
753 }
754
755 static void vl_api_af_packet_create_reply_t_handler
756   (vl_api_af_packet_create_reply_t * mp)
757 {
758   vat_main_t *vam = &vat_main;
759   i32 retval = ntohl (mp->retval);
760
761   vam->retval = retval;
762   vam->regenerate_interface_table = 1;
763   vam->sw_if_index = ntohl (mp->sw_if_index);
764   vam->result_ready = 1;
765 }
766
767 static void vl_api_af_packet_create_reply_t_handler_json
768   (vl_api_af_packet_create_reply_t * mp)
769 {
770   vat_main_t *vam = &vat_main;
771   vat_json_node_t node;
772
773   vat_json_init_object (&node);
774   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
775   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
776
777   vat_json_print (vam->ofp, &node);
778   vat_json_free (&node);
779
780   vam->retval = ntohl (mp->retval);
781   vam->result_ready = 1;
782 }
783
784 static void vl_api_create_vlan_subif_reply_t_handler
785   (vl_api_create_vlan_subif_reply_t * mp)
786 {
787   vat_main_t *vam = &vat_main;
788   i32 retval = ntohl (mp->retval);
789
790   vam->retval = retval;
791   vam->regenerate_interface_table = 1;
792   vam->sw_if_index = ntohl (mp->sw_if_index);
793   vam->result_ready = 1;
794 }
795
796 static void vl_api_create_vlan_subif_reply_t_handler_json
797   (vl_api_create_vlan_subif_reply_t * mp)
798 {
799   vat_main_t *vam = &vat_main;
800   vat_json_node_t node;
801
802   vat_json_init_object (&node);
803   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
804   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
805
806   vat_json_print (vam->ofp, &node);
807   vat_json_free (&node);
808
809   vam->retval = ntohl (mp->retval);
810   vam->result_ready = 1;
811 }
812
813 static void vl_api_create_subif_reply_t_handler
814   (vl_api_create_subif_reply_t * mp)
815 {
816   vat_main_t *vam = &vat_main;
817   i32 retval = ntohl (mp->retval);
818
819   vam->retval = retval;
820   vam->regenerate_interface_table = 1;
821   vam->sw_if_index = ntohl (mp->sw_if_index);
822   vam->result_ready = 1;
823 }
824
825 static void vl_api_create_subif_reply_t_handler_json
826   (vl_api_create_subif_reply_t * mp)
827 {
828   vat_main_t *vam = &vat_main;
829   vat_json_node_t node;
830
831   vat_json_init_object (&node);
832   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
833   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
834
835   vat_json_print (vam->ofp, &node);
836   vat_json_free (&node);
837
838   vam->retval = ntohl (mp->retval);
839   vam->result_ready = 1;
840 }
841
842 static void vl_api_interface_name_renumber_reply_t_handler
843   (vl_api_interface_name_renumber_reply_t * mp)
844 {
845   vat_main_t *vam = &vat_main;
846   i32 retval = ntohl (mp->retval);
847
848   vam->retval = retval;
849   vam->regenerate_interface_table = 1;
850   vam->result_ready = 1;
851 }
852
853 static void vl_api_interface_name_renumber_reply_t_handler_json
854   (vl_api_interface_name_renumber_reply_t * mp)
855 {
856   vat_main_t *vam = &vat_main;
857   vat_json_node_t node;
858
859   vat_json_init_object (&node);
860   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
861
862   vat_json_print (vam->ofp, &node);
863   vat_json_free (&node);
864
865   vam->retval = ntohl (mp->retval);
866   vam->result_ready = 1;
867 }
868
869 /*
870  * Special-case: build the interface table, maintain
871  * the next loopback sw_if_index vbl.
872  */
873 static void vl_api_sw_interface_details_t_handler
874   (vl_api_sw_interface_details_t * mp)
875 {
876   vat_main_t *vam = &vat_main;
877   u8 *s = format (0, "%s%c", mp->interface_name, 0);
878
879   hash_set_mem (vam->sw_if_index_by_interface_name, s,
880                 ntohl (mp->sw_if_index));
881
882   /* In sub interface case, fill the sub interface table entry */
883   if (mp->sw_if_index != mp->sup_sw_if_index)
884     {
885       sw_interface_subif_t *sub = NULL;
886
887       vec_add2 (vam->sw_if_subif_table, sub, 1);
888
889       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
890       strncpy ((char *) sub->interface_name, (char *) s,
891                vec_len (sub->interface_name));
892       sub->sw_if_index = ntohl (mp->sw_if_index);
893       sub->sub_id = ntohl (mp->sub_id);
894
895       sub->sub_dot1ad = mp->sub_dot1ad;
896       sub->sub_number_of_tags = mp->sub_number_of_tags;
897       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
898       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
899       sub->sub_exact_match = mp->sub_exact_match;
900       sub->sub_default = mp->sub_default;
901       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
902       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
903
904       /* vlan tag rewrite */
905       sub->vtr_op = ntohl (mp->vtr_op);
906       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
907       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
908       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
909     }
910 }
911
912 static void vl_api_sw_interface_details_t_handler_json
913   (vl_api_sw_interface_details_t * mp)
914 {
915   vat_main_t *vam = &vat_main;
916   vat_json_node_t *node = NULL;
917
918   if (VAT_JSON_ARRAY != vam->json_tree.type)
919     {
920       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
921       vat_json_init_array (&vam->json_tree);
922     }
923   node = vat_json_array_add (&vam->json_tree);
924
925   vat_json_init_object (node);
926   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
927   vat_json_object_add_uint (node, "sup_sw_if_index",
928                             ntohl (mp->sup_sw_if_index));
929   vat_json_object_add_uint (node, "l2_address_length",
930                             ntohl (mp->l2_address_length));
931   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
932                              sizeof (mp->l2_address));
933   vat_json_object_add_string_copy (node, "interface_name",
934                                    mp->interface_name);
935   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
936   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
937   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
938   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
939   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
940   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
941   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
942   vat_json_object_add_uint (node, "sub_number_of_tags",
943                             mp->sub_number_of_tags);
944   vat_json_object_add_uint (node, "sub_outer_vlan_id",
945                             ntohs (mp->sub_outer_vlan_id));
946   vat_json_object_add_uint (node, "sub_inner_vlan_id",
947                             ntohs (mp->sub_inner_vlan_id));
948   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
949   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
950   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
951                             mp->sub_outer_vlan_id_any);
952   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
953                             mp->sub_inner_vlan_id_any);
954   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
955   vat_json_object_add_uint (node, "vtr_push_dot1q",
956                             ntohl (mp->vtr_push_dot1q));
957   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
958   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
959   if (mp->sub_dot1ah)
960     {
961       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
962                                        format (0, "%U",
963                                                format_ethernet_address,
964                                                &mp->b_dmac));
965       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
966                                        format (0, "%U",
967                                                format_ethernet_address,
968                                                &mp->b_smac));
969       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
970       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
971     }
972 }
973
974 #if VPP_API_TEST_BUILTIN == 0
975 static void vl_api_sw_interface_set_flags_t_handler
976   (vl_api_sw_interface_set_flags_t * mp)
977 {
978   vat_main_t *vam = &vat_main;
979   if (vam->interface_event_display)
980     errmsg ("interface flags: sw_if_index %d %s %s",
981             ntohl (mp->sw_if_index),
982             mp->admin_up_down ? "admin-up" : "admin-down",
983             mp->link_up_down ? "link-up" : "link-down");
984 }
985 #endif
986
987 static void vl_api_sw_interface_set_flags_t_handler_json
988   (vl_api_sw_interface_set_flags_t * mp)
989 {
990   /* JSON output not supported */
991 }
992
993 static void
994 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
995 {
996   vat_main_t *vam = &vat_main;
997   i32 retval = ntohl (mp->retval);
998
999   vam->retval = retval;
1000   vam->shmem_result = (u8 *) mp->reply_in_shmem;
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 = (u8 *) (mp->reply_in_shmem);
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: address %U new mac %U sw_if_index %d",
1259           mp->mac_ip ? "mac/ip binding" : "address resolution",
1260           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: address %U new mac %U sw_if_index %d",
1275           mp->mac_ip ? "mac/ip binding" : "address resolution",
1276           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 /*
1287  * Special-case: build the bridge domain table, maintain
1288  * the next bd id vbl.
1289  */
1290 static void vl_api_bridge_domain_details_t_handler
1291   (vl_api_bridge_domain_details_t * mp)
1292 {
1293   vat_main_t *vam = &vat_main;
1294   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1295
1296   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1297          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1298
1299   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1300          ntohl (mp->bd_id), mp->learn, mp->forward,
1301          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1302
1303   if (n_sw_ifs)
1304     print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG", "Interface Name");
1305 }
1306
1307 static void vl_api_bridge_domain_details_t_handler_json
1308   (vl_api_bridge_domain_details_t * mp)
1309 {
1310   vat_main_t *vam = &vat_main;
1311   vat_json_node_t *node, *array = NULL;
1312
1313   if (VAT_JSON_ARRAY != vam->json_tree.type)
1314     {
1315       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1316       vat_json_init_array (&vam->json_tree);
1317     }
1318   node = vat_json_array_add (&vam->json_tree);
1319
1320   vat_json_init_object (node);
1321   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1322   vat_json_object_add_uint (node, "flood", mp->flood);
1323   vat_json_object_add_uint (node, "forward", mp->forward);
1324   vat_json_object_add_uint (node, "learn", mp->learn);
1325   vat_json_object_add_uint (node, "bvi_sw_if_index",
1326                             ntohl (mp->bvi_sw_if_index));
1327   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1328   array = vat_json_object_add (node, "sw_if");
1329   vat_json_init_array (array);
1330 }
1331
1332 /*
1333  * Special-case: build the bridge domain sw if table.
1334  */
1335 static void vl_api_bridge_domain_sw_if_details_t_handler
1336   (vl_api_bridge_domain_sw_if_details_t * mp)
1337 {
1338   vat_main_t *vam = &vat_main;
1339   hash_pair_t *p;
1340   u8 *sw_if_name = 0;
1341   u32 sw_if_index;
1342
1343   sw_if_index = ntohl (mp->sw_if_index);
1344   /* *INDENT-OFF* */
1345   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1346   ({
1347     if ((u32) p->value[0] == sw_if_index)
1348       {
1349         sw_if_name = (u8 *)(p->key);
1350         break;
1351       }
1352   }));
1353   /* *INDENT-ON* */
1354
1355   print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1356          mp->shg, sw_if_name ? (char *) sw_if_name :
1357          "sw_if_index not found!");
1358 }
1359
1360 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1361   (vl_api_bridge_domain_sw_if_details_t * mp)
1362 {
1363   vat_main_t *vam = &vat_main;
1364   vat_json_node_t *node = NULL;
1365   uword last_index = 0;
1366
1367   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1368   ASSERT (vec_len (vam->json_tree.array) >= 1);
1369   last_index = vec_len (vam->json_tree.array) - 1;
1370   node = &vam->json_tree.array[last_index];
1371   node = vat_json_object_get_element (node, "sw_if");
1372   ASSERT (NULL != node);
1373   node = vat_json_array_add (node);
1374
1375   vat_json_init_object (node);
1376   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1377   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1378   vat_json_object_add_uint (node, "shg", mp->shg);
1379 }
1380
1381 static void vl_api_control_ping_reply_t_handler
1382   (vl_api_control_ping_reply_t * mp)
1383 {
1384   vat_main_t *vam = &vat_main;
1385   i32 retval = ntohl (mp->retval);
1386   if (vam->async_mode)
1387     {
1388       vam->async_errors += (retval < 0);
1389     }
1390   else
1391     {
1392       vam->retval = retval;
1393       vam->result_ready = 1;
1394     }
1395 }
1396
1397 static void vl_api_control_ping_reply_t_handler_json
1398   (vl_api_control_ping_reply_t * mp)
1399 {
1400   vat_main_t *vam = &vat_main;
1401   i32 retval = ntohl (mp->retval);
1402
1403   if (VAT_JSON_NONE != vam->json_tree.type)
1404     {
1405       vat_json_print (vam->ofp, &vam->json_tree);
1406       vat_json_free (&vam->json_tree);
1407       vam->json_tree.type = VAT_JSON_NONE;
1408     }
1409   else
1410     {
1411       /* just print [] */
1412       vat_json_init_array (&vam->json_tree);
1413       vat_json_print (vam->ofp, &vam->json_tree);
1414       vam->json_tree.type = VAT_JSON_NONE;
1415     }
1416
1417   vam->retval = retval;
1418   vam->result_ready = 1;
1419 }
1420
1421 static void
1422 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1423 {
1424   vat_main_t *vam = &vat_main;
1425   i32 retval = ntohl (mp->retval);
1426   if (vam->async_mode)
1427     {
1428       vam->async_errors += (retval < 0);
1429     }
1430   else
1431     {
1432       vam->retval = retval;
1433       vam->result_ready = 1;
1434     }
1435 }
1436
1437 static void vl_api_l2_flags_reply_t_handler_json
1438   (vl_api_l2_flags_reply_t * mp)
1439 {
1440   vat_main_t *vam = &vat_main;
1441   vat_json_node_t node;
1442
1443   vat_json_init_object (&node);
1444   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1445   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1446                             ntohl (mp->resulting_feature_bitmap));
1447
1448   vat_json_print (vam->ofp, &node);
1449   vat_json_free (&node);
1450
1451   vam->retval = ntohl (mp->retval);
1452   vam->result_ready = 1;
1453 }
1454
1455 static void vl_api_bridge_flags_reply_t_handler
1456   (vl_api_bridge_flags_reply_t * mp)
1457 {
1458   vat_main_t *vam = &vat_main;
1459   i32 retval = ntohl (mp->retval);
1460   if (vam->async_mode)
1461     {
1462       vam->async_errors += (retval < 0);
1463     }
1464   else
1465     {
1466       vam->retval = retval;
1467       vam->result_ready = 1;
1468     }
1469 }
1470
1471 static void vl_api_bridge_flags_reply_t_handler_json
1472   (vl_api_bridge_flags_reply_t * mp)
1473 {
1474   vat_main_t *vam = &vat_main;
1475   vat_json_node_t node;
1476
1477   vat_json_init_object (&node);
1478   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1479   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1480                             ntohl (mp->resulting_feature_bitmap));
1481
1482   vat_json_print (vam->ofp, &node);
1483   vat_json_free (&node);
1484
1485   vam->retval = ntohl (mp->retval);
1486   vam->result_ready = 1;
1487 }
1488
1489 static void vl_api_tap_connect_reply_t_handler
1490   (vl_api_tap_connect_reply_t * mp)
1491 {
1492   vat_main_t *vam = &vat_main;
1493   i32 retval = ntohl (mp->retval);
1494   if (vam->async_mode)
1495     {
1496       vam->async_errors += (retval < 0);
1497     }
1498   else
1499     {
1500       vam->retval = retval;
1501       vam->sw_if_index = ntohl (mp->sw_if_index);
1502       vam->result_ready = 1;
1503     }
1504
1505 }
1506
1507 static void vl_api_tap_connect_reply_t_handler_json
1508   (vl_api_tap_connect_reply_t * mp)
1509 {
1510   vat_main_t *vam = &vat_main;
1511   vat_json_node_t node;
1512
1513   vat_json_init_object (&node);
1514   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1515   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1516
1517   vat_json_print (vam->ofp, &node);
1518   vat_json_free (&node);
1519
1520   vam->retval = ntohl (mp->retval);
1521   vam->result_ready = 1;
1522
1523 }
1524
1525 static void
1526 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1527 {
1528   vat_main_t *vam = &vat_main;
1529   i32 retval = ntohl (mp->retval);
1530   if (vam->async_mode)
1531     {
1532       vam->async_errors += (retval < 0);
1533     }
1534   else
1535     {
1536       vam->retval = retval;
1537       vam->sw_if_index = ntohl (mp->sw_if_index);
1538       vam->result_ready = 1;
1539     }
1540 }
1541
1542 static void vl_api_tap_modify_reply_t_handler_json
1543   (vl_api_tap_modify_reply_t * mp)
1544 {
1545   vat_main_t *vam = &vat_main;
1546   vat_json_node_t node;
1547
1548   vat_json_init_object (&node);
1549   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1550   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1551
1552   vat_json_print (vam->ofp, &node);
1553   vat_json_free (&node);
1554
1555   vam->retval = ntohl (mp->retval);
1556   vam->result_ready = 1;
1557 }
1558
1559 static void
1560 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1561 {
1562   vat_main_t *vam = &vat_main;
1563   i32 retval = ntohl (mp->retval);
1564   if (vam->async_mode)
1565     {
1566       vam->async_errors += (retval < 0);
1567     }
1568   else
1569     {
1570       vam->retval = retval;
1571       vam->result_ready = 1;
1572     }
1573 }
1574
1575 static void vl_api_tap_delete_reply_t_handler_json
1576   (vl_api_tap_delete_reply_t * mp)
1577 {
1578   vat_main_t *vam = &vat_main;
1579   vat_json_node_t node;
1580
1581   vat_json_init_object (&node);
1582   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1583
1584   vat_json_print (vam->ofp, &node);
1585   vat_json_free (&node);
1586
1587   vam->retval = ntohl (mp->retval);
1588   vam->result_ready = 1;
1589 }
1590
1591 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1592   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1593 {
1594   vat_main_t *vam = &vat_main;
1595   i32 retval = ntohl (mp->retval);
1596   if (vam->async_mode)
1597     {
1598       vam->async_errors += (retval < 0);
1599     }
1600   else
1601     {
1602       vam->retval = retval;
1603       vam->result_ready = 1;
1604     }
1605 }
1606
1607 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1608   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1609 {
1610   vat_main_t *vam = &vat_main;
1611   vat_json_node_t node;
1612
1613   vat_json_init_object (&node);
1614   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1615   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1616                             ntohl (mp->sw_if_index));
1617
1618   vat_json_print (vam->ofp, &node);
1619   vat_json_free (&node);
1620
1621   vam->retval = ntohl (mp->retval);
1622   vam->result_ready = 1;
1623 }
1624
1625 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1626   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1627 {
1628   vat_main_t *vam = &vat_main;
1629   i32 retval = ntohl (mp->retval);
1630   if (vam->async_mode)
1631     {
1632       vam->async_errors += (retval < 0);
1633     }
1634   else
1635     {
1636       vam->retval = retval;
1637       vam->sw_if_index = ntohl (mp->sw_if_index);
1638       vam->result_ready = 1;
1639     }
1640 }
1641
1642 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1643   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1644 {
1645   vat_main_t *vam = &vat_main;
1646   vat_json_node_t node;
1647
1648   vat_json_init_object (&node);
1649   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1650   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1651
1652   vat_json_print (vam->ofp, &node);
1653   vat_json_free (&node);
1654
1655   vam->retval = ntohl (mp->retval);
1656   vam->result_ready = 1;
1657 }
1658
1659
1660 static void vl_api_one_add_del_locator_set_reply_t_handler
1661   (vl_api_one_add_del_locator_set_reply_t * mp)
1662 {
1663   vat_main_t *vam = &vat_main;
1664   i32 retval = ntohl (mp->retval);
1665   if (vam->async_mode)
1666     {
1667       vam->async_errors += (retval < 0);
1668     }
1669   else
1670     {
1671       vam->retval = retval;
1672       vam->result_ready = 1;
1673     }
1674 }
1675
1676 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1677   (vl_api_one_add_del_locator_set_reply_t * mp)
1678 {
1679   vat_main_t *vam = &vat_main;
1680   vat_json_node_t node;
1681
1682   vat_json_init_object (&node);
1683   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1684   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1685
1686   vat_json_print (vam->ofp, &node);
1687   vat_json_free (&node);
1688
1689   vam->retval = ntohl (mp->retval);
1690   vam->result_ready = 1;
1691 }
1692
1693 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1694   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1695 {
1696   vat_main_t *vam = &vat_main;
1697   i32 retval = ntohl (mp->retval);
1698   if (vam->async_mode)
1699     {
1700       vam->async_errors += (retval < 0);
1701     }
1702   else
1703     {
1704       vam->retval = retval;
1705       vam->sw_if_index = ntohl (mp->sw_if_index);
1706       vam->result_ready = 1;
1707     }
1708 }
1709
1710 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1711   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1712 {
1713   vat_main_t *vam = &vat_main;
1714   vat_json_node_t node;
1715
1716   vat_json_init_object (&node);
1717   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1718   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1719
1720   vat_json_print (vam->ofp, &node);
1721   vat_json_free (&node);
1722
1723   vam->retval = ntohl (mp->retval);
1724   vam->result_ready = 1;
1725 }
1726
1727 static void vl_api_gre_add_del_tunnel_reply_t_handler
1728   (vl_api_gre_add_del_tunnel_reply_t * mp)
1729 {
1730   vat_main_t *vam = &vat_main;
1731   i32 retval = ntohl (mp->retval);
1732   if (vam->async_mode)
1733     {
1734       vam->async_errors += (retval < 0);
1735     }
1736   else
1737     {
1738       vam->retval = retval;
1739       vam->sw_if_index = ntohl (mp->sw_if_index);
1740       vam->result_ready = 1;
1741     }
1742 }
1743
1744 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1745   (vl_api_gre_add_del_tunnel_reply_t * mp)
1746 {
1747   vat_main_t *vam = &vat_main;
1748   vat_json_node_t node;
1749
1750   vat_json_init_object (&node);
1751   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1752   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1753
1754   vat_json_print (vam->ofp, &node);
1755   vat_json_free (&node);
1756
1757   vam->retval = ntohl (mp->retval);
1758   vam->result_ready = 1;
1759 }
1760
1761 static void vl_api_create_vhost_user_if_reply_t_handler
1762   (vl_api_create_vhost_user_if_reply_t * mp)
1763 {
1764   vat_main_t *vam = &vat_main;
1765   i32 retval = ntohl (mp->retval);
1766   if (vam->async_mode)
1767     {
1768       vam->async_errors += (retval < 0);
1769     }
1770   else
1771     {
1772       vam->retval = retval;
1773       vam->sw_if_index = ntohl (mp->sw_if_index);
1774       vam->result_ready = 1;
1775     }
1776 }
1777
1778 static void vl_api_create_vhost_user_if_reply_t_handler_json
1779   (vl_api_create_vhost_user_if_reply_t * mp)
1780 {
1781   vat_main_t *vam = &vat_main;
1782   vat_json_node_t node;
1783
1784   vat_json_init_object (&node);
1785   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1786   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1787
1788   vat_json_print (vam->ofp, &node);
1789   vat_json_free (&node);
1790
1791   vam->retval = ntohl (mp->retval);
1792   vam->result_ready = 1;
1793 }
1794
1795 static void vl_api_ip_address_details_t_handler
1796   (vl_api_ip_address_details_t * mp)
1797 {
1798   vat_main_t *vam = &vat_main;
1799   static ip_address_details_t empty_ip_address_details = { {0} };
1800   ip_address_details_t *address = NULL;
1801   ip_details_t *current_ip_details = NULL;
1802   ip_details_t *details = NULL;
1803
1804   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1805
1806   if (!details || vam->current_sw_if_index >= vec_len (details)
1807       || !details[vam->current_sw_if_index].present)
1808     {
1809       errmsg ("ip address details arrived but not stored");
1810       errmsg ("ip_dump should be called first");
1811       return;
1812     }
1813
1814   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1815
1816 #define addresses (current_ip_details->addr)
1817
1818   vec_validate_init_empty (addresses, vec_len (addresses),
1819                            empty_ip_address_details);
1820
1821   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1822
1823   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1824   address->prefix_length = mp->prefix_length;
1825 #undef addresses
1826 }
1827
1828 static void vl_api_ip_address_details_t_handler_json
1829   (vl_api_ip_address_details_t * mp)
1830 {
1831   vat_main_t *vam = &vat_main;
1832   vat_json_node_t *node = NULL;
1833   struct in6_addr ip6;
1834   struct in_addr ip4;
1835
1836   if (VAT_JSON_ARRAY != vam->json_tree.type)
1837     {
1838       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1839       vat_json_init_array (&vam->json_tree);
1840     }
1841   node = vat_json_array_add (&vam->json_tree);
1842
1843   vat_json_init_object (node);
1844   if (vam->is_ipv6)
1845     {
1846       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1847       vat_json_object_add_ip6 (node, "ip", ip6);
1848     }
1849   else
1850     {
1851       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1852       vat_json_object_add_ip4 (node, "ip", ip4);
1853     }
1854   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1855 }
1856
1857 static void
1858 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1859 {
1860   vat_main_t *vam = &vat_main;
1861   static ip_details_t empty_ip_details = { 0 };
1862   ip_details_t *ip = NULL;
1863   u32 sw_if_index = ~0;
1864
1865   sw_if_index = ntohl (mp->sw_if_index);
1866
1867   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1868                            sw_if_index, empty_ip_details);
1869
1870   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1871                          sw_if_index);
1872
1873   ip->present = 1;
1874 }
1875
1876 static void
1877 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1878 {
1879   vat_main_t *vam = &vat_main;
1880
1881   if (VAT_JSON_ARRAY != vam->json_tree.type)
1882     {
1883       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1884       vat_json_init_array (&vam->json_tree);
1885     }
1886   vat_json_array_add_uint (&vam->json_tree,
1887                            clib_net_to_host_u32 (mp->sw_if_index));
1888 }
1889
1890 static void vl_api_map_domain_details_t_handler_json
1891   (vl_api_map_domain_details_t * mp)
1892 {
1893   vat_json_node_t *node = NULL;
1894   vat_main_t *vam = &vat_main;
1895   struct in6_addr ip6;
1896   struct in_addr ip4;
1897
1898   if (VAT_JSON_ARRAY != vam->json_tree.type)
1899     {
1900       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1901       vat_json_init_array (&vam->json_tree);
1902     }
1903
1904   node = vat_json_array_add (&vam->json_tree);
1905   vat_json_init_object (node);
1906
1907   vat_json_object_add_uint (node, "domain_index",
1908                             clib_net_to_host_u32 (mp->domain_index));
1909   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1910   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1911   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1912   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1913   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1914   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1915   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1916   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1917   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1918   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1919   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1920   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1921   vat_json_object_add_uint (node, "flags", mp->flags);
1922   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1923   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1924 }
1925
1926 static void vl_api_map_domain_details_t_handler
1927   (vl_api_map_domain_details_t * mp)
1928 {
1929   vat_main_t *vam = &vat_main;
1930
1931   if (mp->is_translation)
1932     {
1933       print (vam->ofp,
1934              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
1935              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1936              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1937              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1938              clib_net_to_host_u32 (mp->domain_index));
1939     }
1940   else
1941     {
1942       print (vam->ofp,
1943              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
1944              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1945              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1946              format_ip6_address, mp->ip6_src,
1947              clib_net_to_host_u32 (mp->domain_index));
1948     }
1949   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
1950          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1951          mp->is_translation ? "map-t" : "");
1952 }
1953
1954 static void vl_api_map_rule_details_t_handler_json
1955   (vl_api_map_rule_details_t * mp)
1956 {
1957   struct in6_addr ip6;
1958   vat_json_node_t *node = NULL;
1959   vat_main_t *vam = &vat_main;
1960
1961   if (VAT_JSON_ARRAY != vam->json_tree.type)
1962     {
1963       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1964       vat_json_init_array (&vam->json_tree);
1965     }
1966
1967   node = vat_json_array_add (&vam->json_tree);
1968   vat_json_init_object (node);
1969
1970   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1971   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1972   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1973 }
1974
1975 static void
1976 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1977 {
1978   vat_main_t *vam = &vat_main;
1979   print (vam->ofp, " %d (psid) %U (ip6-dst)",
1980          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1981 }
1982
1983 static void
1984 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1985 {
1986   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1987           "router_addr %U host_mac %U",
1988           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1989           format_ip4_address, &mp->host_address,
1990           format_ip4_address, &mp->router_address,
1991           format_ethernet_address, mp->host_mac);
1992 }
1993
1994 static void vl_api_dhcp_compl_event_t_handler_json
1995   (vl_api_dhcp_compl_event_t * mp)
1996 {
1997   /* JSON output not supported */
1998 }
1999
2000 static void
2001 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2002                               u32 counter)
2003 {
2004   vat_main_t *vam = &vat_main;
2005   static u64 default_counter = 0;
2006
2007   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2008                            NULL);
2009   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2010                            sw_if_index, default_counter);
2011   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2012 }
2013
2014 static void
2015 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2016                                 interface_counter_t counter)
2017 {
2018   vat_main_t *vam = &vat_main;
2019   static interface_counter_t default_counter = { 0, };
2020
2021   vec_validate_init_empty (vam->combined_interface_counters,
2022                            vnet_counter_type, NULL);
2023   vec_validate_init_empty (vam->combined_interface_counters
2024                            [vnet_counter_type], sw_if_index, default_counter);
2025   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2026 }
2027
2028 static void vl_api_vnet_interface_counters_t_handler
2029   (vl_api_vnet_interface_counters_t * mp)
2030 {
2031   /* not supported */
2032 }
2033
2034 static void vl_api_vnet_interface_counters_t_handler_json
2035   (vl_api_vnet_interface_counters_t * mp)
2036 {
2037   interface_counter_t counter;
2038   vlib_counter_t *v;
2039   u64 *v_packets;
2040   u64 packets;
2041   u32 count;
2042   u32 first_sw_if_index;
2043   int i;
2044
2045   count = ntohl (mp->count);
2046   first_sw_if_index = ntohl (mp->first_sw_if_index);
2047
2048   if (!mp->is_combined)
2049     {
2050       v_packets = (u64 *) & mp->data;
2051       for (i = 0; i < count; i++)
2052         {
2053           packets =
2054             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2055           set_simple_interface_counter (mp->vnet_counter_type,
2056                                         first_sw_if_index + i, packets);
2057           v_packets++;
2058         }
2059     }
2060   else
2061     {
2062       v = (vlib_counter_t *) & mp->data;
2063       for (i = 0; i < count; i++)
2064         {
2065           counter.packets =
2066             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2067           counter.bytes =
2068             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2069           set_combined_interface_counter (mp->vnet_counter_type,
2070                                           first_sw_if_index + i, counter);
2071           v++;
2072         }
2073     }
2074 }
2075
2076 static u32
2077 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2078 {
2079   vat_main_t *vam = &vat_main;
2080   u32 i;
2081
2082   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2083     {
2084       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2085         {
2086           return i;
2087         }
2088     }
2089   return ~0;
2090 }
2091
2092 static u32
2093 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2094 {
2095   vat_main_t *vam = &vat_main;
2096   u32 i;
2097
2098   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2099     {
2100       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2101         {
2102           return i;
2103         }
2104     }
2105   return ~0;
2106 }
2107
2108 static void vl_api_vnet_ip4_fib_counters_t_handler
2109   (vl_api_vnet_ip4_fib_counters_t * mp)
2110 {
2111   /* not supported */
2112 }
2113
2114 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2115   (vl_api_vnet_ip4_fib_counters_t * mp)
2116 {
2117   vat_main_t *vam = &vat_main;
2118   vl_api_ip4_fib_counter_t *v;
2119   ip4_fib_counter_t *counter;
2120   struct in_addr ip4;
2121   u32 vrf_id;
2122   u32 vrf_index;
2123   u32 count;
2124   int i;
2125
2126   vrf_id = ntohl (mp->vrf_id);
2127   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2128   if (~0 == vrf_index)
2129     {
2130       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2131       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2132       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2133       vec_validate (vam->ip4_fib_counters, vrf_index);
2134       vam->ip4_fib_counters[vrf_index] = NULL;
2135     }
2136
2137   vec_free (vam->ip4_fib_counters[vrf_index]);
2138   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2139   count = ntohl (mp->count);
2140   for (i = 0; i < count; i++)
2141     {
2142       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2143       counter = &vam->ip4_fib_counters[vrf_index][i];
2144       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2145       counter->address = ip4;
2146       counter->address_length = v->address_length;
2147       counter->packets = clib_net_to_host_u64 (v->packets);
2148       counter->bytes = clib_net_to_host_u64 (v->bytes);
2149       v++;
2150     }
2151 }
2152
2153 static void vl_api_vnet_ip4_nbr_counters_t_handler
2154   (vl_api_vnet_ip4_nbr_counters_t * mp)
2155 {
2156   /* not supported */
2157 }
2158
2159 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2160   (vl_api_vnet_ip4_nbr_counters_t * mp)
2161 {
2162   vat_main_t *vam = &vat_main;
2163   vl_api_ip4_nbr_counter_t *v;
2164   ip4_nbr_counter_t *counter;
2165   u32 sw_if_index;
2166   u32 count;
2167   int i;
2168
2169   sw_if_index = ntohl (mp->sw_if_index);
2170   count = ntohl (mp->count);
2171   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2172
2173   if (mp->begin)
2174     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2175
2176   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2177   for (i = 0; i < count; i++)
2178     {
2179       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2180       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2181       counter->address.s_addr = v->address;
2182       counter->packets = clib_net_to_host_u64 (v->packets);
2183       counter->bytes = clib_net_to_host_u64 (v->bytes);
2184       counter->linkt = v->link_type;
2185       v++;
2186     }
2187 }
2188
2189 static void vl_api_vnet_ip6_fib_counters_t_handler
2190   (vl_api_vnet_ip6_fib_counters_t * mp)
2191 {
2192   /* not supported */
2193 }
2194
2195 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2196   (vl_api_vnet_ip6_fib_counters_t * mp)
2197 {
2198   vat_main_t *vam = &vat_main;
2199   vl_api_ip6_fib_counter_t *v;
2200   ip6_fib_counter_t *counter;
2201   struct in6_addr ip6;
2202   u32 vrf_id;
2203   u32 vrf_index;
2204   u32 count;
2205   int i;
2206
2207   vrf_id = ntohl (mp->vrf_id);
2208   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2209   if (~0 == vrf_index)
2210     {
2211       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2212       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2213       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2214       vec_validate (vam->ip6_fib_counters, vrf_index);
2215       vam->ip6_fib_counters[vrf_index] = NULL;
2216     }
2217
2218   vec_free (vam->ip6_fib_counters[vrf_index]);
2219   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2220   count = ntohl (mp->count);
2221   for (i = 0; i < count; i++)
2222     {
2223       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2224       counter = &vam->ip6_fib_counters[vrf_index][i];
2225       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2226       counter->address = ip6;
2227       counter->address_length = v->address_length;
2228       counter->packets = clib_net_to_host_u64 (v->packets);
2229       counter->bytes = clib_net_to_host_u64 (v->bytes);
2230       v++;
2231     }
2232 }
2233
2234 static void vl_api_vnet_ip6_nbr_counters_t_handler
2235   (vl_api_vnet_ip6_nbr_counters_t * mp)
2236 {
2237   /* not supported */
2238 }
2239
2240 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2241   (vl_api_vnet_ip6_nbr_counters_t * mp)
2242 {
2243   vat_main_t *vam = &vat_main;
2244   vl_api_ip6_nbr_counter_t *v;
2245   ip6_nbr_counter_t *counter;
2246   struct in6_addr ip6;
2247   u32 sw_if_index;
2248   u32 count;
2249   int i;
2250
2251   sw_if_index = ntohl (mp->sw_if_index);
2252   count = ntohl (mp->count);
2253   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2254
2255   if (mp->begin)
2256     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2257
2258   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2259   for (i = 0; i < count; i++)
2260     {
2261       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2262       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2263       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2264       counter->address = ip6;
2265       counter->packets = clib_net_to_host_u64 (v->packets);
2266       counter->bytes = clib_net_to_host_u64 (v->bytes);
2267       v++;
2268     }
2269 }
2270
2271 static void vl_api_get_first_msg_id_reply_t_handler
2272   (vl_api_get_first_msg_id_reply_t * mp)
2273 {
2274   vat_main_t *vam = &vat_main;
2275   i32 retval = ntohl (mp->retval);
2276
2277   if (vam->async_mode)
2278     {
2279       vam->async_errors += (retval < 0);
2280     }
2281   else
2282     {
2283       vam->retval = retval;
2284       vam->result_ready = 1;
2285     }
2286   if (retval >= 0)
2287     {
2288       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2289     }
2290 }
2291
2292 static void vl_api_get_first_msg_id_reply_t_handler_json
2293   (vl_api_get_first_msg_id_reply_t * mp)
2294 {
2295   vat_main_t *vam = &vat_main;
2296   vat_json_node_t node;
2297
2298   vat_json_init_object (&node);
2299   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2300   vat_json_object_add_uint (&node, "first_msg_id",
2301                             (uint) ntohs (mp->first_msg_id));
2302
2303   vat_json_print (vam->ofp, &node);
2304   vat_json_free (&node);
2305
2306   vam->retval = ntohl (mp->retval);
2307   vam->result_ready = 1;
2308 }
2309
2310 static void vl_api_get_node_graph_reply_t_handler
2311   (vl_api_get_node_graph_reply_t * mp)
2312 {
2313   vat_main_t *vam = &vat_main;
2314   api_main_t *am = &api_main;
2315   i32 retval = ntohl (mp->retval);
2316   u8 *pvt_copy, *reply;
2317   void *oldheap;
2318   vlib_node_t *node;
2319   int i;
2320
2321   if (vam->async_mode)
2322     {
2323       vam->async_errors += (retval < 0);
2324     }
2325   else
2326     {
2327       vam->retval = retval;
2328       vam->result_ready = 1;
2329     }
2330
2331   /* "Should never happen..." */
2332   if (retval != 0)
2333     return;
2334
2335   reply = (u8 *) (mp->reply_in_shmem);
2336   pvt_copy = vec_dup (reply);
2337
2338   /* Toss the shared-memory original... */
2339   pthread_mutex_lock (&am->vlib_rp->mutex);
2340   oldheap = svm_push_data_heap (am->vlib_rp);
2341
2342   vec_free (reply);
2343
2344   svm_pop_heap (oldheap);
2345   pthread_mutex_unlock (&am->vlib_rp->mutex);
2346
2347   if (vam->graph_nodes)
2348     {
2349       hash_free (vam->graph_node_index_by_name);
2350
2351       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2352         {
2353           node = vam->graph_nodes[i];
2354           vec_free (node->name);
2355           vec_free (node->next_nodes);
2356           vec_free (node);
2357         }
2358       vec_free (vam->graph_nodes);
2359     }
2360
2361   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2362   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2363   vec_free (pvt_copy);
2364
2365   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2366     {
2367       node = vam->graph_nodes[i];
2368       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2369     }
2370 }
2371
2372 static void vl_api_get_node_graph_reply_t_handler_json
2373   (vl_api_get_node_graph_reply_t * mp)
2374 {
2375   vat_main_t *vam = &vat_main;
2376   api_main_t *am = &api_main;
2377   void *oldheap;
2378   vat_json_node_t node;
2379   u8 *reply;
2380
2381   /* $$$$ make this real? */
2382   vat_json_init_object (&node);
2383   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2384   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2385
2386   reply = (u8 *) (mp->reply_in_shmem);
2387
2388   /* Toss the shared-memory original... */
2389   pthread_mutex_lock (&am->vlib_rp->mutex);
2390   oldheap = svm_push_data_heap (am->vlib_rp);
2391
2392   vec_free (reply);
2393
2394   svm_pop_heap (oldheap);
2395   pthread_mutex_unlock (&am->vlib_rp->mutex);
2396
2397   vat_json_print (vam->ofp, &node);
2398   vat_json_free (&node);
2399
2400   vam->retval = ntohl (mp->retval);
2401   vam->result_ready = 1;
2402 }
2403
2404 static void
2405 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2406 {
2407   vat_main_t *vam = &vat_main;
2408   u8 *s = 0;
2409
2410   if (mp->local)
2411     {
2412       s = format (s, "%=16d%=16d%=16d",
2413                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2414     }
2415   else
2416     {
2417       s = format (s, "%=16U%=16d%=16d",
2418                   mp->is_ipv6 ? format_ip6_address :
2419                   format_ip4_address,
2420                   mp->ip_address, mp->priority, mp->weight);
2421     }
2422
2423   print (vam->ofp, "%v", s);
2424   vec_free (s);
2425 }
2426
2427 static void
2428 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2429 {
2430   vat_main_t *vam = &vat_main;
2431   vat_json_node_t *node = NULL;
2432   struct in6_addr ip6;
2433   struct in_addr ip4;
2434
2435   if (VAT_JSON_ARRAY != vam->json_tree.type)
2436     {
2437       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2438       vat_json_init_array (&vam->json_tree);
2439     }
2440   node = vat_json_array_add (&vam->json_tree);
2441   vat_json_init_object (node);
2442
2443   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2444   vat_json_object_add_uint (node, "priority", mp->priority);
2445   vat_json_object_add_uint (node, "weight", mp->weight);
2446
2447   if (mp->local)
2448     vat_json_object_add_uint (node, "sw_if_index",
2449                               clib_net_to_host_u32 (mp->sw_if_index));
2450   else
2451     {
2452       if (mp->is_ipv6)
2453         {
2454           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2455           vat_json_object_add_ip6 (node, "address", ip6);
2456         }
2457       else
2458         {
2459           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2460           vat_json_object_add_ip4 (node, "address", ip4);
2461         }
2462     }
2463 }
2464
2465 static void
2466 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2467                                           mp)
2468 {
2469   vat_main_t *vam = &vat_main;
2470   u8 *ls_name = 0;
2471
2472   ls_name = format (0, "%s", mp->ls_name);
2473
2474   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2475          ls_name);
2476   vec_free (ls_name);
2477 }
2478
2479 static void
2480   vl_api_one_locator_set_details_t_handler_json
2481   (vl_api_one_locator_set_details_t * mp)
2482 {
2483   vat_main_t *vam = &vat_main;
2484   vat_json_node_t *node = 0;
2485   u8 *ls_name = 0;
2486
2487   ls_name = format (0, "%s", mp->ls_name);
2488   vec_add1 (ls_name, 0);
2489
2490   if (VAT_JSON_ARRAY != vam->json_tree.type)
2491     {
2492       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2493       vat_json_init_array (&vam->json_tree);
2494     }
2495   node = vat_json_array_add (&vam->json_tree);
2496
2497   vat_json_init_object (node);
2498   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2499   vat_json_object_add_uint (node, "ls_index",
2500                             clib_net_to_host_u32 (mp->ls_index));
2501   vec_free (ls_name);
2502 }
2503
2504 static u8 *
2505 format_lisp_flat_eid (u8 * s, va_list * args)
2506 {
2507   u32 type = va_arg (*args, u32);
2508   u8 *eid = va_arg (*args, u8 *);
2509   u32 eid_len = va_arg (*args, u32);
2510
2511   switch (type)
2512     {
2513     case 0:
2514       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2515     case 1:
2516       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2517     case 2:
2518       return format (s, "%U", format_ethernet_address, eid);
2519     }
2520   return 0;
2521 }
2522
2523 static u8 *
2524 format_lisp_eid_vat (u8 * s, va_list * args)
2525 {
2526   u32 type = va_arg (*args, u32);
2527   u8 *eid = va_arg (*args, u8 *);
2528   u32 eid_len = va_arg (*args, u32);
2529   u8 *seid = va_arg (*args, u8 *);
2530   u32 seid_len = va_arg (*args, u32);
2531   u32 is_src_dst = va_arg (*args, u32);
2532
2533   if (is_src_dst)
2534     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2535
2536   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2537
2538   return s;
2539 }
2540
2541 static void
2542 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2543 {
2544   vat_main_t *vam = &vat_main;
2545   u8 *s = 0, *eid = 0;
2546
2547   if (~0 == mp->locator_set_index)
2548     s = format (0, "action: %d", mp->action);
2549   else
2550     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2551
2552   eid = format (0, "%U", format_lisp_eid_vat,
2553                 mp->eid_type,
2554                 mp->eid,
2555                 mp->eid_prefix_len,
2556                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2557   vec_add1 (eid, 0);
2558
2559   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2560          clib_net_to_host_u32 (mp->vni),
2561          eid,
2562          mp->is_local ? "local" : "remote",
2563          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2564          clib_net_to_host_u16 (mp->key_id), mp->key);
2565
2566   vec_free (s);
2567   vec_free (eid);
2568 }
2569
2570 static void
2571 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2572                                              * mp)
2573 {
2574   vat_main_t *vam = &vat_main;
2575   vat_json_node_t *node = 0;
2576   u8 *eid = 0;
2577
2578   if (VAT_JSON_ARRAY != vam->json_tree.type)
2579     {
2580       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2581       vat_json_init_array (&vam->json_tree);
2582     }
2583   node = vat_json_array_add (&vam->json_tree);
2584
2585   vat_json_init_object (node);
2586   if (~0 == mp->locator_set_index)
2587     vat_json_object_add_uint (node, "action", mp->action);
2588   else
2589     vat_json_object_add_uint (node, "locator_set_index",
2590                               clib_net_to_host_u32 (mp->locator_set_index));
2591
2592   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2593   eid = format (0, "%U", format_lisp_eid_vat,
2594                 mp->eid_type,
2595                 mp->eid,
2596                 mp->eid_prefix_len,
2597                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2598   vec_add1 (eid, 0);
2599   vat_json_object_add_string_copy (node, "eid", eid);
2600   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2601   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2602   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2603
2604   if (mp->key_id)
2605     {
2606       vat_json_object_add_uint (node, "key_id",
2607                                 clib_net_to_host_u16 (mp->key_id));
2608       vat_json_object_add_string_copy (node, "key", mp->key);
2609     }
2610   vec_free (eid);
2611 }
2612
2613 static void
2614   vl_api_one_eid_table_map_details_t_handler
2615   (vl_api_one_eid_table_map_details_t * mp)
2616 {
2617   vat_main_t *vam = &vat_main;
2618
2619   u8 *line = format (0, "%=10d%=10d",
2620                      clib_net_to_host_u32 (mp->vni),
2621                      clib_net_to_host_u32 (mp->dp_table));
2622   print (vam->ofp, "%v", line);
2623   vec_free (line);
2624 }
2625
2626 static void
2627   vl_api_one_eid_table_map_details_t_handler_json
2628   (vl_api_one_eid_table_map_details_t * mp)
2629 {
2630   vat_main_t *vam = &vat_main;
2631   vat_json_node_t *node = NULL;
2632
2633   if (VAT_JSON_ARRAY != vam->json_tree.type)
2634     {
2635       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2636       vat_json_init_array (&vam->json_tree);
2637     }
2638   node = vat_json_array_add (&vam->json_tree);
2639   vat_json_init_object (node);
2640   vat_json_object_add_uint (node, "dp_table",
2641                             clib_net_to_host_u32 (mp->dp_table));
2642   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2643 }
2644
2645 static void
2646   vl_api_one_eid_table_vni_details_t_handler
2647   (vl_api_one_eid_table_vni_details_t * mp)
2648 {
2649   vat_main_t *vam = &vat_main;
2650
2651   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2652   print (vam->ofp, "%v", line);
2653   vec_free (line);
2654 }
2655
2656 static void
2657   vl_api_one_eid_table_vni_details_t_handler_json
2658   (vl_api_one_eid_table_vni_details_t * mp)
2659 {
2660   vat_main_t *vam = &vat_main;
2661   vat_json_node_t *node = NULL;
2662
2663   if (VAT_JSON_ARRAY != vam->json_tree.type)
2664     {
2665       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2666       vat_json_init_array (&vam->json_tree);
2667     }
2668   node = vat_json_array_add (&vam->json_tree);
2669   vat_json_init_object (node);
2670   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2671 }
2672
2673 static void
2674   vl_api_show_one_map_register_state_reply_t_handler
2675   (vl_api_show_one_map_register_state_reply_t * mp)
2676 {
2677   vat_main_t *vam = &vat_main;
2678   int retval = clib_net_to_host_u32 (mp->retval);
2679
2680   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2681
2682   vam->retval = retval;
2683   vam->result_ready = 1;
2684 }
2685
2686 static void
2687   vl_api_show_one_map_register_state_reply_t_handler_json
2688   (vl_api_show_one_map_register_state_reply_t * mp)
2689 {
2690   vat_main_t *vam = &vat_main;
2691   vat_json_node_t _node, *node = &_node;
2692   int retval = clib_net_to_host_u32 (mp->retval);
2693
2694   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2695
2696   vat_json_init_object (node);
2697   vat_json_object_add_string_copy (node, "state", s);
2698
2699   vat_json_print (vam->ofp, node);
2700   vat_json_free (node);
2701
2702   vam->retval = retval;
2703   vam->result_ready = 1;
2704   vec_free (s);
2705 }
2706
2707 static void
2708   vl_api_show_one_rloc_probe_state_reply_t_handler
2709   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2710 {
2711   vat_main_t *vam = &vat_main;
2712   int retval = clib_net_to_host_u32 (mp->retval);
2713
2714   if (retval)
2715     goto end;
2716
2717   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2718 end:
2719   vam->retval = retval;
2720   vam->result_ready = 1;
2721 }
2722
2723 static void
2724   vl_api_show_one_rloc_probe_state_reply_t_handler_json
2725   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2726 {
2727   vat_main_t *vam = &vat_main;
2728   vat_json_node_t _node, *node = &_node;
2729   int retval = clib_net_to_host_u32 (mp->retval);
2730
2731   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2732   vat_json_init_object (node);
2733   vat_json_object_add_string_copy (node, "state", s);
2734
2735   vat_json_print (vam->ofp, node);
2736   vat_json_free (node);
2737
2738   vam->retval = retval;
2739   vam->result_ready = 1;
2740   vec_free (s);
2741 }
2742
2743 static void
2744 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
2745 {
2746   e->dp_table = clib_net_to_host_u32 (e->dp_table);
2747   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
2748 }
2749
2750 static void
2751   gpe_fwd_entries_get_reply_t_net_to_host
2752   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2753 {
2754   u32 i;
2755
2756   mp->count = clib_net_to_host_u32 (mp->count);
2757   for (i = 0; i < mp->count; i++)
2758     {
2759       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
2760     }
2761 }
2762
2763 static u8 *
2764 format_gpe_encap_mode (u8 * s, va_list * args)
2765 {
2766   u32 mode = va_arg (*args, u32);
2767
2768   switch (mode)
2769     {
2770     case 0:
2771       return format (s, "lisp");
2772     case 1:
2773       return format (s, "vxlan");
2774     }
2775   return 0;
2776 }
2777
2778 static void
2779   vl_api_gpe_get_encap_mode_reply_t_handler
2780   (vl_api_gpe_get_encap_mode_reply_t * mp)
2781 {
2782   vat_main_t *vam = &vat_main;
2783
2784   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
2785   vam->retval = ntohl (mp->retval);
2786   vam->result_ready = 1;
2787 }
2788
2789 static void
2790   vl_api_gpe_get_encap_mode_reply_t_handler_json
2791   (vl_api_gpe_get_encap_mode_reply_t * mp)
2792 {
2793   vat_main_t *vam = &vat_main;
2794   vat_json_node_t node;
2795
2796   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
2797   vec_add1 (encap_mode, 0);
2798
2799   vat_json_init_object (&node);
2800   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
2801
2802   vec_free (encap_mode);
2803   vat_json_print (vam->ofp, &node);
2804   vat_json_free (&node);
2805
2806   vam->retval = ntohl (mp->retval);
2807   vam->result_ready = 1;
2808 }
2809
2810 static void
2811   vl_api_gpe_fwd_entry_path_details_t_handler
2812   (vl_api_gpe_fwd_entry_path_details_t * mp)
2813 {
2814   vat_main_t *vam = &vat_main;
2815   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2816
2817   if (mp->lcl_loc.is_ip4)
2818     format_ip_address_fcn = format_ip4_address;
2819   else
2820     format_ip_address_fcn = format_ip6_address;
2821
2822   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
2823          format_ip_address_fcn, &mp->lcl_loc,
2824          format_ip_address_fcn, &mp->rmt_loc);
2825 }
2826
2827 static void
2828 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
2829 {
2830   struct in6_addr ip6;
2831   struct in_addr ip4;
2832
2833   if (loc->is_ip4)
2834     {
2835       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
2836       vat_json_object_add_ip4 (n, "address", ip4);
2837     }
2838   else
2839     {
2840       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
2841       vat_json_object_add_ip6 (n, "address", ip6);
2842     }
2843   vat_json_object_add_uint (n, "weight", loc->weight);
2844 }
2845
2846 static void
2847   vl_api_gpe_fwd_entry_path_details_t_handler_json
2848   (vl_api_gpe_fwd_entry_path_details_t * mp)
2849 {
2850   vat_main_t *vam = &vat_main;
2851   vat_json_node_t *node = NULL;
2852   vat_json_node_t *loc_node;
2853
2854   if (VAT_JSON_ARRAY != vam->json_tree.type)
2855     {
2856       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2857       vat_json_init_array (&vam->json_tree);
2858     }
2859   node = vat_json_array_add (&vam->json_tree);
2860   vat_json_init_object (node);
2861
2862   loc_node = vat_json_object_add (node, "local_locator");
2863   vat_json_init_object (loc_node);
2864   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
2865
2866   loc_node = vat_json_object_add (node, "remote_locator");
2867   vat_json_init_object (loc_node);
2868   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
2869 }
2870
2871 static void
2872   vl_api_gpe_fwd_entries_get_reply_t_handler
2873   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2874 {
2875   vat_main_t *vam = &vat_main;
2876   u32 i;
2877   int retval = clib_net_to_host_u32 (mp->retval);
2878   vl_api_gpe_fwd_entry_t *e;
2879
2880   if (retval)
2881     goto end;
2882
2883   gpe_fwd_entries_get_reply_t_net_to_host (mp);
2884
2885   for (i = 0; i < mp->count; i++)
2886     {
2887       e = &mp->entries[i];
2888       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
2889              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
2890              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
2891     }
2892
2893 end:
2894   vam->retval = retval;
2895   vam->result_ready = 1;
2896 }
2897
2898 static void
2899   vl_api_gpe_fwd_entries_get_reply_t_handler_json
2900   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2901 {
2902   u8 *s = 0;
2903   vat_main_t *vam = &vat_main;
2904   vat_json_node_t *e = 0, root;
2905   u32 i;
2906   int retval = clib_net_to_host_u32 (mp->retval);
2907   vl_api_gpe_fwd_entry_t *fwd;
2908
2909   if (retval)
2910     goto end;
2911
2912   gpe_fwd_entries_get_reply_t_net_to_host (mp);
2913   vat_json_init_array (&root);
2914
2915   for (i = 0; i < mp->count; i++)
2916     {
2917       e = vat_json_array_add (&root);
2918       fwd = &mp->entries[i];
2919
2920       vat_json_init_object (e);
2921       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
2922       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
2923
2924       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
2925                   fwd->leid_prefix_len);
2926       vec_add1 (s, 0);
2927       vat_json_object_add_string_copy (e, "leid", s);
2928       vec_free (s);
2929
2930       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
2931                   fwd->reid_prefix_len);
2932       vec_add1 (s, 0);
2933       vat_json_object_add_string_copy (e, "reid", s);
2934       vec_free (s);
2935     }
2936
2937   vat_json_print (vam->ofp, &root);
2938   vat_json_free (&root);
2939
2940 end:
2941   vam->retval = retval;
2942   vam->result_ready = 1;
2943 }
2944
2945 static void
2946   vl_api_one_adjacencies_get_reply_t_handler
2947   (vl_api_one_adjacencies_get_reply_t * mp)
2948 {
2949   vat_main_t *vam = &vat_main;
2950   u32 i, n;
2951   int retval = clib_net_to_host_u32 (mp->retval);
2952   vl_api_one_adjacency_t *a;
2953
2954   if (retval)
2955     goto end;
2956
2957   n = clib_net_to_host_u32 (mp->count);
2958
2959   for (i = 0; i < n; i++)
2960     {
2961       a = &mp->adjacencies[i];
2962       print (vam->ofp, "%U %40U",
2963              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2964              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
2965     }
2966
2967 end:
2968   vam->retval = retval;
2969   vam->result_ready = 1;
2970 }
2971
2972 static void
2973   vl_api_one_adjacencies_get_reply_t_handler_json
2974   (vl_api_one_adjacencies_get_reply_t * mp)
2975 {
2976   u8 *s = 0;
2977   vat_main_t *vam = &vat_main;
2978   vat_json_node_t *e = 0, root;
2979   u32 i, n;
2980   int retval = clib_net_to_host_u32 (mp->retval);
2981   vl_api_one_adjacency_t *a;
2982
2983   if (retval)
2984     goto end;
2985
2986   n = clib_net_to_host_u32 (mp->count);
2987   vat_json_init_array (&root);
2988
2989   for (i = 0; i < n; i++)
2990     {
2991       e = vat_json_array_add (&root);
2992       a = &mp->adjacencies[i];
2993
2994       vat_json_init_object (e);
2995       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2996                   a->leid_prefix_len);
2997       vec_add1 (s, 0);
2998       vat_json_object_add_string_copy (e, "leid", s);
2999       vec_free (s);
3000
3001       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3002                   a->reid_prefix_len);
3003       vec_add1 (s, 0);
3004       vat_json_object_add_string_copy (e, "reid", s);
3005       vec_free (s);
3006     }
3007
3008   vat_json_print (vam->ofp, &root);
3009   vat_json_free (&root);
3010
3011 end:
3012   vam->retval = retval;
3013   vam->result_ready = 1;
3014 }
3015
3016 static void
3017 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3018 {
3019   vat_main_t *vam = &vat_main;
3020
3021   print (vam->ofp, "%=20U",
3022          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3023          mp->ip_address);
3024 }
3025
3026 static void
3027   vl_api_one_map_server_details_t_handler_json
3028   (vl_api_one_map_server_details_t * mp)
3029 {
3030   vat_main_t *vam = &vat_main;
3031   vat_json_node_t *node = NULL;
3032   struct in6_addr ip6;
3033   struct in_addr ip4;
3034
3035   if (VAT_JSON_ARRAY != vam->json_tree.type)
3036     {
3037       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3038       vat_json_init_array (&vam->json_tree);
3039     }
3040   node = vat_json_array_add (&vam->json_tree);
3041
3042   vat_json_init_object (node);
3043   if (mp->is_ipv6)
3044     {
3045       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3046       vat_json_object_add_ip6 (node, "map-server", ip6);
3047     }
3048   else
3049     {
3050       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3051       vat_json_object_add_ip4 (node, "map-server", ip4);
3052     }
3053 }
3054
3055 static void
3056 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3057                                            * mp)
3058 {
3059   vat_main_t *vam = &vat_main;
3060
3061   print (vam->ofp, "%=20U",
3062          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3063          mp->ip_address);
3064 }
3065
3066 static void
3067   vl_api_one_map_resolver_details_t_handler_json
3068   (vl_api_one_map_resolver_details_t * mp)
3069 {
3070   vat_main_t *vam = &vat_main;
3071   vat_json_node_t *node = NULL;
3072   struct in6_addr ip6;
3073   struct in_addr ip4;
3074
3075   if (VAT_JSON_ARRAY != vam->json_tree.type)
3076     {
3077       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3078       vat_json_init_array (&vam->json_tree);
3079     }
3080   node = vat_json_array_add (&vam->json_tree);
3081
3082   vat_json_init_object (node);
3083   if (mp->is_ipv6)
3084     {
3085       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3086       vat_json_object_add_ip6 (node, "map resolver", ip6);
3087     }
3088   else
3089     {
3090       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3091       vat_json_object_add_ip4 (node, "map resolver", ip4);
3092     }
3093 }
3094
3095 static void
3096 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
3097 {
3098   vat_main_t *vam = &vat_main;
3099   i32 retval = ntohl (mp->retval);
3100
3101   if (0 <= retval)
3102     {
3103       print (vam->ofp, "feature: %s\ngpe: %s",
3104              mp->feature_status ? "enabled" : "disabled",
3105              mp->gpe_status ? "enabled" : "disabled");
3106     }
3107
3108   vam->retval = retval;
3109   vam->result_ready = 1;
3110 }
3111
3112 static void
3113   vl_api_show_one_status_reply_t_handler_json
3114   (vl_api_show_one_status_reply_t * mp)
3115 {
3116   vat_main_t *vam = &vat_main;
3117   vat_json_node_t node;
3118   u8 *gpe_status = NULL;
3119   u8 *feature_status = NULL;
3120
3121   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
3122   feature_status = format (0, "%s",
3123                            mp->feature_status ? "enabled" : "disabled");
3124   vec_add1 (gpe_status, 0);
3125   vec_add1 (feature_status, 0);
3126
3127   vat_json_init_object (&node);
3128   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
3129   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
3130
3131   vec_free (gpe_status);
3132   vec_free (feature_status);
3133
3134   vat_json_print (vam->ofp, &node);
3135   vat_json_free (&node);
3136
3137   vam->retval = ntohl (mp->retval);
3138   vam->result_ready = 1;
3139 }
3140
3141 static void
3142   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
3143   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3144 {
3145   vat_main_t *vam = &vat_main;
3146   i32 retval = ntohl (mp->retval);
3147
3148   if (retval >= 0)
3149     {
3150       print (vam->ofp, "%=20s", mp->locator_set_name);
3151     }
3152
3153   vam->retval = retval;
3154   vam->result_ready = 1;
3155 }
3156
3157 static void
3158   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
3159   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3160 {
3161   vat_main_t *vam = &vat_main;
3162   vat_json_node_t *node = NULL;
3163
3164   if (VAT_JSON_ARRAY != vam->json_tree.type)
3165     {
3166       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3167       vat_json_init_array (&vam->json_tree);
3168     }
3169   node = vat_json_array_add (&vam->json_tree);
3170
3171   vat_json_init_object (node);
3172   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
3173
3174   vat_json_print (vam->ofp, node);
3175   vat_json_free (node);
3176
3177   vam->retval = ntohl (mp->retval);
3178   vam->result_ready = 1;
3179 }
3180
3181 static u8 *
3182 format_lisp_map_request_mode (u8 * s, va_list * args)
3183 {
3184   u32 mode = va_arg (*args, u32);
3185
3186   switch (mode)
3187     {
3188     case 0:
3189       return format (0, "dst-only");
3190     case 1:
3191       return format (0, "src-dst");
3192     }
3193   return 0;
3194 }
3195
3196 static void
3197   vl_api_show_one_map_request_mode_reply_t_handler
3198   (vl_api_show_one_map_request_mode_reply_t * mp)
3199 {
3200   vat_main_t *vam = &vat_main;
3201   i32 retval = ntohl (mp->retval);
3202
3203   if (0 <= retval)
3204     {
3205       u32 mode = mp->mode;
3206       print (vam->ofp, "map_request_mode: %U",
3207              format_lisp_map_request_mode, mode);
3208     }
3209
3210   vam->retval = retval;
3211   vam->result_ready = 1;
3212 }
3213
3214 static void
3215   vl_api_show_one_map_request_mode_reply_t_handler_json
3216   (vl_api_show_one_map_request_mode_reply_t * mp)
3217 {
3218   vat_main_t *vam = &vat_main;
3219   vat_json_node_t node;
3220   u8 *s = 0;
3221   u32 mode;
3222
3223   mode = mp->mode;
3224   s = format (0, "%U", format_lisp_map_request_mode, mode);
3225   vec_add1 (s, 0);
3226
3227   vat_json_init_object (&node);
3228   vat_json_object_add_string_copy (&node, "map_request_mode", s);
3229   vat_json_print (vam->ofp, &node);
3230   vat_json_free (&node);
3231
3232   vec_free (s);
3233   vam->retval = ntohl (mp->retval);
3234   vam->result_ready = 1;
3235 }
3236
3237 static void
3238 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
3239 {
3240   vat_main_t *vam = &vat_main;
3241   i32 retval = ntohl (mp->retval);
3242
3243   if (0 <= retval)
3244     {
3245       print (vam->ofp, "%-20s%-16s",
3246              mp->status ? "enabled" : "disabled",
3247              mp->status ? (char *) mp->locator_set_name : "");
3248     }
3249
3250   vam->retval = retval;
3251   vam->result_ready = 1;
3252 }
3253
3254 static void
3255 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
3256 {
3257   vat_main_t *vam = &vat_main;
3258   vat_json_node_t node;
3259   u8 *status = 0;
3260
3261   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3262   vec_add1 (status, 0);
3263
3264   vat_json_init_object (&node);
3265   vat_json_object_add_string_copy (&node, "status", status);
3266   if (mp->status)
3267     {
3268       vat_json_object_add_string_copy (&node, "locator_set",
3269                                        mp->locator_set_name);
3270     }
3271
3272   vec_free (status);
3273
3274   vat_json_print (vam->ofp, &node);
3275   vat_json_free (&node);
3276
3277   vam->retval = ntohl (mp->retval);
3278   vam->result_ready = 1;
3279 }
3280
3281 static u8 *
3282 format_policer_type (u8 * s, va_list * va)
3283 {
3284   u32 i = va_arg (*va, u32);
3285
3286   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
3287     s = format (s, "1r2c");
3288   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
3289     s = format (s, "1r3c");
3290   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
3291     s = format (s, "2r3c-2698");
3292   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
3293     s = format (s, "2r3c-4115");
3294   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
3295     s = format (s, "2r3c-mef5cf1");
3296   else
3297     s = format (s, "ILLEGAL");
3298   return s;
3299 }
3300
3301 static u8 *
3302 format_policer_rate_type (u8 * s, va_list * va)
3303 {
3304   u32 i = va_arg (*va, u32);
3305
3306   if (i == SSE2_QOS_RATE_KBPS)
3307     s = format (s, "kbps");
3308   else if (i == SSE2_QOS_RATE_PPS)
3309     s = format (s, "pps");
3310   else
3311     s = format (s, "ILLEGAL");
3312   return s;
3313 }
3314
3315 static u8 *
3316 format_policer_round_type (u8 * s, va_list * va)
3317 {
3318   u32 i = va_arg (*va, u32);
3319
3320   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3321     s = format (s, "closest");
3322   else if (i == SSE2_QOS_ROUND_TO_UP)
3323     s = format (s, "up");
3324   else if (i == SSE2_QOS_ROUND_TO_DOWN)
3325     s = format (s, "down");
3326   else
3327     s = format (s, "ILLEGAL");
3328   return s;
3329 }
3330
3331 static u8 *
3332 format_policer_action_type (u8 * s, va_list * va)
3333 {
3334   u32 i = va_arg (*va, u32);
3335
3336   if (i == SSE2_QOS_ACTION_DROP)
3337     s = format (s, "drop");
3338   else if (i == SSE2_QOS_ACTION_TRANSMIT)
3339     s = format (s, "transmit");
3340   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3341     s = format (s, "mark-and-transmit");
3342   else
3343     s = format (s, "ILLEGAL");
3344   return s;
3345 }
3346
3347 static u8 *
3348 format_dscp (u8 * s, va_list * va)
3349 {
3350   u32 i = va_arg (*va, u32);
3351   char *t = 0;
3352
3353   switch (i)
3354     {
3355 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3356       foreach_vnet_dscp
3357 #undef _
3358     default:
3359       return format (s, "ILLEGAL");
3360     }
3361   s = format (s, "%s", t);
3362   return s;
3363 }
3364
3365 static void
3366 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3367 {
3368   vat_main_t *vam = &vat_main;
3369   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3370
3371   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3372     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3373   else
3374     conform_dscp_str = format (0, "");
3375
3376   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3377     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3378   else
3379     exceed_dscp_str = format (0, "");
3380
3381   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3382     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3383   else
3384     violate_dscp_str = format (0, "");
3385
3386   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3387          "rate type %U, round type %U, %s rate, %s color-aware, "
3388          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3389          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3390          "conform action %U%s, exceed action %U%s, violate action %U%s",
3391          mp->name,
3392          format_policer_type, mp->type,
3393          ntohl (mp->cir),
3394          ntohl (mp->eir),
3395          clib_net_to_host_u64 (mp->cb),
3396          clib_net_to_host_u64 (mp->eb),
3397          format_policer_rate_type, mp->rate_type,
3398          format_policer_round_type, mp->round_type,
3399          mp->single_rate ? "single" : "dual",
3400          mp->color_aware ? "is" : "not",
3401          ntohl (mp->cir_tokens_per_period),
3402          ntohl (mp->pir_tokens_per_period),
3403          ntohl (mp->scale),
3404          ntohl (mp->current_limit),
3405          ntohl (mp->current_bucket),
3406          ntohl (mp->extended_limit),
3407          ntohl (mp->extended_bucket),
3408          clib_net_to_host_u64 (mp->last_update_time),
3409          format_policer_action_type, mp->conform_action_type,
3410          conform_dscp_str,
3411          format_policer_action_type, mp->exceed_action_type,
3412          exceed_dscp_str,
3413          format_policer_action_type, mp->violate_action_type,
3414          violate_dscp_str);
3415
3416   vec_free (conform_dscp_str);
3417   vec_free (exceed_dscp_str);
3418   vec_free (violate_dscp_str);
3419 }
3420
3421 static void vl_api_policer_details_t_handler_json
3422   (vl_api_policer_details_t * mp)
3423 {
3424   vat_main_t *vam = &vat_main;
3425   vat_json_node_t *node;
3426   u8 *rate_type_str, *round_type_str, *type_str;
3427   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3428
3429   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3430   round_type_str =
3431     format (0, "%U", format_policer_round_type, mp->round_type);
3432   type_str = format (0, "%U", format_policer_type, mp->type);
3433   conform_action_str = format (0, "%U", format_policer_action_type,
3434                                mp->conform_action_type);
3435   exceed_action_str = format (0, "%U", format_policer_action_type,
3436                               mp->exceed_action_type);
3437   violate_action_str = format (0, "%U", format_policer_action_type,
3438                                mp->violate_action_type);
3439
3440   if (VAT_JSON_ARRAY != vam->json_tree.type)
3441     {
3442       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3443       vat_json_init_array (&vam->json_tree);
3444     }
3445   node = vat_json_array_add (&vam->json_tree);
3446
3447   vat_json_init_object (node);
3448   vat_json_object_add_string_copy (node, "name", mp->name);
3449   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3450   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3451   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3452   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3453   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3454   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3455   vat_json_object_add_string_copy (node, "type", type_str);
3456   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3457   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3458   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3459   vat_json_object_add_uint (node, "cir_tokens_per_period",
3460                             ntohl (mp->cir_tokens_per_period));
3461   vat_json_object_add_uint (node, "eir_tokens_per_period",
3462                             ntohl (mp->pir_tokens_per_period));
3463   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3464   vat_json_object_add_uint (node, "current_bucket",
3465                             ntohl (mp->current_bucket));
3466   vat_json_object_add_uint (node, "extended_limit",
3467                             ntohl (mp->extended_limit));
3468   vat_json_object_add_uint (node, "extended_bucket",
3469                             ntohl (mp->extended_bucket));
3470   vat_json_object_add_uint (node, "last_update_time",
3471                             ntohl (mp->last_update_time));
3472   vat_json_object_add_string_copy (node, "conform_action",
3473                                    conform_action_str);
3474   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3475     {
3476       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3477       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3478       vec_free (dscp_str);
3479     }
3480   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3481   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3482     {
3483       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3484       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3485       vec_free (dscp_str);
3486     }
3487   vat_json_object_add_string_copy (node, "violate_action",
3488                                    violate_action_str);
3489   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3490     {
3491       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3492       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3493       vec_free (dscp_str);
3494     }
3495
3496   vec_free (rate_type_str);
3497   vec_free (round_type_str);
3498   vec_free (type_str);
3499   vec_free (conform_action_str);
3500   vec_free (exceed_action_str);
3501   vec_free (violate_action_str);
3502 }
3503
3504 static void
3505 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3506                                            mp)
3507 {
3508   vat_main_t *vam = &vat_main;
3509   int i, count = ntohl (mp->count);
3510
3511   if (count > 0)
3512     print (vam->ofp, "classify table ids (%d) : ", count);
3513   for (i = 0; i < count; i++)
3514     {
3515       print (vam->ofp, "%d", ntohl (mp->ids[i]));
3516       print (vam->ofp, (i < count - 1) ? "," : "");
3517     }
3518   vam->retval = ntohl (mp->retval);
3519   vam->result_ready = 1;
3520 }
3521
3522 static void
3523   vl_api_classify_table_ids_reply_t_handler_json
3524   (vl_api_classify_table_ids_reply_t * mp)
3525 {
3526   vat_main_t *vam = &vat_main;
3527   int i, count = ntohl (mp->count);
3528
3529   if (count > 0)
3530     {
3531       vat_json_node_t node;
3532
3533       vat_json_init_object (&node);
3534       for (i = 0; i < count; i++)
3535         {
3536           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3537         }
3538       vat_json_print (vam->ofp, &node);
3539       vat_json_free (&node);
3540     }
3541   vam->retval = ntohl (mp->retval);
3542   vam->result_ready = 1;
3543 }
3544
3545 static void
3546   vl_api_classify_table_by_interface_reply_t_handler
3547   (vl_api_classify_table_by_interface_reply_t * mp)
3548 {
3549   vat_main_t *vam = &vat_main;
3550   u32 table_id;
3551
3552   table_id = ntohl (mp->l2_table_id);
3553   if (table_id != ~0)
3554     print (vam->ofp, "l2 table id : %d", table_id);
3555   else
3556     print (vam->ofp, "l2 table id : No input ACL tables configured");
3557   table_id = ntohl (mp->ip4_table_id);
3558   if (table_id != ~0)
3559     print (vam->ofp, "ip4 table id : %d", table_id);
3560   else
3561     print (vam->ofp, "ip4 table id : No input ACL tables configured");
3562   table_id = ntohl (mp->ip6_table_id);
3563   if (table_id != ~0)
3564     print (vam->ofp, "ip6 table id : %d", table_id);
3565   else
3566     print (vam->ofp, "ip6 table id : No input ACL tables configured");
3567   vam->retval = ntohl (mp->retval);
3568   vam->result_ready = 1;
3569 }
3570
3571 static void
3572   vl_api_classify_table_by_interface_reply_t_handler_json
3573   (vl_api_classify_table_by_interface_reply_t * mp)
3574 {
3575   vat_main_t *vam = &vat_main;
3576   vat_json_node_t node;
3577
3578   vat_json_init_object (&node);
3579
3580   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3581   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3582   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3583
3584   vat_json_print (vam->ofp, &node);
3585   vat_json_free (&node);
3586
3587   vam->retval = ntohl (mp->retval);
3588   vam->result_ready = 1;
3589 }
3590
3591 static void vl_api_policer_add_del_reply_t_handler
3592   (vl_api_policer_add_del_reply_t * mp)
3593 {
3594   vat_main_t *vam = &vat_main;
3595   i32 retval = ntohl (mp->retval);
3596   if (vam->async_mode)
3597     {
3598       vam->async_errors += (retval < 0);
3599     }
3600   else
3601     {
3602       vam->retval = retval;
3603       vam->result_ready = 1;
3604       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3605         /*
3606          * Note: this is just barely thread-safe, depends on
3607          * the main thread spinning waiting for an answer...
3608          */
3609         errmsg ("policer index %d", ntohl (mp->policer_index));
3610     }
3611 }
3612
3613 static void vl_api_policer_add_del_reply_t_handler_json
3614   (vl_api_policer_add_del_reply_t * mp)
3615 {
3616   vat_main_t *vam = &vat_main;
3617   vat_json_node_t node;
3618
3619   vat_json_init_object (&node);
3620   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3621   vat_json_object_add_uint (&node, "policer_index",
3622                             ntohl (mp->policer_index));
3623
3624   vat_json_print (vam->ofp, &node);
3625   vat_json_free (&node);
3626
3627   vam->retval = ntohl (mp->retval);
3628   vam->result_ready = 1;
3629 }
3630
3631 /* Format hex dump. */
3632 u8 *
3633 format_hex_bytes (u8 * s, va_list * va)
3634 {
3635   u8 *bytes = va_arg (*va, u8 *);
3636   int n_bytes = va_arg (*va, int);
3637   uword i;
3638
3639   /* Print short or long form depending on byte count. */
3640   uword short_form = n_bytes <= 32;
3641   uword indent = format_get_indent (s);
3642
3643   if (n_bytes == 0)
3644     return s;
3645
3646   for (i = 0; i < n_bytes; i++)
3647     {
3648       if (!short_form && (i % 32) == 0)
3649         s = format (s, "%08x: ", i);
3650       s = format (s, "%02x", bytes[i]);
3651       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3652         s = format (s, "\n%U", format_white_space, indent);
3653     }
3654
3655   return s;
3656 }
3657
3658 static void
3659 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3660                                             * mp)
3661 {
3662   vat_main_t *vam = &vat_main;
3663   i32 retval = ntohl (mp->retval);
3664   if (retval == 0)
3665     {
3666       print (vam->ofp, "classify table info :");
3667       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3668              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3669              ntohl (mp->miss_next_index));
3670       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3671              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3672              ntohl (mp->match_n_vectors));
3673       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3674              ntohl (mp->mask_length));
3675     }
3676   vam->retval = retval;
3677   vam->result_ready = 1;
3678 }
3679
3680 static void
3681   vl_api_classify_table_info_reply_t_handler_json
3682   (vl_api_classify_table_info_reply_t * mp)
3683 {
3684   vat_main_t *vam = &vat_main;
3685   vat_json_node_t node;
3686
3687   i32 retval = ntohl (mp->retval);
3688   if (retval == 0)
3689     {
3690       vat_json_init_object (&node);
3691
3692       vat_json_object_add_int (&node, "sessions",
3693                                ntohl (mp->active_sessions));
3694       vat_json_object_add_int (&node, "nexttbl",
3695                                ntohl (mp->next_table_index));
3696       vat_json_object_add_int (&node, "nextnode",
3697                                ntohl (mp->miss_next_index));
3698       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3699       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3700       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3701       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3702                       ntohl (mp->mask_length), 0);
3703       vat_json_object_add_string_copy (&node, "mask", s);
3704
3705       vat_json_print (vam->ofp, &node);
3706       vat_json_free (&node);
3707     }
3708   vam->retval = ntohl (mp->retval);
3709   vam->result_ready = 1;
3710 }
3711
3712 static void
3713 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3714                                            mp)
3715 {
3716   vat_main_t *vam = &vat_main;
3717
3718   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3719          ntohl (mp->hit_next_index), ntohl (mp->advance),
3720          ntohl (mp->opaque_index));
3721   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3722          ntohl (mp->match_length));
3723 }
3724
3725 static void
3726   vl_api_classify_session_details_t_handler_json
3727   (vl_api_classify_session_details_t * mp)
3728 {
3729   vat_main_t *vam = &vat_main;
3730   vat_json_node_t *node = NULL;
3731
3732   if (VAT_JSON_ARRAY != vam->json_tree.type)
3733     {
3734       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3735       vat_json_init_array (&vam->json_tree);
3736     }
3737   node = vat_json_array_add (&vam->json_tree);
3738
3739   vat_json_init_object (node);
3740   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3741   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3742   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3743   u8 *s =
3744     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3745             0);
3746   vat_json_object_add_string_copy (node, "match", s);
3747 }
3748
3749 static void vl_api_pg_create_interface_reply_t_handler
3750   (vl_api_pg_create_interface_reply_t * mp)
3751 {
3752   vat_main_t *vam = &vat_main;
3753
3754   vam->retval = ntohl (mp->retval);
3755   vam->result_ready = 1;
3756 }
3757
3758 static void vl_api_pg_create_interface_reply_t_handler_json
3759   (vl_api_pg_create_interface_reply_t * mp)
3760 {
3761   vat_main_t *vam = &vat_main;
3762   vat_json_node_t node;
3763
3764   i32 retval = ntohl (mp->retval);
3765   if (retval == 0)
3766     {
3767       vat_json_init_object (&node);
3768
3769       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3770
3771       vat_json_print (vam->ofp, &node);
3772       vat_json_free (&node);
3773     }
3774   vam->retval = ntohl (mp->retval);
3775   vam->result_ready = 1;
3776 }
3777
3778 static void vl_api_policer_classify_details_t_handler
3779   (vl_api_policer_classify_details_t * mp)
3780 {
3781   vat_main_t *vam = &vat_main;
3782
3783   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3784          ntohl (mp->table_index));
3785 }
3786
3787 static void vl_api_policer_classify_details_t_handler_json
3788   (vl_api_policer_classify_details_t * mp)
3789 {
3790   vat_main_t *vam = &vat_main;
3791   vat_json_node_t *node;
3792
3793   if (VAT_JSON_ARRAY != vam->json_tree.type)
3794     {
3795       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3796       vat_json_init_array (&vam->json_tree);
3797     }
3798   node = vat_json_array_add (&vam->json_tree);
3799
3800   vat_json_init_object (node);
3801   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3802   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3803 }
3804
3805 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3806   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3807 {
3808   vat_main_t *vam = &vat_main;
3809   i32 retval = ntohl (mp->retval);
3810   if (vam->async_mode)
3811     {
3812       vam->async_errors += (retval < 0);
3813     }
3814   else
3815     {
3816       vam->retval = retval;
3817       vam->sw_if_index = ntohl (mp->sw_if_index);
3818       vam->result_ready = 1;
3819     }
3820 }
3821
3822 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3823   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3824 {
3825   vat_main_t *vam = &vat_main;
3826   vat_json_node_t node;
3827
3828   vat_json_init_object (&node);
3829   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3830   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3831
3832   vat_json_print (vam->ofp, &node);
3833   vat_json_free (&node);
3834
3835   vam->retval = ntohl (mp->retval);
3836   vam->result_ready = 1;
3837 }
3838
3839 static void vl_api_flow_classify_details_t_handler
3840   (vl_api_flow_classify_details_t * mp)
3841 {
3842   vat_main_t *vam = &vat_main;
3843
3844   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3845          ntohl (mp->table_index));
3846 }
3847
3848 static void vl_api_flow_classify_details_t_handler_json
3849   (vl_api_flow_classify_details_t * mp)
3850 {
3851   vat_main_t *vam = &vat_main;
3852   vat_json_node_t *node;
3853
3854   if (VAT_JSON_ARRAY != vam->json_tree.type)
3855     {
3856       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3857       vat_json_init_array (&vam->json_tree);
3858     }
3859   node = vat_json_array_add (&vam->json_tree);
3860
3861   vat_json_init_object (node);
3862   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3863   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3864 }
3865
3866
3867
3868 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3869 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3870 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3871 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3872 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
3873 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
3874 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
3875 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
3876 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
3877 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
3878
3879 /*
3880  * Generate boilerplate reply handlers, which
3881  * dig the return value out of the xxx_reply_t API message,
3882  * stick it into vam->retval, and set vam->result_ready
3883  *
3884  * Could also do this by pointing N message decode slots at
3885  * a single function, but that could break in subtle ways.
3886  */
3887
3888 #define foreach_standard_reply_retval_handler           \
3889 _(sw_interface_set_flags_reply)                         \
3890 _(sw_interface_add_del_address_reply)                   \
3891 _(sw_interface_set_table_reply)                         \
3892 _(sw_interface_set_mpls_enable_reply)                   \
3893 _(sw_interface_set_vpath_reply)                         \
3894 _(sw_interface_set_vxlan_bypass_reply)                  \
3895 _(sw_interface_set_l2_bridge_reply)                     \
3896 _(bridge_domain_add_del_reply)                          \
3897 _(sw_interface_set_l2_xconnect_reply)                   \
3898 _(l2fib_add_del_reply)                                  \
3899 _(ip_add_del_route_reply)                               \
3900 _(ip_mroute_add_del_reply)                              \
3901 _(mpls_route_add_del_reply)                             \
3902 _(mpls_ip_bind_unbind_reply)                            \
3903 _(proxy_arp_add_del_reply)                              \
3904 _(proxy_arp_intfc_enable_disable_reply)                 \
3905 _(sw_interface_set_unnumbered_reply)                    \
3906 _(ip_neighbor_add_del_reply)                            \
3907 _(reset_vrf_reply)                                      \
3908 _(oam_add_del_reply)                                    \
3909 _(reset_fib_reply)                                      \
3910 _(dhcp_proxy_config_reply)                              \
3911 _(dhcp_proxy_set_vss_reply)                             \
3912 _(dhcp_client_config_reply)                             \
3913 _(set_ip_flow_hash_reply)                               \
3914 _(sw_interface_ip6_enable_disable_reply)                \
3915 _(sw_interface_ip6_set_link_local_address_reply)        \
3916 _(ip6nd_proxy_add_del_reply)                            \
3917 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3918 _(sw_interface_ip6nd_ra_config_reply)                   \
3919 _(set_arp_neighbor_limit_reply)                         \
3920 _(l2_patch_add_del_reply)                               \
3921 _(sr_policy_add_reply)                                  \
3922 _(sr_policy_mod_reply)                                  \
3923 _(sr_policy_del_reply)                                  \
3924 _(sr_localsid_add_del_reply)                            \
3925 _(sr_steering_add_del_reply)                            \
3926 _(classify_add_del_session_reply)                       \
3927 _(classify_set_interface_ip_table_reply)                \
3928 _(classify_set_interface_l2_tables_reply)               \
3929 _(l2tpv3_set_tunnel_cookies_reply)                      \
3930 _(l2tpv3_interface_enable_disable_reply)                \
3931 _(l2tpv3_set_lookup_key_reply)                          \
3932 _(l2_fib_clear_table_reply)                             \
3933 _(l2_interface_efp_filter_reply)                        \
3934 _(l2_interface_vlan_tag_rewrite_reply)                  \
3935 _(modify_vhost_user_if_reply)                           \
3936 _(delete_vhost_user_if_reply)                           \
3937 _(want_ip4_arp_events_reply)                            \
3938 _(want_ip6_nd_events_reply)                             \
3939 _(input_acl_set_interface_reply)                        \
3940 _(ipsec_spd_add_del_reply)                              \
3941 _(ipsec_interface_add_del_spd_reply)                    \
3942 _(ipsec_spd_add_del_entry_reply)                        \
3943 _(ipsec_sad_add_del_entry_reply)                        \
3944 _(ipsec_sa_set_key_reply)                               \
3945 _(ikev2_profile_add_del_reply)                          \
3946 _(ikev2_profile_set_auth_reply)                         \
3947 _(ikev2_profile_set_id_reply)                           \
3948 _(ikev2_profile_set_ts_reply)                           \
3949 _(ikev2_set_local_key_reply)                            \
3950 _(ikev2_set_responder_reply)                            \
3951 _(ikev2_set_ike_transforms_reply)                       \
3952 _(ikev2_set_esp_transforms_reply)                       \
3953 _(ikev2_set_sa_lifetime_reply)                          \
3954 _(ikev2_initiate_sa_init_reply)                         \
3955 _(ikev2_initiate_del_ike_sa_reply)                      \
3956 _(ikev2_initiate_del_child_sa_reply)                    \
3957 _(ikev2_initiate_rekey_child_sa_reply)                  \
3958 _(delete_loopback_reply)                                \
3959 _(bd_ip_mac_add_del_reply)                              \
3960 _(map_del_domain_reply)                                 \
3961 _(map_add_del_rule_reply)                               \
3962 _(want_interface_events_reply)                          \
3963 _(want_stats_reply)                                     \
3964 _(cop_interface_enable_disable_reply)                   \
3965 _(cop_whitelist_enable_disable_reply)                   \
3966 _(sw_interface_clear_stats_reply)                       \
3967 _(ioam_enable_reply)                              \
3968 _(ioam_disable_reply)                              \
3969 _(one_add_del_locator_reply)                            \
3970 _(one_add_del_local_eid_reply)                          \
3971 _(one_add_del_remote_mapping_reply)                     \
3972 _(one_add_del_adjacency_reply)                          \
3973 _(one_add_del_map_resolver_reply)                       \
3974 _(one_add_del_map_server_reply)                         \
3975 _(one_enable_disable_reply)                             \
3976 _(one_rloc_probe_enable_disable_reply)                  \
3977 _(one_map_register_enable_disable_reply)                \
3978 _(one_pitr_set_locator_set_reply)                       \
3979 _(one_map_request_mode_reply)                           \
3980 _(one_add_del_map_request_itr_rlocs_reply)              \
3981 _(one_eid_table_add_del_map_reply)                      \
3982 _(gpe_add_del_fwd_entry_reply)                          \
3983 _(gpe_enable_disable_reply)                             \
3984 _(gpe_set_encap_mode_reply)                             \
3985 _(gpe_add_del_iface_reply)                              \
3986 _(vxlan_gpe_add_del_tunnel_reply)                       \
3987 _(af_packet_delete_reply)                               \
3988 _(policer_classify_set_interface_reply)                 \
3989 _(netmap_create_reply)                                  \
3990 _(netmap_delete_reply)                                  \
3991 _(set_ipfix_exporter_reply)                             \
3992 _(set_ipfix_classify_stream_reply)                      \
3993 _(ipfix_classify_table_add_del_reply)                   \
3994 _(flow_classify_set_interface_reply)                    \
3995 _(sw_interface_span_enable_disable_reply)               \
3996 _(pg_capture_reply)                                     \
3997 _(pg_enable_disable_reply)                              \
3998 _(ip_source_and_port_range_check_add_del_reply)         \
3999 _(ip_source_and_port_range_check_interface_add_del_reply)\
4000 _(delete_subif_reply)                                   \
4001 _(l2_interface_pbb_tag_rewrite_reply)                   \
4002 _(punt_reply)                                           \
4003 _(feature_enable_disable_reply)                         \
4004 _(sw_interface_tag_add_del_reply)                       \
4005 _(sw_interface_set_mtu_reply)
4006
4007 #define _(n)                                    \
4008     static void vl_api_##n##_t_handler          \
4009     (vl_api_##n##_t * mp)                       \
4010     {                                           \
4011         vat_main_t * vam = &vat_main;           \
4012         i32 retval = ntohl(mp->retval);         \
4013         if (vam->async_mode) {                  \
4014             vam->async_errors += (retval < 0);  \
4015         } else {                                \
4016             vam->retval = retval;               \
4017             vam->result_ready = 1;              \
4018         }                                       \
4019     }
4020 foreach_standard_reply_retval_handler;
4021 #undef _
4022
4023 #define _(n)                                    \
4024     static void vl_api_##n##_t_handler_json     \
4025     (vl_api_##n##_t * mp)                       \
4026     {                                           \
4027         vat_main_t * vam = &vat_main;           \
4028         vat_json_node_t node;                   \
4029         vat_json_init_object(&node);            \
4030         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
4031         vat_json_print(vam->ofp, &node);        \
4032         vam->retval = ntohl(mp->retval);        \
4033         vam->result_ready = 1;                  \
4034     }
4035 foreach_standard_reply_retval_handler;
4036 #undef _
4037
4038 /*
4039  * Table of message reply handlers, must include boilerplate handlers
4040  * we just generated
4041  */
4042
4043 #define foreach_vpe_api_reply_msg                                       \
4044 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
4045 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
4046 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
4047 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
4048 _(CONTROL_PING_REPLY, control_ping_reply)                               \
4049 _(CLI_REPLY, cli_reply)                                                 \
4050 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
4051 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
4052   sw_interface_add_del_address_reply)                                   \
4053 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
4054 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
4055 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
4056 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
4057 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
4058   sw_interface_set_l2_xconnect_reply)                                   \
4059 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
4060   sw_interface_set_l2_bridge_reply)                                     \
4061 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
4062 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
4063 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
4064 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
4065 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
4066 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
4067 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
4068 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
4069 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
4070 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
4071 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
4072 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
4073 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
4074 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
4075 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
4076 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
4077   proxy_arp_intfc_enable_disable_reply)                                 \
4078 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
4079 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
4080   sw_interface_set_unnumbered_reply)                                    \
4081 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
4082 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
4083 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
4084 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
4085 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
4086 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
4087 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
4088 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
4089 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
4090 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
4091 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
4092 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
4093   sw_interface_ip6_enable_disable_reply)                                \
4094 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
4095   sw_interface_ip6_set_link_local_address_reply)                        \
4096 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
4097 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
4098 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
4099   sw_interface_ip6nd_ra_prefix_reply)                                   \
4100 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
4101   sw_interface_ip6nd_ra_config_reply)                                   \
4102 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
4103 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
4104 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
4105 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
4106 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
4107 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
4108 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
4109 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
4110 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
4111 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
4112 classify_set_interface_ip_table_reply)                                  \
4113 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
4114   classify_set_interface_l2_tables_reply)                               \
4115 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
4116 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
4117 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
4118 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
4119 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
4120   l2tpv3_interface_enable_disable_reply)                                \
4121 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
4122 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
4123 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
4124 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
4125 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
4126 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
4127 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
4128 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
4129 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4130 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
4131 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
4132 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
4133 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
4134 _(SHOW_VERSION_REPLY, show_version_reply)                               \
4135 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
4136 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
4137 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
4138 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
4139 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
4140 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
4141 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
4142 _(IP6_ND_EVENT, ip6_nd_event)                                           \
4143 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
4144 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
4145 _(IP_DETAILS, ip_details)                                               \
4146 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
4147 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4148 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
4149 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
4150 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
4151 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
4152 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
4153 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
4154 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
4155 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
4156 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
4157 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
4158 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
4159 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
4160 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
4161 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
4162 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
4163 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
4164 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
4165 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
4166 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
4167 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
4168 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
4169 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
4170 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
4171 _(MAP_RULE_DETAILS, map_rule_details)                                   \
4172 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
4173 _(WANT_STATS_REPLY, want_stats_reply)                                   \
4174 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
4175 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4176 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4177 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
4178 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
4179 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
4180 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
4181 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
4182 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
4183 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
4184 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
4185 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
4186 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
4187 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
4188 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
4189 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
4190   one_map_register_enable_disable_reply)                                \
4191 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
4192   one_rloc_probe_enable_disable_reply)                                  \
4193 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
4194 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
4195 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
4196 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
4197 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
4198 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
4199 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
4200 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
4201 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
4202 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
4203 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
4204 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
4205 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
4206 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
4207 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
4208 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
4209 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
4210 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
4211   gpe_fwd_entry_path_details)                                           \
4212 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
4213 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
4214   one_add_del_map_request_itr_rlocs_reply)                              \
4215 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
4216   one_get_map_request_itr_rlocs_reply)                                  \
4217 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
4218 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
4219 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
4220 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
4221   show_one_map_register_state_reply)                                    \
4222 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
4223 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
4224 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
4225 _(POLICER_DETAILS, policer_details)                                     \
4226 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4227 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
4228 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
4229 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
4230 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
4231 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
4232 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
4233 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4234 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
4235 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
4236 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
4237 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
4238 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
4239 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
4240 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4241 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
4242 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4243 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
4244 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
4245 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
4246 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
4247 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
4248 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
4249 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
4250 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
4251  ip_source_and_port_range_check_add_del_reply)                          \
4252 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
4253  ip_source_and_port_range_check_interface_add_del_reply)                \
4254 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
4255 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
4256 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
4257 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
4258 _(PUNT_REPLY, punt_reply)                                               \
4259 _(IP_FIB_DETAILS, ip_fib_details)                                       \
4260 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
4261 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
4262 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
4263 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
4264 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
4265 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
4266 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
4267
4268 #define foreach_standalone_reply_msg                                    \
4269 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
4270 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
4271 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
4272 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
4273 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
4274 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
4275
4276 typedef struct
4277 {
4278   u8 *name;
4279   u32 value;
4280 } name_sort_t;
4281
4282
4283 #define STR_VTR_OP_CASE(op)     \
4284     case L2_VTR_ ## op:         \
4285         return "" # op;
4286
4287 static const char *
4288 str_vtr_op (u32 vtr_op)
4289 {
4290   switch (vtr_op)
4291     {
4292       STR_VTR_OP_CASE (DISABLED);
4293       STR_VTR_OP_CASE (PUSH_1);
4294       STR_VTR_OP_CASE (PUSH_2);
4295       STR_VTR_OP_CASE (POP_1);
4296       STR_VTR_OP_CASE (POP_2);
4297       STR_VTR_OP_CASE (TRANSLATE_1_1);
4298       STR_VTR_OP_CASE (TRANSLATE_1_2);
4299       STR_VTR_OP_CASE (TRANSLATE_2_1);
4300       STR_VTR_OP_CASE (TRANSLATE_2_2);
4301     }
4302
4303   return "UNKNOWN";
4304 }
4305
4306 static int
4307 dump_sub_interface_table (vat_main_t * vam)
4308 {
4309   const sw_interface_subif_t *sub = NULL;
4310
4311   if (vam->json_output)
4312     {
4313       clib_warning
4314         ("JSON output supported only for VPE API calls and dump_stats_table");
4315       return -99;
4316     }
4317
4318   print (vam->ofp,
4319          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4320          "Interface", "sw_if_index",
4321          "sub id", "dot1ad", "tags", "outer id",
4322          "inner id", "exact", "default", "outer any", "inner any");
4323
4324   vec_foreach (sub, vam->sw_if_subif_table)
4325   {
4326     print (vam->ofp,
4327            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4328            sub->interface_name,
4329            sub->sw_if_index,
4330            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4331            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4332            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4333            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4334     if (sub->vtr_op != L2_VTR_DISABLED)
4335       {
4336         print (vam->ofp,
4337                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4338                "tag1: %d tag2: %d ]",
4339                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4340                sub->vtr_tag1, sub->vtr_tag2);
4341       }
4342   }
4343
4344   return 0;
4345 }
4346
4347 static int
4348 name_sort_cmp (void *a1, void *a2)
4349 {
4350   name_sort_t *n1 = a1;
4351   name_sort_t *n2 = a2;
4352
4353   return strcmp ((char *) n1->name, (char *) n2->name);
4354 }
4355
4356 static int
4357 dump_interface_table (vat_main_t * vam)
4358 {
4359   hash_pair_t *p;
4360   name_sort_t *nses = 0, *ns;
4361
4362   if (vam->json_output)
4363     {
4364       clib_warning
4365         ("JSON output supported only for VPE API calls and dump_stats_table");
4366       return -99;
4367     }
4368
4369   /* *INDENT-OFF* */
4370   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4371   ({
4372     vec_add2 (nses, ns, 1);
4373     ns->name = (u8 *)(p->key);
4374     ns->value = (u32) p->value[0];
4375   }));
4376   /* *INDENT-ON* */
4377
4378   vec_sort_with_function (nses, name_sort_cmp);
4379
4380   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4381   vec_foreach (ns, nses)
4382   {
4383     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4384   }
4385   vec_free (nses);
4386   return 0;
4387 }
4388
4389 static int
4390 dump_ip_table (vat_main_t * vam, int is_ipv6)
4391 {
4392   const ip_details_t *det = NULL;
4393   const ip_address_details_t *address = NULL;
4394   u32 i = ~0;
4395
4396   print (vam->ofp, "%-12s", "sw_if_index");
4397
4398   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4399   {
4400     i++;
4401     if (!det->present)
4402       {
4403         continue;
4404       }
4405     print (vam->ofp, "%-12d", i);
4406     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
4407     if (!det->addr)
4408       {
4409         continue;
4410       }
4411     vec_foreach (address, det->addr)
4412     {
4413       print (vam->ofp,
4414              "            %-30U%-13d",
4415              is_ipv6 ? format_ip6_address : format_ip4_address,
4416              address->ip, address->prefix_length);
4417     }
4418   }
4419
4420   return 0;
4421 }
4422
4423 static int
4424 dump_ipv4_table (vat_main_t * vam)
4425 {
4426   if (vam->json_output)
4427     {
4428       clib_warning
4429         ("JSON output supported only for VPE API calls and dump_stats_table");
4430       return -99;
4431     }
4432
4433   return dump_ip_table (vam, 0);
4434 }
4435
4436 static int
4437 dump_ipv6_table (vat_main_t * vam)
4438 {
4439   if (vam->json_output)
4440     {
4441       clib_warning
4442         ("JSON output supported only for VPE API calls and dump_stats_table");
4443       return -99;
4444     }
4445
4446   return dump_ip_table (vam, 1);
4447 }
4448
4449 static char *
4450 counter_type_to_str (u8 counter_type, u8 is_combined)
4451 {
4452   if (!is_combined)
4453     {
4454       switch (counter_type)
4455         {
4456         case VNET_INTERFACE_COUNTER_DROP:
4457           return "drop";
4458         case VNET_INTERFACE_COUNTER_PUNT:
4459           return "punt";
4460         case VNET_INTERFACE_COUNTER_IP4:
4461           return "ip4";
4462         case VNET_INTERFACE_COUNTER_IP6:
4463           return "ip6";
4464         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4465           return "rx-no-buf";
4466         case VNET_INTERFACE_COUNTER_RX_MISS:
4467           return "rx-miss";
4468         case VNET_INTERFACE_COUNTER_RX_ERROR:
4469           return "rx-error";
4470         case VNET_INTERFACE_COUNTER_TX_ERROR:
4471           return "tx-error";
4472         default:
4473           return "INVALID-COUNTER-TYPE";
4474         }
4475     }
4476   else
4477     {
4478       switch (counter_type)
4479         {
4480         case VNET_INTERFACE_COUNTER_RX:
4481           return "rx";
4482         case VNET_INTERFACE_COUNTER_TX:
4483           return "tx";
4484         default:
4485           return "INVALID-COUNTER-TYPE";
4486         }
4487     }
4488 }
4489
4490 static int
4491 dump_stats_table (vat_main_t * vam)
4492 {
4493   vat_json_node_t node;
4494   vat_json_node_t *msg_array;
4495   vat_json_node_t *msg;
4496   vat_json_node_t *counter_array;
4497   vat_json_node_t *counter;
4498   interface_counter_t c;
4499   u64 packets;
4500   ip4_fib_counter_t *c4;
4501   ip6_fib_counter_t *c6;
4502   ip4_nbr_counter_t *n4;
4503   ip6_nbr_counter_t *n6;
4504   int i, j;
4505
4506   if (!vam->json_output)
4507     {
4508       clib_warning ("dump_stats_table supported only in JSON format");
4509       return -99;
4510     }
4511
4512   vat_json_init_object (&node);
4513
4514   /* interface counters */
4515   msg_array = vat_json_object_add (&node, "interface_counters");
4516   vat_json_init_array (msg_array);
4517   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4518     {
4519       msg = vat_json_array_add (msg_array);
4520       vat_json_init_object (msg);
4521       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4522                                        (u8 *) counter_type_to_str (i, 0));
4523       vat_json_object_add_int (msg, "is_combined", 0);
4524       counter_array = vat_json_object_add (msg, "data");
4525       vat_json_init_array (counter_array);
4526       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4527         {
4528           packets = vam->simple_interface_counters[i][j];
4529           vat_json_array_add_uint (counter_array, packets);
4530         }
4531     }
4532   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4533     {
4534       msg = vat_json_array_add (msg_array);
4535       vat_json_init_object (msg);
4536       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4537                                        (u8 *) counter_type_to_str (i, 1));
4538       vat_json_object_add_int (msg, "is_combined", 1);
4539       counter_array = vat_json_object_add (msg, "data");
4540       vat_json_init_array (counter_array);
4541       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4542         {
4543           c = vam->combined_interface_counters[i][j];
4544           counter = vat_json_array_add (counter_array);
4545           vat_json_init_object (counter);
4546           vat_json_object_add_uint (counter, "packets", c.packets);
4547           vat_json_object_add_uint (counter, "bytes", c.bytes);
4548         }
4549     }
4550
4551   /* ip4 fib counters */
4552   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4553   vat_json_init_array (msg_array);
4554   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4555     {
4556       msg = vat_json_array_add (msg_array);
4557       vat_json_init_object (msg);
4558       vat_json_object_add_uint (msg, "vrf_id",
4559                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4560       counter_array = vat_json_object_add (msg, "c");
4561       vat_json_init_array (counter_array);
4562       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4563         {
4564           counter = vat_json_array_add (counter_array);
4565           vat_json_init_object (counter);
4566           c4 = &vam->ip4_fib_counters[i][j];
4567           vat_json_object_add_ip4 (counter, "address", c4->address);
4568           vat_json_object_add_uint (counter, "address_length",
4569                                     c4->address_length);
4570           vat_json_object_add_uint (counter, "packets", c4->packets);
4571           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4572         }
4573     }
4574
4575   /* ip6 fib counters */
4576   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4577   vat_json_init_array (msg_array);
4578   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4579     {
4580       msg = vat_json_array_add (msg_array);
4581       vat_json_init_object (msg);
4582       vat_json_object_add_uint (msg, "vrf_id",
4583                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4584       counter_array = vat_json_object_add (msg, "c");
4585       vat_json_init_array (counter_array);
4586       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4587         {
4588           counter = vat_json_array_add (counter_array);
4589           vat_json_init_object (counter);
4590           c6 = &vam->ip6_fib_counters[i][j];
4591           vat_json_object_add_ip6 (counter, "address", c6->address);
4592           vat_json_object_add_uint (counter, "address_length",
4593                                     c6->address_length);
4594           vat_json_object_add_uint (counter, "packets", c6->packets);
4595           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4596         }
4597     }
4598
4599   /* ip4 nbr counters */
4600   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
4601   vat_json_init_array (msg_array);
4602   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
4603     {
4604       msg = vat_json_array_add (msg_array);
4605       vat_json_init_object (msg);
4606       vat_json_object_add_uint (msg, "sw_if_index", i);
4607       counter_array = vat_json_object_add (msg, "c");
4608       vat_json_init_array (counter_array);
4609       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
4610         {
4611           counter = vat_json_array_add (counter_array);
4612           vat_json_init_object (counter);
4613           n4 = &vam->ip4_nbr_counters[i][j];
4614           vat_json_object_add_ip4 (counter, "address", n4->address);
4615           vat_json_object_add_uint (counter, "link-type", n4->linkt);
4616           vat_json_object_add_uint (counter, "packets", n4->packets);
4617           vat_json_object_add_uint (counter, "bytes", n4->bytes);
4618         }
4619     }
4620
4621   /* ip6 nbr counters */
4622   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
4623   vat_json_init_array (msg_array);
4624   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
4625     {
4626       msg = vat_json_array_add (msg_array);
4627       vat_json_init_object (msg);
4628       vat_json_object_add_uint (msg, "sw_if_index", i);
4629       counter_array = vat_json_object_add (msg, "c");
4630       vat_json_init_array (counter_array);
4631       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
4632         {
4633           counter = vat_json_array_add (counter_array);
4634           vat_json_init_object (counter);
4635           n6 = &vam->ip6_nbr_counters[i][j];
4636           vat_json_object_add_ip6 (counter, "address", n6->address);
4637           vat_json_object_add_uint (counter, "packets", n6->packets);
4638           vat_json_object_add_uint (counter, "bytes", n6->bytes);
4639         }
4640     }
4641
4642   vat_json_print (vam->ofp, &node);
4643   vat_json_free (&node);
4644
4645   return 0;
4646 }
4647
4648 int
4649 exec (vat_main_t * vam)
4650 {
4651   api_main_t *am = &api_main;
4652   vl_api_cli_request_t *mp;
4653   f64 timeout;
4654   void *oldheap;
4655   u8 *cmd = 0;
4656   unformat_input_t *i = vam->input;
4657
4658   if (vec_len (i->buffer) == 0)
4659     return -1;
4660
4661   if (vam->exec_mode == 0 && unformat (i, "mode"))
4662     {
4663       vam->exec_mode = 1;
4664       return 0;
4665     }
4666   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4667     {
4668       vam->exec_mode = 0;
4669       return 0;
4670     }
4671
4672
4673   M (CLI_REQUEST, mp);
4674
4675   /*
4676    * Copy cmd into shared memory.
4677    * In order for the CLI command to work, it
4678    * must be a vector ending in \n, not a C-string ending
4679    * in \n\0.
4680    */
4681   pthread_mutex_lock (&am->vlib_rp->mutex);
4682   oldheap = svm_push_data_heap (am->vlib_rp);
4683
4684   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4685   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4686
4687   svm_pop_heap (oldheap);
4688   pthread_mutex_unlock (&am->vlib_rp->mutex);
4689
4690   mp->cmd_in_shmem = (u64) cmd;
4691   S (mp);
4692   timeout = vat_time_now (vam) + 10.0;
4693
4694   while (vat_time_now (vam) < timeout)
4695     {
4696       if (vam->result_ready == 1)
4697         {
4698           u8 *free_me;
4699           if (vam->shmem_result != NULL)
4700             print (vam->ofp, "%s", vam->shmem_result);
4701           pthread_mutex_lock (&am->vlib_rp->mutex);
4702           oldheap = svm_push_data_heap (am->vlib_rp);
4703
4704           free_me = (u8 *) vam->shmem_result;
4705           vec_free (free_me);
4706
4707           svm_pop_heap (oldheap);
4708           pthread_mutex_unlock (&am->vlib_rp->mutex);
4709           return 0;
4710         }
4711     }
4712   return -99;
4713 }
4714
4715 /*
4716  * Future replacement of exec() that passes CLI buffers directly in
4717  * the API messages instead of an additional shared memory area.
4718  */
4719 static int
4720 exec_inband (vat_main_t * vam)
4721 {
4722   vl_api_cli_inband_t *mp;
4723   unformat_input_t *i = vam->input;
4724   int ret;
4725
4726   if (vec_len (i->buffer) == 0)
4727     return -1;
4728
4729   if (vam->exec_mode == 0 && unformat (i, "mode"))
4730     {
4731       vam->exec_mode = 1;
4732       return 0;
4733     }
4734   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4735     {
4736       vam->exec_mode = 0;
4737       return 0;
4738     }
4739
4740   /*
4741    * In order for the CLI command to work, it
4742    * must be a vector ending in \n, not a C-string ending
4743    * in \n\0.
4744    */
4745   u32 len = vec_len (vam->input->buffer);
4746   M2 (CLI_INBAND, mp, len);
4747   clib_memcpy (mp->cmd, vam->input->buffer, len);
4748   mp->length = htonl (len);
4749
4750   S (mp);
4751   W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
4752   return ret;
4753 }
4754
4755 static int
4756 api_create_loopback (vat_main_t * vam)
4757 {
4758   unformat_input_t *i = vam->input;
4759   vl_api_create_loopback_t *mp;
4760   vl_api_create_loopback_instance_t *mp_lbi;
4761   u8 mac_address[6];
4762   u8 mac_set = 0;
4763   u8 is_specified = 0;
4764   u32 user_instance = 0;
4765   int ret;
4766
4767   memset (mac_address, 0, sizeof (mac_address));
4768
4769   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4770     {
4771       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4772         mac_set = 1;
4773       if (unformat (i, "instance %d", &user_instance))
4774         is_specified = 1;
4775       else
4776         break;
4777     }
4778
4779   if (is_specified)
4780     {
4781       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
4782       mp_lbi->is_specified = is_specified;
4783       if (is_specified)
4784         mp_lbi->user_instance = htonl (user_instance);
4785       if (mac_set)
4786         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
4787       S (mp_lbi);
4788     }
4789   else
4790     {
4791       /* Construct the API message */
4792       M (CREATE_LOOPBACK, mp);
4793       if (mac_set)
4794         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4795       S (mp);
4796     }
4797
4798   W (ret);
4799   return ret;
4800 }
4801
4802 static int
4803 api_delete_loopback (vat_main_t * vam)
4804 {
4805   unformat_input_t *i = vam->input;
4806   vl_api_delete_loopback_t *mp;
4807   u32 sw_if_index = ~0;
4808   int ret;
4809
4810   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4811     {
4812       if (unformat (i, "sw_if_index %d", &sw_if_index))
4813         ;
4814       else
4815         break;
4816     }
4817
4818   if (sw_if_index == ~0)
4819     {
4820       errmsg ("missing sw_if_index");
4821       return -99;
4822     }
4823
4824   /* Construct the API message */
4825   M (DELETE_LOOPBACK, mp);
4826   mp->sw_if_index = ntohl (sw_if_index);
4827
4828   S (mp);
4829   W (ret);
4830   return ret;
4831 }
4832
4833 static int
4834 api_want_stats (vat_main_t * vam)
4835 {
4836   unformat_input_t *i = vam->input;
4837   vl_api_want_stats_t *mp;
4838   int enable = -1;
4839   int ret;
4840
4841   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4842     {
4843       if (unformat (i, "enable"))
4844         enable = 1;
4845       else if (unformat (i, "disable"))
4846         enable = 0;
4847       else
4848         break;
4849     }
4850
4851   if (enable == -1)
4852     {
4853       errmsg ("missing enable|disable");
4854       return -99;
4855     }
4856
4857   M (WANT_STATS, mp);
4858   mp->enable_disable = enable;
4859
4860   S (mp);
4861   W (ret);
4862   return ret;
4863 }
4864
4865 static int
4866 api_want_interface_events (vat_main_t * vam)
4867 {
4868   unformat_input_t *i = vam->input;
4869   vl_api_want_interface_events_t *mp;
4870   int enable = -1;
4871   int ret;
4872
4873   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4874     {
4875       if (unformat (i, "enable"))
4876         enable = 1;
4877       else if (unformat (i, "disable"))
4878         enable = 0;
4879       else
4880         break;
4881     }
4882
4883   if (enable == -1)
4884     {
4885       errmsg ("missing enable|disable");
4886       return -99;
4887     }
4888
4889   M (WANT_INTERFACE_EVENTS, mp);
4890   mp->enable_disable = enable;
4891
4892   vam->interface_event_display = enable;
4893
4894   S (mp);
4895   W (ret);
4896   return ret;
4897 }
4898
4899
4900 /* Note: non-static, called once to set up the initial intfc table */
4901 int
4902 api_sw_interface_dump (vat_main_t * vam)
4903 {
4904   vl_api_sw_interface_dump_t *mp;
4905   vl_api_control_ping_t *mp_ping;
4906   hash_pair_t *p;
4907   name_sort_t *nses = 0, *ns;
4908   sw_interface_subif_t *sub = NULL;
4909   int ret;
4910
4911   /* Toss the old name table */
4912   /* *INDENT-OFF* */
4913   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4914   ({
4915     vec_add2 (nses, ns, 1);
4916     ns->name = (u8 *)(p->key);
4917     ns->value = (u32) p->value[0];
4918   }));
4919   /* *INDENT-ON* */
4920
4921   hash_free (vam->sw_if_index_by_interface_name);
4922
4923   vec_foreach (ns, nses) vec_free (ns->name);
4924
4925   vec_free (nses);
4926
4927   vec_foreach (sub, vam->sw_if_subif_table)
4928   {
4929     vec_free (sub->interface_name);
4930   }
4931   vec_free (vam->sw_if_subif_table);
4932
4933   /* recreate the interface name hash table */
4934   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4935
4936   /* Get list of ethernets */
4937   M (SW_INTERFACE_DUMP, mp);
4938   mp->name_filter_valid = 1;
4939   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4940   S (mp);
4941
4942   /* and local / loopback interfaces */
4943   M (SW_INTERFACE_DUMP, mp);
4944   mp->name_filter_valid = 1;
4945   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4946   S (mp);
4947
4948   /* and packet-generator interfaces */
4949   M (SW_INTERFACE_DUMP, mp);
4950   mp->name_filter_valid = 1;
4951   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4952   S (mp);
4953
4954   /* and vxlan-gpe tunnel interfaces */
4955   M (SW_INTERFACE_DUMP, mp);
4956   mp->name_filter_valid = 1;
4957   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4958            sizeof (mp->name_filter) - 1);
4959   S (mp);
4960
4961   /* and vxlan tunnel interfaces */
4962   M (SW_INTERFACE_DUMP, mp);
4963   mp->name_filter_valid = 1;
4964   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4965   S (mp);
4966
4967   /* and host (af_packet) interfaces */
4968   M (SW_INTERFACE_DUMP, mp);
4969   mp->name_filter_valid = 1;
4970   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4971   S (mp);
4972
4973   /* and l2tpv3 tunnel interfaces */
4974   M (SW_INTERFACE_DUMP, mp);
4975   mp->name_filter_valid = 1;
4976   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4977            sizeof (mp->name_filter) - 1);
4978   S (mp);
4979
4980   /* and GRE tunnel interfaces */
4981   M (SW_INTERFACE_DUMP, mp);
4982   mp->name_filter_valid = 1;
4983   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4984   S (mp);
4985
4986   /* and LISP-GPE interfaces */
4987   M (SW_INTERFACE_DUMP, mp);
4988   mp->name_filter_valid = 1;
4989   strncpy ((char *) mp->name_filter, "lisp_gpe",
4990            sizeof (mp->name_filter) - 1);
4991   S (mp);
4992
4993   /* and IPSEC tunnel interfaces */
4994   M (SW_INTERFACE_DUMP, mp);
4995   mp->name_filter_valid = 1;
4996   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4997   S (mp);
4998
4999   /* Use a control ping for synchronization */
5000   M (CONTROL_PING, mp_ping);
5001   S (mp_ping);
5002
5003   W (ret);
5004   return ret;
5005 }
5006
5007 static int
5008 api_sw_interface_set_flags (vat_main_t * vam)
5009 {
5010   unformat_input_t *i = vam->input;
5011   vl_api_sw_interface_set_flags_t *mp;
5012   u32 sw_if_index;
5013   u8 sw_if_index_set = 0;
5014   u8 admin_up = 0, link_up = 0;
5015   int ret;
5016
5017   /* Parse args required to build the message */
5018   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5019     {
5020       if (unformat (i, "admin-up"))
5021         admin_up = 1;
5022       else if (unformat (i, "admin-down"))
5023         admin_up = 0;
5024       else if (unformat (i, "link-up"))
5025         link_up = 1;
5026       else if (unformat (i, "link-down"))
5027         link_up = 0;
5028       else
5029         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5030         sw_if_index_set = 1;
5031       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5032         sw_if_index_set = 1;
5033       else
5034         break;
5035     }
5036
5037   if (sw_if_index_set == 0)
5038     {
5039       errmsg ("missing interface name or sw_if_index");
5040       return -99;
5041     }
5042
5043   /* Construct the API message */
5044   M (SW_INTERFACE_SET_FLAGS, mp);
5045   mp->sw_if_index = ntohl (sw_if_index);
5046   mp->admin_up_down = admin_up;
5047   mp->link_up_down = link_up;
5048
5049   /* send it... */
5050   S (mp);
5051
5052   /* Wait for a reply, return the good/bad news... */
5053   W (ret);
5054   return ret;
5055 }
5056
5057 static int
5058 api_sw_interface_clear_stats (vat_main_t * vam)
5059 {
5060   unformat_input_t *i = vam->input;
5061   vl_api_sw_interface_clear_stats_t *mp;
5062   u32 sw_if_index;
5063   u8 sw_if_index_set = 0;
5064   int ret;
5065
5066   /* Parse args required to build the message */
5067   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5068     {
5069       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5070         sw_if_index_set = 1;
5071       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5072         sw_if_index_set = 1;
5073       else
5074         break;
5075     }
5076
5077   /* Construct the API message */
5078   M (SW_INTERFACE_CLEAR_STATS, mp);
5079
5080   if (sw_if_index_set == 1)
5081     mp->sw_if_index = ntohl (sw_if_index);
5082   else
5083     mp->sw_if_index = ~0;
5084
5085   /* send it... */
5086   S (mp);
5087
5088   /* Wait for a reply, return the good/bad news... */
5089   W (ret);
5090   return ret;
5091 }
5092
5093 static int
5094 api_sw_interface_add_del_address (vat_main_t * vam)
5095 {
5096   unformat_input_t *i = vam->input;
5097   vl_api_sw_interface_add_del_address_t *mp;
5098   u32 sw_if_index;
5099   u8 sw_if_index_set = 0;
5100   u8 is_add = 1, del_all = 0;
5101   u32 address_length = 0;
5102   u8 v4_address_set = 0;
5103   u8 v6_address_set = 0;
5104   ip4_address_t v4address;
5105   ip6_address_t v6address;
5106   int ret;
5107
5108   /* Parse args required to build the message */
5109   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5110     {
5111       if (unformat (i, "del-all"))
5112         del_all = 1;
5113       else if (unformat (i, "del"))
5114         is_add = 0;
5115       else
5116         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5117         sw_if_index_set = 1;
5118       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5119         sw_if_index_set = 1;
5120       else if (unformat (i, "%U/%d",
5121                          unformat_ip4_address, &v4address, &address_length))
5122         v4_address_set = 1;
5123       else if (unformat (i, "%U/%d",
5124                          unformat_ip6_address, &v6address, &address_length))
5125         v6_address_set = 1;
5126       else
5127         break;
5128     }
5129
5130   if (sw_if_index_set == 0)
5131     {
5132       errmsg ("missing interface name or sw_if_index");
5133       return -99;
5134     }
5135   if (v4_address_set && v6_address_set)
5136     {
5137       errmsg ("both v4 and v6 addresses set");
5138       return -99;
5139     }
5140   if (!v4_address_set && !v6_address_set && !del_all)
5141     {
5142       errmsg ("no addresses set");
5143       return -99;
5144     }
5145
5146   /* Construct the API message */
5147   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
5148
5149   mp->sw_if_index = ntohl (sw_if_index);
5150   mp->is_add = is_add;
5151   mp->del_all = del_all;
5152   if (v6_address_set)
5153     {
5154       mp->is_ipv6 = 1;
5155       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5156     }
5157   else
5158     {
5159       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5160     }
5161   mp->address_length = address_length;
5162
5163   /* send it... */
5164   S (mp);
5165
5166   /* Wait for a reply, return good/bad news  */
5167   W (ret);
5168   return ret;
5169 }
5170
5171 static int
5172 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5173 {
5174   unformat_input_t *i = vam->input;
5175   vl_api_sw_interface_set_mpls_enable_t *mp;
5176   u32 sw_if_index;
5177   u8 sw_if_index_set = 0;
5178   u8 enable = 1;
5179   int ret;
5180
5181   /* Parse args required to build the message */
5182   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5183     {
5184       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5185         sw_if_index_set = 1;
5186       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5187         sw_if_index_set = 1;
5188       else if (unformat (i, "disable"))
5189         enable = 0;
5190       else if (unformat (i, "dis"))
5191         enable = 0;
5192       else
5193         break;
5194     }
5195
5196   if (sw_if_index_set == 0)
5197     {
5198       errmsg ("missing interface name or sw_if_index");
5199       return -99;
5200     }
5201
5202   /* Construct the API message */
5203   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
5204
5205   mp->sw_if_index = ntohl (sw_if_index);
5206   mp->enable = enable;
5207
5208   /* send it... */
5209   S (mp);
5210
5211   /* Wait for a reply... */
5212   W (ret);
5213   return ret;
5214 }
5215
5216 static int
5217 api_sw_interface_set_table (vat_main_t * vam)
5218 {
5219   unformat_input_t *i = vam->input;
5220   vl_api_sw_interface_set_table_t *mp;
5221   u32 sw_if_index, vrf_id = 0;
5222   u8 sw_if_index_set = 0;
5223   u8 is_ipv6 = 0;
5224   int ret;
5225
5226   /* Parse args required to build the message */
5227   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5228     {
5229       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5230         sw_if_index_set = 1;
5231       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5232         sw_if_index_set = 1;
5233       else if (unformat (i, "vrf %d", &vrf_id))
5234         ;
5235       else if (unformat (i, "ipv6"))
5236         is_ipv6 = 1;
5237       else
5238         break;
5239     }
5240
5241   if (sw_if_index_set == 0)
5242     {
5243       errmsg ("missing interface name or sw_if_index");
5244       return -99;
5245     }
5246
5247   /* Construct the API message */
5248   M (SW_INTERFACE_SET_TABLE, mp);
5249
5250   mp->sw_if_index = ntohl (sw_if_index);
5251   mp->is_ipv6 = is_ipv6;
5252   mp->vrf_id = ntohl (vrf_id);
5253
5254   /* send it... */
5255   S (mp);
5256
5257   /* Wait for a reply... */
5258   W (ret);
5259   return ret;
5260 }
5261
5262 static void vl_api_sw_interface_get_table_reply_t_handler
5263   (vl_api_sw_interface_get_table_reply_t * mp)
5264 {
5265   vat_main_t *vam = &vat_main;
5266
5267   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5268
5269   vam->retval = ntohl (mp->retval);
5270   vam->result_ready = 1;
5271
5272 }
5273
5274 static void vl_api_sw_interface_get_table_reply_t_handler_json
5275   (vl_api_sw_interface_get_table_reply_t * mp)
5276 {
5277   vat_main_t *vam = &vat_main;
5278   vat_json_node_t node;
5279
5280   vat_json_init_object (&node);
5281   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5282   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5283
5284   vat_json_print (vam->ofp, &node);
5285   vat_json_free (&node);
5286
5287   vam->retval = ntohl (mp->retval);
5288   vam->result_ready = 1;
5289 }
5290
5291 static int
5292 api_sw_interface_get_table (vat_main_t * vam)
5293 {
5294   unformat_input_t *i = vam->input;
5295   vl_api_sw_interface_get_table_t *mp;
5296   u32 sw_if_index;
5297   u8 sw_if_index_set = 0;
5298   u8 is_ipv6 = 0;
5299   int ret;
5300
5301   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5302     {
5303       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5304         sw_if_index_set = 1;
5305       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5306         sw_if_index_set = 1;
5307       else if (unformat (i, "ipv6"))
5308         is_ipv6 = 1;
5309       else
5310         break;
5311     }
5312
5313   if (sw_if_index_set == 0)
5314     {
5315       errmsg ("missing interface name or sw_if_index");
5316       return -99;
5317     }
5318
5319   M (SW_INTERFACE_GET_TABLE, mp);
5320   mp->sw_if_index = htonl (sw_if_index);
5321   mp->is_ipv6 = is_ipv6;
5322
5323   S (mp);
5324   W (ret);
5325   return ret;
5326 }
5327
5328 static int
5329 api_sw_interface_set_vpath (vat_main_t * vam)
5330 {
5331   unformat_input_t *i = vam->input;
5332   vl_api_sw_interface_set_vpath_t *mp;
5333   u32 sw_if_index = 0;
5334   u8 sw_if_index_set = 0;
5335   u8 is_enable = 0;
5336   int ret;
5337
5338   /* Parse args required to build the message */
5339   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5340     {
5341       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5342         sw_if_index_set = 1;
5343       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5344         sw_if_index_set = 1;
5345       else if (unformat (i, "enable"))
5346         is_enable = 1;
5347       else if (unformat (i, "disable"))
5348         is_enable = 0;
5349       else
5350         break;
5351     }
5352
5353   if (sw_if_index_set == 0)
5354     {
5355       errmsg ("missing interface name or sw_if_index");
5356       return -99;
5357     }
5358
5359   /* Construct the API message */
5360   M (SW_INTERFACE_SET_VPATH, mp);
5361
5362   mp->sw_if_index = ntohl (sw_if_index);
5363   mp->enable = is_enable;
5364
5365   /* send it... */
5366   S (mp);
5367
5368   /* Wait for a reply... */
5369   W (ret);
5370   return ret;
5371 }
5372
5373 static int
5374 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5375 {
5376   unformat_input_t *i = vam->input;
5377   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5378   u32 sw_if_index = 0;
5379   u8 sw_if_index_set = 0;
5380   u8 is_enable = 1;
5381   u8 is_ipv6 = 0;
5382   int ret;
5383
5384   /* Parse args required to build the message */
5385   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5386     {
5387       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5388         sw_if_index_set = 1;
5389       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5390         sw_if_index_set = 1;
5391       else if (unformat (i, "enable"))
5392         is_enable = 1;
5393       else if (unformat (i, "disable"))
5394         is_enable = 0;
5395       else if (unformat (i, "ip4"))
5396         is_ipv6 = 0;
5397       else if (unformat (i, "ip6"))
5398         is_ipv6 = 1;
5399       else
5400         break;
5401     }
5402
5403   if (sw_if_index_set == 0)
5404     {
5405       errmsg ("missing interface name or sw_if_index");
5406       return -99;
5407     }
5408
5409   /* Construct the API message */
5410   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
5411
5412   mp->sw_if_index = ntohl (sw_if_index);
5413   mp->enable = is_enable;
5414   mp->is_ipv6 = is_ipv6;
5415
5416   /* send it... */
5417   S (mp);
5418
5419   /* Wait for a reply... */
5420   W (ret);
5421   return ret;
5422 }
5423
5424 static int
5425 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5426 {
5427   unformat_input_t *i = vam->input;
5428   vl_api_sw_interface_set_l2_xconnect_t *mp;
5429   u32 rx_sw_if_index;
5430   u8 rx_sw_if_index_set = 0;
5431   u32 tx_sw_if_index;
5432   u8 tx_sw_if_index_set = 0;
5433   u8 enable = 1;
5434   int ret;
5435
5436   /* Parse args required to build the message */
5437   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5438     {
5439       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5440         rx_sw_if_index_set = 1;
5441       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5442         tx_sw_if_index_set = 1;
5443       else if (unformat (i, "rx"))
5444         {
5445           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5446             {
5447               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5448                             &rx_sw_if_index))
5449                 rx_sw_if_index_set = 1;
5450             }
5451           else
5452             break;
5453         }
5454       else if (unformat (i, "tx"))
5455         {
5456           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5457             {
5458               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5459                             &tx_sw_if_index))
5460                 tx_sw_if_index_set = 1;
5461             }
5462           else
5463             break;
5464         }
5465       else if (unformat (i, "enable"))
5466         enable = 1;
5467       else if (unformat (i, "disable"))
5468         enable = 0;
5469       else
5470         break;
5471     }
5472
5473   if (rx_sw_if_index_set == 0)
5474     {
5475       errmsg ("missing rx interface name or rx_sw_if_index");
5476       return -99;
5477     }
5478
5479   if (enable && (tx_sw_if_index_set == 0))
5480     {
5481       errmsg ("missing tx interface name or tx_sw_if_index");
5482       return -99;
5483     }
5484
5485   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
5486
5487   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5488   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5489   mp->enable = enable;
5490
5491   S (mp);
5492   W (ret);
5493   return ret;
5494 }
5495
5496 static int
5497 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5498 {
5499   unformat_input_t *i = vam->input;
5500   vl_api_sw_interface_set_l2_bridge_t *mp;
5501   u32 rx_sw_if_index;
5502   u8 rx_sw_if_index_set = 0;
5503   u32 bd_id;
5504   u8 bd_id_set = 0;
5505   u8 bvi = 0;
5506   u32 shg = 0;
5507   u8 enable = 1;
5508   int ret;
5509
5510   /* Parse args required to build the message */
5511   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5512     {
5513       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5514         rx_sw_if_index_set = 1;
5515       else if (unformat (i, "bd_id %d", &bd_id))
5516         bd_id_set = 1;
5517       else
5518         if (unformat
5519             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5520         rx_sw_if_index_set = 1;
5521       else if (unformat (i, "shg %d", &shg))
5522         ;
5523       else if (unformat (i, "bvi"))
5524         bvi = 1;
5525       else if (unformat (i, "enable"))
5526         enable = 1;
5527       else if (unformat (i, "disable"))
5528         enable = 0;
5529       else
5530         break;
5531     }
5532
5533   if (rx_sw_if_index_set == 0)
5534     {
5535       errmsg ("missing rx interface name or sw_if_index");
5536       return -99;
5537     }
5538
5539   if (enable && (bd_id_set == 0))
5540     {
5541       errmsg ("missing bridge domain");
5542       return -99;
5543     }
5544
5545   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
5546
5547   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5548   mp->bd_id = ntohl (bd_id);
5549   mp->shg = (u8) shg;
5550   mp->bvi = bvi;
5551   mp->enable = enable;
5552
5553   S (mp);
5554   W (ret);
5555   return ret;
5556 }
5557
5558 static int
5559 api_bridge_domain_dump (vat_main_t * vam)
5560 {
5561   unformat_input_t *i = vam->input;
5562   vl_api_bridge_domain_dump_t *mp;
5563   vl_api_control_ping_t *mp_ping;
5564   u32 bd_id = ~0;
5565   int ret;
5566
5567   /* Parse args required to build the message */
5568   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5569     {
5570       if (unformat (i, "bd_id %d", &bd_id))
5571         ;
5572       else
5573         break;
5574     }
5575
5576   M (BRIDGE_DOMAIN_DUMP, mp);
5577   mp->bd_id = ntohl (bd_id);
5578   S (mp);
5579
5580   /* Use a control ping for synchronization */
5581   M (CONTROL_PING, mp_ping);
5582   S (mp_ping);
5583
5584   W (ret);
5585   return ret;
5586 }
5587
5588 static int
5589 api_bridge_domain_add_del (vat_main_t * vam)
5590 {
5591   unformat_input_t *i = vam->input;
5592   vl_api_bridge_domain_add_del_t *mp;
5593   u32 bd_id = ~0;
5594   u8 is_add = 1;
5595   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5596   u32 mac_age = 0;
5597   int ret;
5598
5599   /* Parse args required to build the message */
5600   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5601     {
5602       if (unformat (i, "bd_id %d", &bd_id))
5603         ;
5604       else if (unformat (i, "flood %d", &flood))
5605         ;
5606       else if (unformat (i, "uu-flood %d", &uu_flood))
5607         ;
5608       else if (unformat (i, "forward %d", &forward))
5609         ;
5610       else if (unformat (i, "learn %d", &learn))
5611         ;
5612       else if (unformat (i, "arp-term %d", &arp_term))
5613         ;
5614       else if (unformat (i, "mac-age %d", &mac_age))
5615         ;
5616       else if (unformat (i, "del"))
5617         {
5618           is_add = 0;
5619           flood = uu_flood = forward = learn = 0;
5620         }
5621       else
5622         break;
5623     }
5624
5625   if (bd_id == ~0)
5626     {
5627       errmsg ("missing bridge domain");
5628       return -99;
5629     }
5630
5631   if (mac_age > 255)
5632     {
5633       errmsg ("mac age must be less than 256 ");
5634       return -99;
5635     }
5636
5637   M (BRIDGE_DOMAIN_ADD_DEL, mp);
5638
5639   mp->bd_id = ntohl (bd_id);
5640   mp->flood = flood;
5641   mp->uu_flood = uu_flood;
5642   mp->forward = forward;
5643   mp->learn = learn;
5644   mp->arp_term = arp_term;
5645   mp->is_add = is_add;
5646   mp->mac_age = (u8) mac_age;
5647
5648   S (mp);
5649   W (ret);
5650   return ret;
5651 }
5652
5653 static int
5654 api_l2fib_add_del (vat_main_t * vam)
5655 {
5656   unformat_input_t *i = vam->input;
5657   vl_api_l2fib_add_del_t *mp;
5658   f64 timeout;
5659   u64 mac = 0;
5660   u8 mac_set = 0;
5661   u32 bd_id;
5662   u8 bd_id_set = 0;
5663   u32 sw_if_index = ~0;
5664   u8 sw_if_index_set = 0;
5665   u8 is_add = 1;
5666   u8 static_mac = 0;
5667   u8 filter_mac = 0;
5668   u8 bvi_mac = 0;
5669   int count = 1;
5670   f64 before = 0;
5671   int j;
5672
5673   /* Parse args required to build the message */
5674   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5675     {
5676       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5677         mac_set = 1;
5678       else if (unformat (i, "bd_id %d", &bd_id))
5679         bd_id_set = 1;
5680       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5681         sw_if_index_set = 1;
5682       else if (unformat (i, "sw_if"))
5683         {
5684           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5685             {
5686               if (unformat
5687                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5688                 sw_if_index_set = 1;
5689             }
5690           else
5691             break;
5692         }
5693       else if (unformat (i, "static"))
5694         static_mac = 1;
5695       else if (unformat (i, "filter"))
5696         {
5697           filter_mac = 1;
5698           static_mac = 1;
5699         }
5700       else if (unformat (i, "bvi"))
5701         {
5702           bvi_mac = 1;
5703           static_mac = 1;
5704         }
5705       else if (unformat (i, "del"))
5706         is_add = 0;
5707       else if (unformat (i, "count %d", &count))
5708         ;
5709       else
5710         break;
5711     }
5712
5713   if (mac_set == 0)
5714     {
5715       errmsg ("missing mac address");
5716       return -99;
5717     }
5718
5719   if (bd_id_set == 0)
5720     {
5721       errmsg ("missing bridge domain");
5722       return -99;
5723     }
5724
5725   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
5726     {
5727       errmsg ("missing interface name or sw_if_index");
5728       return -99;
5729     }
5730
5731   if (count > 1)
5732     {
5733       /* Turn on async mode */
5734       vam->async_mode = 1;
5735       vam->async_errors = 0;
5736       before = vat_time_now (vam);
5737     }
5738
5739   for (j = 0; j < count; j++)
5740     {
5741       M (L2FIB_ADD_DEL, mp);
5742
5743       mp->mac = mac;
5744       mp->bd_id = ntohl (bd_id);
5745       mp->is_add = is_add;
5746
5747       if (is_add)
5748         {
5749           mp->sw_if_index = ntohl (sw_if_index);
5750           mp->static_mac = static_mac;
5751           mp->filter_mac = filter_mac;
5752           mp->bvi_mac = bvi_mac;
5753         }
5754       increment_mac_address (&mac);
5755       /* send it... */
5756       S (mp);
5757     }
5758
5759   if (count > 1)
5760     {
5761       vl_api_control_ping_t *mp_ping;
5762       f64 after;
5763
5764       /* Shut off async mode */
5765       vam->async_mode = 0;
5766
5767       M (CONTROL_PING, mp_ping);
5768       S (mp_ping);
5769
5770       timeout = vat_time_now (vam) + 1.0;
5771       while (vat_time_now (vam) < timeout)
5772         if (vam->result_ready == 1)
5773           goto out;
5774       vam->retval = -99;
5775
5776     out:
5777       if (vam->retval == -99)
5778         errmsg ("timeout");
5779
5780       if (vam->async_errors > 0)
5781         {
5782           errmsg ("%d asynchronous errors", vam->async_errors);
5783           vam->retval = -98;
5784         }
5785       vam->async_errors = 0;
5786       after = vat_time_now (vam);
5787
5788       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
5789              count, after - before, count / (after - before));
5790     }
5791   else
5792     {
5793       int ret;
5794
5795       /* Wait for a reply... */
5796       W (ret);
5797       return ret;
5798     }
5799   /* Return the good/bad news */
5800   return (vam->retval);
5801 }
5802
5803 static int
5804 api_l2_flags (vat_main_t * vam)
5805 {
5806   unformat_input_t *i = vam->input;
5807   vl_api_l2_flags_t *mp;
5808   u32 sw_if_index;
5809   u32 feature_bitmap = 0;
5810   u8 sw_if_index_set = 0;
5811   int ret;
5812
5813   /* Parse args required to build the message */
5814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5815     {
5816       if (unformat (i, "sw_if_index %d", &sw_if_index))
5817         sw_if_index_set = 1;
5818       else if (unformat (i, "sw_if"))
5819         {
5820           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5821             {
5822               if (unformat
5823                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5824                 sw_if_index_set = 1;
5825             }
5826           else
5827             break;
5828         }
5829       else if (unformat (i, "learn"))
5830         feature_bitmap |= L2INPUT_FEAT_LEARN;
5831       else if (unformat (i, "forward"))
5832         feature_bitmap |= L2INPUT_FEAT_FWD;
5833       else if (unformat (i, "flood"))
5834         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5835       else if (unformat (i, "uu-flood"))
5836         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5837       else
5838         break;
5839     }
5840
5841   if (sw_if_index_set == 0)
5842     {
5843       errmsg ("missing interface name or sw_if_index");
5844       return -99;
5845     }
5846
5847   M (L2_FLAGS, mp);
5848
5849   mp->sw_if_index = ntohl (sw_if_index);
5850   mp->feature_bitmap = ntohl (feature_bitmap);
5851
5852   S (mp);
5853   W (ret);
5854   return ret;
5855 }
5856
5857 static int
5858 api_bridge_flags (vat_main_t * vam)
5859 {
5860   unformat_input_t *i = vam->input;
5861   vl_api_bridge_flags_t *mp;
5862   u32 bd_id;
5863   u8 bd_id_set = 0;
5864   u8 is_set = 1;
5865   u32 flags = 0;
5866   int ret;
5867
5868   /* Parse args required to build the message */
5869   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5870     {
5871       if (unformat (i, "bd_id %d", &bd_id))
5872         bd_id_set = 1;
5873       else if (unformat (i, "learn"))
5874         flags |= L2_LEARN;
5875       else if (unformat (i, "forward"))
5876         flags |= L2_FWD;
5877       else if (unformat (i, "flood"))
5878         flags |= L2_FLOOD;
5879       else if (unformat (i, "uu-flood"))
5880         flags |= L2_UU_FLOOD;
5881       else if (unformat (i, "arp-term"))
5882         flags |= L2_ARP_TERM;
5883       else if (unformat (i, "off"))
5884         is_set = 0;
5885       else if (unformat (i, "disable"))
5886         is_set = 0;
5887       else
5888         break;
5889     }
5890
5891   if (bd_id_set == 0)
5892     {
5893       errmsg ("missing bridge domain");
5894       return -99;
5895     }
5896
5897   M (BRIDGE_FLAGS, mp);
5898
5899   mp->bd_id = ntohl (bd_id);
5900   mp->feature_bitmap = ntohl (flags);
5901   mp->is_set = is_set;
5902
5903   S (mp);
5904   W (ret);
5905   return ret;
5906 }
5907
5908 static int
5909 api_bd_ip_mac_add_del (vat_main_t * vam)
5910 {
5911   unformat_input_t *i = vam->input;
5912   vl_api_bd_ip_mac_add_del_t *mp;
5913   u32 bd_id;
5914   u8 is_ipv6 = 0;
5915   u8 is_add = 1;
5916   u8 bd_id_set = 0;
5917   u8 ip_set = 0;
5918   u8 mac_set = 0;
5919   ip4_address_t v4addr;
5920   ip6_address_t v6addr;
5921   u8 macaddr[6];
5922   int ret;
5923
5924
5925   /* Parse args required to build the message */
5926   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5927     {
5928       if (unformat (i, "bd_id %d", &bd_id))
5929         {
5930           bd_id_set++;
5931         }
5932       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5933         {
5934           ip_set++;
5935         }
5936       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5937         {
5938           ip_set++;
5939           is_ipv6++;
5940         }
5941       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5942         {
5943           mac_set++;
5944         }
5945       else if (unformat (i, "del"))
5946         is_add = 0;
5947       else
5948         break;
5949     }
5950
5951   if (bd_id_set == 0)
5952     {
5953       errmsg ("missing bridge domain");
5954       return -99;
5955     }
5956   else if (ip_set == 0)
5957     {
5958       errmsg ("missing IP address");
5959       return -99;
5960     }
5961   else if (mac_set == 0)
5962     {
5963       errmsg ("missing MAC address");
5964       return -99;
5965     }
5966
5967   M (BD_IP_MAC_ADD_DEL, mp);
5968
5969   mp->bd_id = ntohl (bd_id);
5970   mp->is_ipv6 = is_ipv6;
5971   mp->is_add = is_add;
5972   if (is_ipv6)
5973     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5974   else
5975     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5976   clib_memcpy (mp->mac_address, macaddr, 6);
5977   S (mp);
5978   W (ret);
5979   return ret;
5980 }
5981
5982 static int
5983 api_tap_connect (vat_main_t * vam)
5984 {
5985   unformat_input_t *i = vam->input;
5986   vl_api_tap_connect_t *mp;
5987   u8 mac_address[6];
5988   u8 random_mac = 1;
5989   u8 name_set = 0;
5990   u8 *tap_name;
5991   u8 *tag = 0;
5992   ip4_address_t ip4_address;
5993   u32 ip4_mask_width;
5994   int ip4_address_set = 0;
5995   ip6_address_t ip6_address;
5996   u32 ip6_mask_width;
5997   int ip6_address_set = 0;
5998   int ret;
5999
6000   memset (mac_address, 0, sizeof (mac_address));
6001
6002   /* Parse args required to build the message */
6003   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6004     {
6005       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6006         {
6007           random_mac = 0;
6008         }
6009       else if (unformat (i, "random-mac"))
6010         random_mac = 1;
6011       else if (unformat (i, "tapname %s", &tap_name))
6012         name_set = 1;
6013       else if (unformat (i, "tag %s", &tag))
6014         ;
6015       else if (unformat (i, "address %U/%d",
6016                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
6017         ip4_address_set = 1;
6018       else if (unformat (i, "address %U/%d",
6019                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
6020         ip6_address_set = 1;
6021       else
6022         break;
6023     }
6024
6025   if (name_set == 0)
6026     {
6027       errmsg ("missing tap name");
6028       return -99;
6029     }
6030   if (vec_len (tap_name) > 63)
6031     {
6032       errmsg ("tap name too long");
6033       return -99;
6034     }
6035   vec_add1 (tap_name, 0);
6036
6037   if (vec_len (tag) > 63)
6038     {
6039       errmsg ("tag too long");
6040       return -99;
6041     }
6042
6043   /* Construct the API message */
6044   M (TAP_CONNECT, mp);
6045
6046   mp->use_random_mac = random_mac;
6047   clib_memcpy (mp->mac_address, mac_address, 6);
6048   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6049   if (tag)
6050     clib_memcpy (mp->tag, tag, vec_len (tag));
6051
6052   if (ip4_address_set)
6053     {
6054       mp->ip4_address_set = 1;
6055       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6056       mp->ip4_mask_width = ip4_mask_width;
6057     }
6058   if (ip6_address_set)
6059     {
6060       mp->ip6_address_set = 1;
6061       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6062       mp->ip6_mask_width = ip6_mask_width;
6063     }
6064
6065   vec_free (tap_name);
6066   vec_free (tag);
6067
6068   /* send it... */
6069   S (mp);
6070
6071   /* Wait for a reply... */
6072   W (ret);
6073   return ret;
6074 }
6075
6076 static int
6077 api_tap_modify (vat_main_t * vam)
6078 {
6079   unformat_input_t *i = vam->input;
6080   vl_api_tap_modify_t *mp;
6081   u8 mac_address[6];
6082   u8 random_mac = 1;
6083   u8 name_set = 0;
6084   u8 *tap_name;
6085   u32 sw_if_index = ~0;
6086   u8 sw_if_index_set = 0;
6087   int ret;
6088
6089   memset (mac_address, 0, sizeof (mac_address));
6090
6091   /* Parse args required to build the message */
6092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6093     {
6094       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6095         sw_if_index_set = 1;
6096       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6097         sw_if_index_set = 1;
6098       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6099         {
6100           random_mac = 0;
6101         }
6102       else if (unformat (i, "random-mac"))
6103         random_mac = 1;
6104       else if (unformat (i, "tapname %s", &tap_name))
6105         name_set = 1;
6106       else
6107         break;
6108     }
6109
6110   if (sw_if_index_set == 0)
6111     {
6112       errmsg ("missing vpp interface name");
6113       return -99;
6114     }
6115   if (name_set == 0)
6116     {
6117       errmsg ("missing tap name");
6118       return -99;
6119     }
6120   if (vec_len (tap_name) > 63)
6121     {
6122       errmsg ("tap name too long");
6123     }
6124   vec_add1 (tap_name, 0);
6125
6126   /* Construct the API message */
6127   M (TAP_MODIFY, mp);
6128
6129   mp->use_random_mac = random_mac;
6130   mp->sw_if_index = ntohl (sw_if_index);
6131   clib_memcpy (mp->mac_address, mac_address, 6);
6132   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6133   vec_free (tap_name);
6134
6135   /* send it... */
6136   S (mp);
6137
6138   /* Wait for a reply... */
6139   W (ret);
6140   return ret;
6141 }
6142
6143 static int
6144 api_tap_delete (vat_main_t * vam)
6145 {
6146   unformat_input_t *i = vam->input;
6147   vl_api_tap_delete_t *mp;
6148   u32 sw_if_index = ~0;
6149   u8 sw_if_index_set = 0;
6150   int ret;
6151
6152   /* Parse args required to build the message */
6153   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6154     {
6155       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6156         sw_if_index_set = 1;
6157       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6158         sw_if_index_set = 1;
6159       else
6160         break;
6161     }
6162
6163   if (sw_if_index_set == 0)
6164     {
6165       errmsg ("missing vpp interface name");
6166       return -99;
6167     }
6168
6169   /* Construct the API message */
6170   M (TAP_DELETE, mp);
6171
6172   mp->sw_if_index = ntohl (sw_if_index);
6173
6174   /* send it... */
6175   S (mp);
6176
6177   /* Wait for a reply... */
6178   W (ret);
6179   return ret;
6180 }
6181
6182 static int
6183 api_ip_add_del_route (vat_main_t * vam)
6184 {
6185   unformat_input_t *i = vam->input;
6186   vl_api_ip_add_del_route_t *mp;
6187   u32 sw_if_index = ~0, vrf_id = 0;
6188   u8 is_ipv6 = 0;
6189   u8 is_local = 0, is_drop = 0;
6190   u8 is_unreach = 0, is_prohibit = 0;
6191   u8 create_vrf_if_needed = 0;
6192   u8 is_add = 1;
6193   u32 next_hop_weight = 1;
6194   u8 not_last = 0;
6195   u8 is_multipath = 0;
6196   u8 address_set = 0;
6197   u8 address_length_set = 0;
6198   u32 next_hop_table_id = 0;
6199   u32 resolve_attempts = 0;
6200   u32 dst_address_length = 0;
6201   u8 next_hop_set = 0;
6202   ip4_address_t v4_dst_address, v4_next_hop_address;
6203   ip6_address_t v6_dst_address, v6_next_hop_address;
6204   int count = 1;
6205   int j;
6206   f64 before = 0;
6207   u32 random_add_del = 0;
6208   u32 *random_vector = 0;
6209   uword *random_hash;
6210   u32 random_seed = 0xdeaddabe;
6211   u32 classify_table_index = ~0;
6212   u8 is_classify = 0;
6213   u8 resolve_host = 0, resolve_attached = 0;
6214   mpls_label_t *next_hop_out_label_stack = NULL;
6215   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6216   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6217
6218   /* Parse args required to build the message */
6219   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6220     {
6221       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6222         ;
6223       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6224         ;
6225       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6226         {
6227           address_set = 1;
6228           is_ipv6 = 0;
6229         }
6230       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6231         {
6232           address_set = 1;
6233           is_ipv6 = 1;
6234         }
6235       else if (unformat (i, "/%d", &dst_address_length))
6236         {
6237           address_length_set = 1;
6238         }
6239
6240       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6241                                          &v4_next_hop_address))
6242         {
6243           next_hop_set = 1;
6244         }
6245       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6246                                          &v6_next_hop_address))
6247         {
6248           next_hop_set = 1;
6249         }
6250       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6251         ;
6252       else if (unformat (i, "weight %d", &next_hop_weight))
6253         ;
6254       else if (unformat (i, "drop"))
6255         {
6256           is_drop = 1;
6257         }
6258       else if (unformat (i, "null-send-unreach"))
6259         {
6260           is_unreach = 1;
6261         }
6262       else if (unformat (i, "null-send-prohibit"))
6263         {
6264           is_prohibit = 1;
6265         }
6266       else if (unformat (i, "local"))
6267         {
6268           is_local = 1;
6269         }
6270       else if (unformat (i, "classify %d", &classify_table_index))
6271         {
6272           is_classify = 1;
6273         }
6274       else if (unformat (i, "del"))
6275         is_add = 0;
6276       else if (unformat (i, "add"))
6277         is_add = 1;
6278       else if (unformat (i, "not-last"))
6279         not_last = 1;
6280       else if (unformat (i, "resolve-via-host"))
6281         resolve_host = 1;
6282       else if (unformat (i, "resolve-via-attached"))
6283         resolve_attached = 1;
6284       else if (unformat (i, "multipath"))
6285         is_multipath = 1;
6286       else if (unformat (i, "vrf %d", &vrf_id))
6287         ;
6288       else if (unformat (i, "create-vrf"))
6289         create_vrf_if_needed = 1;
6290       else if (unformat (i, "count %d", &count))
6291         ;
6292       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6293         ;
6294       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6295         ;
6296       else if (unformat (i, "out-label %d", &next_hop_out_label))
6297         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6298       else if (unformat (i, "via-label %d", &next_hop_via_label))
6299         ;
6300       else if (unformat (i, "random"))
6301         random_add_del = 1;
6302       else if (unformat (i, "seed %d", &random_seed))
6303         ;
6304       else
6305         {
6306           clib_warning ("parse error '%U'", format_unformat_error, i);
6307           return -99;
6308         }
6309     }
6310
6311   if (!next_hop_set && !is_drop && !is_local &&
6312       !is_classify && !is_unreach && !is_prohibit &&
6313       MPLS_LABEL_INVALID == next_hop_via_label)
6314     {
6315       errmsg
6316         ("next hop / local / drop / unreach / prohibit / classify not set");
6317       return -99;
6318     }
6319
6320   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6321     {
6322       errmsg ("next hop and next-hop via label set");
6323       return -99;
6324     }
6325   if (address_set == 0)
6326     {
6327       errmsg ("missing addresses");
6328       return -99;
6329     }
6330
6331   if (address_length_set == 0)
6332     {
6333       errmsg ("missing address length");
6334       return -99;
6335     }
6336
6337   /* Generate a pile of unique, random routes */
6338   if (random_add_del)
6339     {
6340       u32 this_random_address;
6341       random_hash = hash_create (count, sizeof (uword));
6342
6343       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6344       for (j = 0; j <= count; j++)
6345         {
6346           do
6347             {
6348               this_random_address = random_u32 (&random_seed);
6349               this_random_address =
6350                 clib_host_to_net_u32 (this_random_address);
6351             }
6352           while (hash_get (random_hash, this_random_address));
6353           vec_add1 (random_vector, this_random_address);
6354           hash_set (random_hash, this_random_address, 1);
6355         }
6356       hash_free (random_hash);
6357       v4_dst_address.as_u32 = random_vector[0];
6358     }
6359
6360   if (count > 1)
6361     {
6362       /* Turn on async mode */
6363       vam->async_mode = 1;
6364       vam->async_errors = 0;
6365       before = vat_time_now (vam);
6366     }
6367
6368   for (j = 0; j < count; j++)
6369     {
6370       /* Construct the API message */
6371       M2 (IP_ADD_DEL_ROUTE, mp,
6372           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6373
6374       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6375       mp->table_id = ntohl (vrf_id);
6376       mp->create_vrf_if_needed = create_vrf_if_needed;
6377
6378       mp->is_add = is_add;
6379       mp->is_drop = is_drop;
6380       mp->is_unreach = is_unreach;
6381       mp->is_prohibit = is_prohibit;
6382       mp->is_ipv6 = is_ipv6;
6383       mp->is_local = is_local;
6384       mp->is_classify = is_classify;
6385       mp->is_multipath = is_multipath;
6386       mp->is_resolve_host = resolve_host;
6387       mp->is_resolve_attached = resolve_attached;
6388       mp->not_last = not_last;
6389       mp->next_hop_weight = next_hop_weight;
6390       mp->dst_address_length = dst_address_length;
6391       mp->next_hop_table_id = ntohl (next_hop_table_id);
6392       mp->classify_table_index = ntohl (classify_table_index);
6393       mp->next_hop_via_label = ntohl (next_hop_via_label);
6394       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6395       if (0 != mp->next_hop_n_out_labels)
6396         {
6397           memcpy (mp->next_hop_out_label_stack,
6398                   next_hop_out_label_stack,
6399                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6400           vec_free (next_hop_out_label_stack);
6401         }
6402
6403       if (is_ipv6)
6404         {
6405           clib_memcpy (mp->dst_address, &v6_dst_address,
6406                        sizeof (v6_dst_address));
6407           if (next_hop_set)
6408             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6409                          sizeof (v6_next_hop_address));
6410           increment_v6_address (&v6_dst_address);
6411         }
6412       else
6413         {
6414           clib_memcpy (mp->dst_address, &v4_dst_address,
6415                        sizeof (v4_dst_address));
6416           if (next_hop_set)
6417             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6418                          sizeof (v4_next_hop_address));
6419           if (random_add_del)
6420             v4_dst_address.as_u32 = random_vector[j + 1];
6421           else
6422             increment_v4_address (&v4_dst_address);
6423         }
6424       /* send it... */
6425       S (mp);
6426       /* If we receive SIGTERM, stop now... */
6427       if (vam->do_exit)
6428         break;
6429     }
6430
6431   /* When testing multiple add/del ops, use a control-ping to sync */
6432   if (count > 1)
6433     {
6434       vl_api_control_ping_t *mp_ping;
6435       f64 after;
6436       f64 timeout;
6437
6438       /* Shut off async mode */
6439       vam->async_mode = 0;
6440
6441       M (CONTROL_PING, mp_ping);
6442       S (mp_ping);
6443
6444       timeout = vat_time_now (vam) + 1.0;
6445       while (vat_time_now (vam) < timeout)
6446         if (vam->result_ready == 1)
6447           goto out;
6448       vam->retval = -99;
6449
6450     out:
6451       if (vam->retval == -99)
6452         errmsg ("timeout");
6453
6454       if (vam->async_errors > 0)
6455         {
6456           errmsg ("%d asynchronous errors", vam->async_errors);
6457           vam->retval = -98;
6458         }
6459       vam->async_errors = 0;
6460       after = vat_time_now (vam);
6461
6462       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6463       if (j > 0)
6464         count = j;
6465
6466       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6467              count, after - before, count / (after - before));
6468     }
6469   else
6470     {
6471       int ret;
6472
6473       /* Wait for a reply... */
6474       W (ret);
6475       return ret;
6476     }
6477
6478   /* Return the good/bad news */
6479   return (vam->retval);
6480 }
6481
6482 static int
6483 api_ip_mroute_add_del (vat_main_t * vam)
6484 {
6485   unformat_input_t *i = vam->input;
6486   vl_api_ip_mroute_add_del_t *mp;
6487   u32 sw_if_index = ~0, vrf_id = 0;
6488   u8 is_ipv6 = 0;
6489   u8 is_local = 0;
6490   u8 create_vrf_if_needed = 0;
6491   u8 is_add = 1;
6492   u8 address_set = 0;
6493   u32 grp_address_length = 0;
6494   ip4_address_t v4_grp_address, v4_src_address;
6495   ip6_address_t v6_grp_address, v6_src_address;
6496   mfib_itf_flags_t iflags = 0;
6497   mfib_entry_flags_t eflags = 0;
6498   int ret;
6499
6500   /* Parse args required to build the message */
6501   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6502     {
6503       if (unformat (i, "sw_if_index %d", &sw_if_index))
6504         ;
6505       else if (unformat (i, "%U %U",
6506                          unformat_ip4_address, &v4_src_address,
6507                          unformat_ip4_address, &v4_grp_address))
6508         {
6509           grp_address_length = 64;
6510           address_set = 1;
6511           is_ipv6 = 0;
6512         }
6513       else if (unformat (i, "%U %U",
6514                          unformat_ip6_address, &v6_src_address,
6515                          unformat_ip6_address, &v6_grp_address))
6516         {
6517           grp_address_length = 256;
6518           address_set = 1;
6519           is_ipv6 = 1;
6520         }
6521       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
6522         {
6523           memset (&v4_src_address, 0, sizeof (v4_src_address));
6524           grp_address_length = 32;
6525           address_set = 1;
6526           is_ipv6 = 0;
6527         }
6528       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
6529         {
6530           memset (&v6_src_address, 0, sizeof (v6_src_address));
6531           grp_address_length = 128;
6532           address_set = 1;
6533           is_ipv6 = 1;
6534         }
6535       else if (unformat (i, "/%d", &grp_address_length))
6536         ;
6537       else if (unformat (i, "local"))
6538         {
6539           is_local = 1;
6540         }
6541       else if (unformat (i, "del"))
6542         is_add = 0;
6543       else if (unformat (i, "add"))
6544         is_add = 1;
6545       else if (unformat (i, "vrf %d", &vrf_id))
6546         ;
6547       else if (unformat (i, "create-vrf"))
6548         create_vrf_if_needed = 1;
6549       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
6550         ;
6551       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6552         ;
6553       else
6554         {
6555           clib_warning ("parse error '%U'", format_unformat_error, i);
6556           return -99;
6557         }
6558     }
6559
6560   if (address_set == 0)
6561     {
6562       errmsg ("missing addresses\n");
6563       return -99;
6564     }
6565
6566   /* Construct the API message */
6567   M (IP_MROUTE_ADD_DEL, mp);
6568
6569   mp->next_hop_sw_if_index = ntohl (sw_if_index);
6570   mp->table_id = ntohl (vrf_id);
6571   mp->create_vrf_if_needed = create_vrf_if_needed;
6572
6573   mp->is_add = is_add;
6574   mp->is_ipv6 = is_ipv6;
6575   mp->is_local = is_local;
6576   mp->itf_flags = ntohl (iflags);
6577   mp->entry_flags = ntohl (eflags);
6578   mp->grp_address_length = grp_address_length;
6579   mp->grp_address_length = ntohs (mp->grp_address_length);
6580
6581   if (is_ipv6)
6582     {
6583       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
6584       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
6585     }
6586   else
6587     {
6588       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
6589       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
6590
6591     }
6592
6593   /* send it... */
6594   S (mp);
6595   /* Wait for a reply... */
6596   W (ret);
6597   return ret;
6598 }
6599
6600 static int
6601 api_mpls_route_add_del (vat_main_t * vam)
6602 {
6603   unformat_input_t *i = vam->input;
6604   vl_api_mpls_route_add_del_t *mp;
6605   u32 sw_if_index = ~0, table_id = 0;
6606   u8 create_table_if_needed = 0;
6607   u8 is_add = 1;
6608   u32 next_hop_weight = 1;
6609   u8 is_multipath = 0;
6610   u32 next_hop_table_id = 0;
6611   u8 next_hop_set = 0;
6612   ip4_address_t v4_next_hop_address = {
6613     .as_u32 = 0,
6614   };
6615   ip6_address_t v6_next_hop_address = { {0} };
6616   int count = 1;
6617   int j;
6618   f64 before = 0;
6619   u32 classify_table_index = ~0;
6620   u8 is_classify = 0;
6621   u8 resolve_host = 0, resolve_attached = 0;
6622   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6623   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6624   mpls_label_t *next_hop_out_label_stack = NULL;
6625   mpls_label_t local_label = MPLS_LABEL_INVALID;
6626   u8 is_eos = 0;
6627   u8 next_hop_proto_is_ip4 = 1;
6628
6629   /* Parse args required to build the message */
6630   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6631     {
6632       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6633         ;
6634       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6635         ;
6636       else if (unformat (i, "%d", &local_label))
6637         ;
6638       else if (unformat (i, "eos"))
6639         is_eos = 1;
6640       else if (unformat (i, "non-eos"))
6641         is_eos = 0;
6642       else if (unformat (i, "via %U", unformat_ip4_address,
6643                          &v4_next_hop_address))
6644         {
6645           next_hop_set = 1;
6646           next_hop_proto_is_ip4 = 1;
6647         }
6648       else if (unformat (i, "via %U", unformat_ip6_address,
6649                          &v6_next_hop_address))
6650         {
6651           next_hop_set = 1;
6652           next_hop_proto_is_ip4 = 0;
6653         }
6654       else if (unformat (i, "weight %d", &next_hop_weight))
6655         ;
6656       else if (unformat (i, "create-table"))
6657         create_table_if_needed = 1;
6658       else if (unformat (i, "classify %d", &classify_table_index))
6659         {
6660           is_classify = 1;
6661         }
6662       else if (unformat (i, "del"))
6663         is_add = 0;
6664       else if (unformat (i, "add"))
6665         is_add = 1;
6666       else if (unformat (i, "resolve-via-host"))
6667         resolve_host = 1;
6668       else if (unformat (i, "resolve-via-attached"))
6669         resolve_attached = 1;
6670       else if (unformat (i, "multipath"))
6671         is_multipath = 1;
6672       else if (unformat (i, "count %d", &count))
6673         ;
6674       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6675         {
6676           next_hop_set = 1;
6677           next_hop_proto_is_ip4 = 1;
6678         }
6679       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6680         {
6681           next_hop_set = 1;
6682           next_hop_proto_is_ip4 = 0;
6683         }
6684       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6685         ;
6686       else if (unformat (i, "via-label %d", &next_hop_via_label))
6687         ;
6688       else if (unformat (i, "out-label %d", &next_hop_out_label))
6689         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6690       else
6691         {
6692           clib_warning ("parse error '%U'", format_unformat_error, i);
6693           return -99;
6694         }
6695     }
6696
6697   if (!next_hop_set && !is_classify)
6698     {
6699       errmsg ("next hop / classify not set");
6700       return -99;
6701     }
6702
6703   if (MPLS_LABEL_INVALID == local_label)
6704     {
6705       errmsg ("missing label");
6706       return -99;
6707     }
6708
6709   if (count > 1)
6710     {
6711       /* Turn on async mode */
6712       vam->async_mode = 1;
6713       vam->async_errors = 0;
6714       before = vat_time_now (vam);
6715     }
6716
6717   for (j = 0; j < count; j++)
6718     {
6719       /* Construct the API message */
6720       M2 (MPLS_ROUTE_ADD_DEL, mp,
6721           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6722
6723       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6724       mp->mr_table_id = ntohl (table_id);
6725       mp->mr_create_table_if_needed = create_table_if_needed;
6726
6727       mp->mr_is_add = is_add;
6728       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6729       mp->mr_is_classify = is_classify;
6730       mp->mr_is_multipath = is_multipath;
6731       mp->mr_is_resolve_host = resolve_host;
6732       mp->mr_is_resolve_attached = resolve_attached;
6733       mp->mr_next_hop_weight = next_hop_weight;
6734       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6735       mp->mr_classify_table_index = ntohl (classify_table_index);
6736       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
6737       mp->mr_label = ntohl (local_label);
6738       mp->mr_eos = is_eos;
6739
6740       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6741       if (0 != mp->mr_next_hop_n_out_labels)
6742         {
6743           memcpy (mp->mr_next_hop_out_label_stack,
6744                   next_hop_out_label_stack,
6745                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6746           vec_free (next_hop_out_label_stack);
6747         }
6748
6749       if (next_hop_set)
6750         {
6751           if (next_hop_proto_is_ip4)
6752             {
6753               clib_memcpy (mp->mr_next_hop,
6754                            &v4_next_hop_address,
6755                            sizeof (v4_next_hop_address));
6756             }
6757           else
6758             {
6759               clib_memcpy (mp->mr_next_hop,
6760                            &v6_next_hop_address,
6761                            sizeof (v6_next_hop_address));
6762             }
6763         }
6764       local_label++;
6765
6766       /* send it... */
6767       S (mp);
6768       /* If we receive SIGTERM, stop now... */
6769       if (vam->do_exit)
6770         break;
6771     }
6772
6773   /* When testing multiple add/del ops, use a control-ping to sync */
6774   if (count > 1)
6775     {
6776       vl_api_control_ping_t *mp_ping;
6777       f64 after;
6778       f64 timeout;
6779
6780       /* Shut off async mode */
6781       vam->async_mode = 0;
6782
6783       M (CONTROL_PING, mp_ping);
6784       S (mp_ping);
6785
6786       timeout = vat_time_now (vam) + 1.0;
6787       while (vat_time_now (vam) < timeout)
6788         if (vam->result_ready == 1)
6789           goto out;
6790       vam->retval = -99;
6791
6792     out:
6793       if (vam->retval == -99)
6794         errmsg ("timeout");
6795
6796       if (vam->async_errors > 0)
6797         {
6798           errmsg ("%d asynchronous errors", vam->async_errors);
6799           vam->retval = -98;
6800         }
6801       vam->async_errors = 0;
6802       after = vat_time_now (vam);
6803
6804       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6805       if (j > 0)
6806         count = j;
6807
6808       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6809              count, after - before, count / (after - before));
6810     }
6811   else
6812     {
6813       int ret;
6814
6815       /* Wait for a reply... */
6816       W (ret);
6817       return ret;
6818     }
6819
6820   /* Return the good/bad news */
6821   return (vam->retval);
6822 }
6823
6824 static int
6825 api_mpls_ip_bind_unbind (vat_main_t * vam)
6826 {
6827   unformat_input_t *i = vam->input;
6828   vl_api_mpls_ip_bind_unbind_t *mp;
6829   u32 ip_table_id = 0;
6830   u8 create_table_if_needed = 0;
6831   u8 is_bind = 1;
6832   u8 is_ip4 = 1;
6833   ip4_address_t v4_address;
6834   ip6_address_t v6_address;
6835   u32 address_length;
6836   u8 address_set = 0;
6837   mpls_label_t local_label = MPLS_LABEL_INVALID;
6838   int ret;
6839
6840   /* Parse args required to build the message */
6841   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6842     {
6843       if (unformat (i, "%U/%d", unformat_ip4_address,
6844                     &v4_address, &address_length))
6845         {
6846           is_ip4 = 1;
6847           address_set = 1;
6848         }
6849       else if (unformat (i, "%U/%d", unformat_ip6_address,
6850                          &v6_address, &address_length))
6851         {
6852           is_ip4 = 0;
6853           address_set = 1;
6854         }
6855       else if (unformat (i, "%d", &local_label))
6856         ;
6857       else if (unformat (i, "create-table"))
6858         create_table_if_needed = 1;
6859       else if (unformat (i, "table-id %d", &ip_table_id))
6860         ;
6861       else if (unformat (i, "unbind"))
6862         is_bind = 0;
6863       else if (unformat (i, "bind"))
6864         is_bind = 1;
6865       else
6866         {
6867           clib_warning ("parse error '%U'", format_unformat_error, i);
6868           return -99;
6869         }
6870     }
6871
6872   if (!address_set)
6873     {
6874       errmsg ("IP addres not set");
6875       return -99;
6876     }
6877
6878   if (MPLS_LABEL_INVALID == local_label)
6879     {
6880       errmsg ("missing label");
6881       return -99;
6882     }
6883
6884   /* Construct the API message */
6885   M (MPLS_IP_BIND_UNBIND, mp);
6886
6887   mp->mb_create_table_if_needed = create_table_if_needed;
6888   mp->mb_is_bind = is_bind;
6889   mp->mb_is_ip4 = is_ip4;
6890   mp->mb_ip_table_id = ntohl (ip_table_id);
6891   mp->mb_mpls_table_id = 0;
6892   mp->mb_label = ntohl (local_label);
6893   mp->mb_address_length = address_length;
6894
6895   if (is_ip4)
6896     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
6897   else
6898     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
6899
6900   /* send it... */
6901   S (mp);
6902
6903   /* Wait for a reply... */
6904   W (ret);
6905   return ret;
6906 }
6907
6908 static int
6909 api_proxy_arp_add_del (vat_main_t * vam)
6910 {
6911   unformat_input_t *i = vam->input;
6912   vl_api_proxy_arp_add_del_t *mp;
6913   u32 vrf_id = 0;
6914   u8 is_add = 1;
6915   ip4_address_t lo, hi;
6916   u8 range_set = 0;
6917   int ret;
6918
6919   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6920     {
6921       if (unformat (i, "vrf %d", &vrf_id))
6922         ;
6923       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
6924                          unformat_ip4_address, &hi))
6925         range_set = 1;
6926       else if (unformat (i, "del"))
6927         is_add = 0;
6928       else
6929         {
6930           clib_warning ("parse error '%U'", format_unformat_error, i);
6931           return -99;
6932         }
6933     }
6934
6935   if (range_set == 0)
6936     {
6937       errmsg ("address range not set");
6938       return -99;
6939     }
6940
6941   M (PROXY_ARP_ADD_DEL, mp);
6942
6943   mp->vrf_id = ntohl (vrf_id);
6944   mp->is_add = is_add;
6945   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
6946   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
6947
6948   S (mp);
6949   W (ret);
6950   return ret;
6951 }
6952
6953 static int
6954 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
6955 {
6956   unformat_input_t *i = vam->input;
6957   vl_api_proxy_arp_intfc_enable_disable_t *mp;
6958   u32 sw_if_index;
6959   u8 enable = 1;
6960   u8 sw_if_index_set = 0;
6961   int ret;
6962
6963   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6964     {
6965       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6966         sw_if_index_set = 1;
6967       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6968         sw_if_index_set = 1;
6969       else if (unformat (i, "enable"))
6970         enable = 1;
6971       else if (unformat (i, "disable"))
6972         enable = 0;
6973       else
6974         {
6975           clib_warning ("parse error '%U'", format_unformat_error, i);
6976           return -99;
6977         }
6978     }
6979
6980   if (sw_if_index_set == 0)
6981     {
6982       errmsg ("missing interface name or sw_if_index");
6983       return -99;
6984     }
6985
6986   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
6987
6988   mp->sw_if_index = ntohl (sw_if_index);
6989   mp->enable_disable = enable;
6990
6991   S (mp);
6992   W (ret);
6993   return ret;
6994 }
6995
6996 static int
6997 api_mpls_tunnel_add_del (vat_main_t * vam)
6998 {
6999   unformat_input_t *i = vam->input;
7000   vl_api_mpls_tunnel_add_del_t *mp;
7001
7002   u8 is_add = 1;
7003   u8 l2_only = 0;
7004   u32 sw_if_index = ~0;
7005   u32 next_hop_sw_if_index = ~0;
7006   u32 next_hop_proto_is_ip4 = 1;
7007
7008   u32 next_hop_table_id = 0;
7009   ip4_address_t v4_next_hop_address = {
7010     .as_u32 = 0,
7011   };
7012   ip6_address_t v6_next_hop_address = { {0} };
7013   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
7014   int ret;
7015
7016   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7017     {
7018       if (unformat (i, "add"))
7019         is_add = 1;
7020       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7021         is_add = 0;
7022       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7023         ;
7024       else if (unformat (i, "via %U",
7025                          unformat_ip4_address, &v4_next_hop_address))
7026         {
7027           next_hop_proto_is_ip4 = 1;
7028         }
7029       else if (unformat (i, "via %U",
7030                          unformat_ip6_address, &v6_next_hop_address))
7031         {
7032           next_hop_proto_is_ip4 = 0;
7033         }
7034       else if (unformat (i, "l2-only"))
7035         l2_only = 1;
7036       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7037         ;
7038       else if (unformat (i, "out-label %d", &next_hop_out_label))
7039         vec_add1 (labels, ntohl (next_hop_out_label));
7040       else
7041         {
7042           clib_warning ("parse error '%U'", format_unformat_error, i);
7043           return -99;
7044         }
7045     }
7046
7047   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
7048
7049   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
7050   mp->mt_sw_if_index = ntohl (sw_if_index);
7051   mp->mt_is_add = is_add;
7052   mp->mt_l2_only = l2_only;
7053   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
7054   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7055
7056   mp->mt_next_hop_n_out_labels = vec_len (labels);
7057
7058   if (0 != mp->mt_next_hop_n_out_labels)
7059     {
7060       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7061                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7062       vec_free (labels);
7063     }
7064
7065   if (next_hop_proto_is_ip4)
7066     {
7067       clib_memcpy (mp->mt_next_hop,
7068                    &v4_next_hop_address, sizeof (v4_next_hop_address));
7069     }
7070   else
7071     {
7072       clib_memcpy (mp->mt_next_hop,
7073                    &v6_next_hop_address, sizeof (v6_next_hop_address));
7074     }
7075
7076   S (mp);
7077   W (ret);
7078   return ret;
7079 }
7080
7081 static int
7082 api_sw_interface_set_unnumbered (vat_main_t * vam)
7083 {
7084   unformat_input_t *i = vam->input;
7085   vl_api_sw_interface_set_unnumbered_t *mp;
7086   u32 sw_if_index;
7087   u32 unnum_sw_index = ~0;
7088   u8 is_add = 1;
7089   u8 sw_if_index_set = 0;
7090   int ret;
7091
7092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7093     {
7094       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7095         sw_if_index_set = 1;
7096       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7097         sw_if_index_set = 1;
7098       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7099         ;
7100       else if (unformat (i, "del"))
7101         is_add = 0;
7102       else
7103         {
7104           clib_warning ("parse error '%U'", format_unformat_error, i);
7105           return -99;
7106         }
7107     }
7108
7109   if (sw_if_index_set == 0)
7110     {
7111       errmsg ("missing interface name or sw_if_index");
7112       return -99;
7113     }
7114
7115   M (SW_INTERFACE_SET_UNNUMBERED, mp);
7116
7117   mp->sw_if_index = ntohl (sw_if_index);
7118   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7119   mp->is_add = is_add;
7120
7121   S (mp);
7122   W (ret);
7123   return ret;
7124 }
7125
7126 static int
7127 api_ip_neighbor_add_del (vat_main_t * vam)
7128 {
7129   unformat_input_t *i = vam->input;
7130   vl_api_ip_neighbor_add_del_t *mp;
7131   u32 sw_if_index;
7132   u8 sw_if_index_set = 0;
7133   u8 is_add = 1;
7134   u8 is_static = 0;
7135   u8 mac_address[6];
7136   u8 mac_set = 0;
7137   u8 v4_address_set = 0;
7138   u8 v6_address_set = 0;
7139   ip4_address_t v4address;
7140   ip6_address_t v6address;
7141   int ret;
7142
7143   memset (mac_address, 0, sizeof (mac_address));
7144
7145   /* Parse args required to build the message */
7146   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7147     {
7148       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7149         {
7150           mac_set = 1;
7151         }
7152       else if (unformat (i, "del"))
7153         is_add = 0;
7154       else
7155         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7156         sw_if_index_set = 1;
7157       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7158         sw_if_index_set = 1;
7159       else if (unformat (i, "is_static"))
7160         is_static = 1;
7161       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
7162         v4_address_set = 1;
7163       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
7164         v6_address_set = 1;
7165       else
7166         {
7167           clib_warning ("parse error '%U'", format_unformat_error, i);
7168           return -99;
7169         }
7170     }
7171
7172   if (sw_if_index_set == 0)
7173     {
7174       errmsg ("missing interface name or sw_if_index");
7175       return -99;
7176     }
7177   if (v4_address_set && v6_address_set)
7178     {
7179       errmsg ("both v4 and v6 addresses set");
7180       return -99;
7181     }
7182   if (!v4_address_set && !v6_address_set)
7183     {
7184       errmsg ("no address set");
7185       return -99;
7186     }
7187
7188   /* Construct the API message */
7189   M (IP_NEIGHBOR_ADD_DEL, mp);
7190
7191   mp->sw_if_index = ntohl (sw_if_index);
7192   mp->is_add = is_add;
7193   mp->is_static = is_static;
7194   if (mac_set)
7195     clib_memcpy (mp->mac_address, mac_address, 6);
7196   if (v6_address_set)
7197     {
7198       mp->is_ipv6 = 1;
7199       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
7200     }
7201   else
7202     {
7203       /* mp->is_ipv6 = 0; via memset in M macro above */
7204       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
7205     }
7206
7207   /* send it... */
7208   S (mp);
7209
7210   /* Wait for a reply, return good/bad news  */
7211   W (ret);
7212   return ret;
7213 }
7214
7215 static int
7216 api_reset_vrf (vat_main_t * vam)
7217 {
7218   unformat_input_t *i = vam->input;
7219   vl_api_reset_vrf_t *mp;
7220   u32 vrf_id = 0;
7221   u8 is_ipv6 = 0;
7222   u8 vrf_id_set = 0;
7223   int ret;
7224
7225   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7226     {
7227       if (unformat (i, "vrf %d", &vrf_id))
7228         vrf_id_set = 1;
7229       else if (unformat (i, "ipv6"))
7230         is_ipv6 = 1;
7231       else
7232         {
7233           clib_warning ("parse error '%U'", format_unformat_error, i);
7234           return -99;
7235         }
7236     }
7237
7238   if (vrf_id_set == 0)
7239     {
7240       errmsg ("missing vrf id");
7241       return -99;
7242     }
7243
7244   M (RESET_VRF, mp);
7245
7246   mp->vrf_id = ntohl (vrf_id);
7247   mp->is_ipv6 = is_ipv6;
7248
7249   S (mp);
7250   W (ret);
7251   return ret;
7252 }
7253
7254 static int
7255 api_create_vlan_subif (vat_main_t * vam)
7256 {
7257   unformat_input_t *i = vam->input;
7258   vl_api_create_vlan_subif_t *mp;
7259   u32 sw_if_index;
7260   u8 sw_if_index_set = 0;
7261   u32 vlan_id;
7262   u8 vlan_id_set = 0;
7263   int ret;
7264
7265   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7266     {
7267       if (unformat (i, "sw_if_index %d", &sw_if_index))
7268         sw_if_index_set = 1;
7269       else
7270         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7271         sw_if_index_set = 1;
7272       else if (unformat (i, "vlan %d", &vlan_id))
7273         vlan_id_set = 1;
7274       else
7275         {
7276           clib_warning ("parse error '%U'", format_unformat_error, i);
7277           return -99;
7278         }
7279     }
7280
7281   if (sw_if_index_set == 0)
7282     {
7283       errmsg ("missing interface name or sw_if_index");
7284       return -99;
7285     }
7286
7287   if (vlan_id_set == 0)
7288     {
7289       errmsg ("missing vlan_id");
7290       return -99;
7291     }
7292   M (CREATE_VLAN_SUBIF, mp);
7293
7294   mp->sw_if_index = ntohl (sw_if_index);
7295   mp->vlan_id = ntohl (vlan_id);
7296
7297   S (mp);
7298   W (ret);
7299   return ret;
7300 }
7301
7302 #define foreach_create_subif_bit                \
7303 _(no_tags)                                      \
7304 _(one_tag)                                      \
7305 _(two_tags)                                     \
7306 _(dot1ad)                                       \
7307 _(exact_match)                                  \
7308 _(default_sub)                                  \
7309 _(outer_vlan_id_any)                            \
7310 _(inner_vlan_id_any)
7311
7312 static int
7313 api_create_subif (vat_main_t * vam)
7314 {
7315   unformat_input_t *i = vam->input;
7316   vl_api_create_subif_t *mp;
7317   u32 sw_if_index;
7318   u8 sw_if_index_set = 0;
7319   u32 sub_id;
7320   u8 sub_id_set = 0;
7321   u32 no_tags = 0;
7322   u32 one_tag = 0;
7323   u32 two_tags = 0;
7324   u32 dot1ad = 0;
7325   u32 exact_match = 0;
7326   u32 default_sub = 0;
7327   u32 outer_vlan_id_any = 0;
7328   u32 inner_vlan_id_any = 0;
7329   u32 tmp;
7330   u16 outer_vlan_id = 0;
7331   u16 inner_vlan_id = 0;
7332   int ret;
7333
7334   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7335     {
7336       if (unformat (i, "sw_if_index %d", &sw_if_index))
7337         sw_if_index_set = 1;
7338       else
7339         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7340         sw_if_index_set = 1;
7341       else if (unformat (i, "sub_id %d", &sub_id))
7342         sub_id_set = 1;
7343       else if (unformat (i, "outer_vlan_id %d", &tmp))
7344         outer_vlan_id = tmp;
7345       else if (unformat (i, "inner_vlan_id %d", &tmp))
7346         inner_vlan_id = tmp;
7347
7348 #define _(a) else if (unformat (i, #a)) a = 1 ;
7349       foreach_create_subif_bit
7350 #undef _
7351         else
7352         {
7353           clib_warning ("parse error '%U'", format_unformat_error, i);
7354           return -99;
7355         }
7356     }
7357
7358   if (sw_if_index_set == 0)
7359     {
7360       errmsg ("missing interface name or sw_if_index");
7361       return -99;
7362     }
7363
7364   if (sub_id_set == 0)
7365     {
7366       errmsg ("missing sub_id");
7367       return -99;
7368     }
7369   M (CREATE_SUBIF, mp);
7370
7371   mp->sw_if_index = ntohl (sw_if_index);
7372   mp->sub_id = ntohl (sub_id);
7373
7374 #define _(a) mp->a = a;
7375   foreach_create_subif_bit;
7376 #undef _
7377
7378   mp->outer_vlan_id = ntohs (outer_vlan_id);
7379   mp->inner_vlan_id = ntohs (inner_vlan_id);
7380
7381   S (mp);
7382   W (ret);
7383   return ret;
7384 }
7385
7386 static int
7387 api_oam_add_del (vat_main_t * vam)
7388 {
7389   unformat_input_t *i = vam->input;
7390   vl_api_oam_add_del_t *mp;
7391   u32 vrf_id = 0;
7392   u8 is_add = 1;
7393   ip4_address_t src, dst;
7394   u8 src_set = 0;
7395   u8 dst_set = 0;
7396   int ret;
7397
7398   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7399     {
7400       if (unformat (i, "vrf %d", &vrf_id))
7401         ;
7402       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7403         src_set = 1;
7404       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7405         dst_set = 1;
7406       else if (unformat (i, "del"))
7407         is_add = 0;
7408       else
7409         {
7410           clib_warning ("parse error '%U'", format_unformat_error, i);
7411           return -99;
7412         }
7413     }
7414
7415   if (src_set == 0)
7416     {
7417       errmsg ("missing src addr");
7418       return -99;
7419     }
7420
7421   if (dst_set == 0)
7422     {
7423       errmsg ("missing dst addr");
7424       return -99;
7425     }
7426
7427   M (OAM_ADD_DEL, mp);
7428
7429   mp->vrf_id = ntohl (vrf_id);
7430   mp->is_add = is_add;
7431   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7432   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7433
7434   S (mp);
7435   W (ret);
7436   return ret;
7437 }
7438
7439 static int
7440 api_reset_fib (vat_main_t * vam)
7441 {
7442   unformat_input_t *i = vam->input;
7443   vl_api_reset_fib_t *mp;
7444   u32 vrf_id = 0;
7445   u8 is_ipv6 = 0;
7446   u8 vrf_id_set = 0;
7447
7448   int ret;
7449   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7450     {
7451       if (unformat (i, "vrf %d", &vrf_id))
7452         vrf_id_set = 1;
7453       else if (unformat (i, "ipv6"))
7454         is_ipv6 = 1;
7455       else
7456         {
7457           clib_warning ("parse error '%U'", format_unformat_error, i);
7458           return -99;
7459         }
7460     }
7461
7462   if (vrf_id_set == 0)
7463     {
7464       errmsg ("missing vrf id");
7465       return -99;
7466     }
7467
7468   M (RESET_FIB, mp);
7469
7470   mp->vrf_id = ntohl (vrf_id);
7471   mp->is_ipv6 = is_ipv6;
7472
7473   S (mp);
7474   W (ret);
7475   return ret;
7476 }
7477
7478 static int
7479 api_dhcp_proxy_config (vat_main_t * vam)
7480 {
7481   unformat_input_t *i = vam->input;
7482   vl_api_dhcp_proxy_config_t *mp;
7483   u32 rx_vrf_id = 0;
7484   u32 server_vrf_id = 0;
7485   u8 is_add = 1;
7486   u8 v4_address_set = 0;
7487   u8 v6_address_set = 0;
7488   ip4_address_t v4address;
7489   ip6_address_t v6address;
7490   u8 v4_src_address_set = 0;
7491   u8 v6_src_address_set = 0;
7492   ip4_address_t v4srcaddress;
7493   ip6_address_t v6srcaddress;
7494   int ret;
7495
7496   /* Parse args required to build the message */
7497   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7498     {
7499       if (unformat (i, "del"))
7500         is_add = 0;
7501       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7502         ;
7503       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7504         ;
7505       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7506         v4_address_set = 1;
7507       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7508         v6_address_set = 1;
7509       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7510         v4_src_address_set = 1;
7511       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7512         v6_src_address_set = 1;
7513       else
7514         break;
7515     }
7516
7517   if (v4_address_set && v6_address_set)
7518     {
7519       errmsg ("both v4 and v6 server addresses set");
7520       return -99;
7521     }
7522   if (!v4_address_set && !v6_address_set)
7523     {
7524       errmsg ("no server addresses set");
7525       return -99;
7526     }
7527
7528   if (v4_src_address_set && v6_src_address_set)
7529     {
7530       errmsg ("both v4 and v6  src addresses set");
7531       return -99;
7532     }
7533   if (!v4_src_address_set && !v6_src_address_set)
7534     {
7535       errmsg ("no src addresses set");
7536       return -99;
7537     }
7538
7539   if (!(v4_src_address_set && v4_address_set) &&
7540       !(v6_src_address_set && v6_address_set))
7541     {
7542       errmsg ("no matching server and src addresses set");
7543       return -99;
7544     }
7545
7546   /* Construct the API message */
7547   M (DHCP_PROXY_CONFIG, mp);
7548
7549   mp->is_add = is_add;
7550   mp->rx_vrf_id = ntohl (rx_vrf_id);
7551   mp->server_vrf_id = ntohl (server_vrf_id);
7552   if (v6_address_set)
7553     {
7554       mp->is_ipv6 = 1;
7555       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7556       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7557     }
7558   else
7559     {
7560       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7561       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7562     }
7563
7564   /* send it... */
7565   S (mp);
7566
7567   /* Wait for a reply, return good/bad news  */
7568   W (ret);
7569   return ret;
7570 }
7571
7572 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
7573 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
7574
7575 static void
7576 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
7577 {
7578   vat_main_t *vam = &vat_main;
7579   u32 i, count = mp->count;
7580   vl_api_dhcp_server_t *s;
7581
7582   if (mp->is_ipv6)
7583     print (vam->ofp,
7584            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7585            ntohl (mp->rx_vrf_id),
7586            format_ip6_address, mp->dhcp_src_address,
7587            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7588   else
7589     print (vam->ofp,
7590            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7591            ntohl (mp->rx_vrf_id),
7592            format_ip4_address, mp->dhcp_src_address,
7593            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7594
7595   for (i = 0; i < count; i++)
7596     {
7597       s = &mp->servers[i];
7598
7599       if (mp->is_ipv6)
7600         print (vam->ofp,
7601                " Server Table-ID %d, Server Address %U",
7602                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
7603       else
7604         print (vam->ofp,
7605                " Server Table-ID %d, Server Address %U",
7606                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
7607     }
7608 }
7609
7610 static void vl_api_dhcp_proxy_details_t_handler_json
7611   (vl_api_dhcp_proxy_details_t * mp)
7612 {
7613   vat_main_t *vam = &vat_main;
7614   vat_json_node_t *node = NULL;
7615   u32 i, count = mp->count;
7616   struct in_addr ip4;
7617   struct in6_addr ip6;
7618   vl_api_dhcp_server_t *s;
7619
7620   if (VAT_JSON_ARRAY != vam->json_tree.type)
7621     {
7622       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7623       vat_json_init_array (&vam->json_tree);
7624     }
7625   node = vat_json_array_add (&vam->json_tree);
7626
7627   vat_json_init_object (node);
7628   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
7629   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
7630   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
7631
7632   if (mp->is_ipv6)
7633     {
7634       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
7635       vat_json_object_add_ip6 (node, "src_address", ip6);
7636     }
7637   else
7638     {
7639       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
7640       vat_json_object_add_ip4 (node, "src_address", ip4);
7641     }
7642
7643   for (i = 0; i < count; i++)
7644     {
7645       s = &mp->servers[i];
7646
7647       vat_json_object_add_uint (node, "server-table-id",
7648                                 ntohl (s->server_vrf_id));
7649
7650       if (mp->is_ipv6)
7651         {
7652           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
7653           vat_json_object_add_ip4 (node, "src_address", ip4);
7654         }
7655       else
7656         {
7657           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
7658           vat_json_object_add_ip6 (node, "server_address", ip6);
7659         }
7660     }
7661 }
7662
7663 static int
7664 api_dhcp_proxy_dump (vat_main_t * vam)
7665 {
7666   unformat_input_t *i = vam->input;
7667   vl_api_control_ping_t *mp_ping;
7668   vl_api_dhcp_proxy_dump_t *mp;
7669   u8 is_ipv6 = 0;
7670   int ret;
7671
7672   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7673     {
7674       if (unformat (i, "ipv6"))
7675         is_ipv6 = 1;
7676       else
7677         {
7678           clib_warning ("parse error '%U'", format_unformat_error, i);
7679           return -99;
7680         }
7681     }
7682
7683   M (DHCP_PROXY_DUMP, mp);
7684
7685   mp->is_ip6 = is_ipv6;
7686   S (mp);
7687
7688   /* Use a control ping for synchronization */
7689   M (CONTROL_PING, mp_ping);
7690   S (mp_ping);
7691
7692   W (ret);
7693   return ret;
7694 }
7695
7696 static int
7697 api_dhcp_proxy_set_vss (vat_main_t * vam)
7698 {
7699   unformat_input_t *i = vam->input;
7700   vl_api_dhcp_proxy_set_vss_t *mp;
7701   u8 is_ipv6 = 0;
7702   u8 is_add = 1;
7703   u32 tbl_id;
7704   u8 tbl_id_set = 0;
7705   u32 oui;
7706   u8 oui_set = 0;
7707   u32 fib_id;
7708   u8 fib_id_set = 0;
7709   int ret;
7710
7711   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7712     {
7713       if (unformat (i, "tbl_id %d", &tbl_id))
7714         tbl_id_set = 1;
7715       if (unformat (i, "fib_id %d", &fib_id))
7716         fib_id_set = 1;
7717       if (unformat (i, "oui %d", &oui))
7718         oui_set = 1;
7719       else if (unformat (i, "ipv6"))
7720         is_ipv6 = 1;
7721       else if (unformat (i, "del"))
7722         is_add = 0;
7723       else
7724         {
7725           clib_warning ("parse error '%U'", format_unformat_error, i);
7726           return -99;
7727         }
7728     }
7729
7730   if (tbl_id_set == 0)
7731     {
7732       errmsg ("missing tbl id");
7733       return -99;
7734     }
7735
7736   if (fib_id_set == 0)
7737     {
7738       errmsg ("missing fib id");
7739       return -99;
7740     }
7741   if (oui_set == 0)
7742     {
7743       errmsg ("missing oui");
7744       return -99;
7745     }
7746
7747   M (DHCP_PROXY_SET_VSS, mp);
7748   mp->tbl_id = ntohl (tbl_id);
7749   mp->fib_id = ntohl (fib_id);
7750   mp->oui = ntohl (oui);
7751   mp->is_ipv6 = is_ipv6;
7752   mp->is_add = is_add;
7753
7754   S (mp);
7755   W (ret);
7756   return ret;
7757 }
7758
7759 static int
7760 api_dhcp_client_config (vat_main_t * vam)
7761 {
7762   unformat_input_t *i = vam->input;
7763   vl_api_dhcp_client_config_t *mp;
7764   u32 sw_if_index;
7765   u8 sw_if_index_set = 0;
7766   u8 is_add = 1;
7767   u8 *hostname = 0;
7768   u8 disable_event = 0;
7769   int ret;
7770
7771   /* Parse args required to build the message */
7772   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7773     {
7774       if (unformat (i, "del"))
7775         is_add = 0;
7776       else
7777         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7778         sw_if_index_set = 1;
7779       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7780         sw_if_index_set = 1;
7781       else if (unformat (i, "hostname %s", &hostname))
7782         ;
7783       else if (unformat (i, "disable_event"))
7784         disable_event = 1;
7785       else
7786         break;
7787     }
7788
7789   if (sw_if_index_set == 0)
7790     {
7791       errmsg ("missing interface name or sw_if_index");
7792       return -99;
7793     }
7794
7795   if (vec_len (hostname) > 63)
7796     {
7797       errmsg ("hostname too long");
7798     }
7799   vec_add1 (hostname, 0);
7800
7801   /* Construct the API message */
7802   M (DHCP_CLIENT_CONFIG, mp);
7803
7804   mp->sw_if_index = ntohl (sw_if_index);
7805   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7806   vec_free (hostname);
7807   mp->is_add = is_add;
7808   mp->want_dhcp_event = disable_event ? 0 : 1;
7809   mp->pid = getpid ();
7810
7811   /* send it... */
7812   S (mp);
7813
7814   /* Wait for a reply, return good/bad news  */
7815   W (ret);
7816   return ret;
7817 }
7818
7819 static int
7820 api_set_ip_flow_hash (vat_main_t * vam)
7821 {
7822   unformat_input_t *i = vam->input;
7823   vl_api_set_ip_flow_hash_t *mp;
7824   u32 vrf_id = 0;
7825   u8 is_ipv6 = 0;
7826   u8 vrf_id_set = 0;
7827   u8 src = 0;
7828   u8 dst = 0;
7829   u8 sport = 0;
7830   u8 dport = 0;
7831   u8 proto = 0;
7832   u8 reverse = 0;
7833   int ret;
7834
7835   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7836     {
7837       if (unformat (i, "vrf %d", &vrf_id))
7838         vrf_id_set = 1;
7839       else if (unformat (i, "ipv6"))
7840         is_ipv6 = 1;
7841       else if (unformat (i, "src"))
7842         src = 1;
7843       else if (unformat (i, "dst"))
7844         dst = 1;
7845       else if (unformat (i, "sport"))
7846         sport = 1;
7847       else if (unformat (i, "dport"))
7848         dport = 1;
7849       else if (unformat (i, "proto"))
7850         proto = 1;
7851       else if (unformat (i, "reverse"))
7852         reverse = 1;
7853
7854       else
7855         {
7856           clib_warning ("parse error '%U'", format_unformat_error, i);
7857           return -99;
7858         }
7859     }
7860
7861   if (vrf_id_set == 0)
7862     {
7863       errmsg ("missing vrf id");
7864       return -99;
7865     }
7866
7867   M (SET_IP_FLOW_HASH, mp);
7868   mp->src = src;
7869   mp->dst = dst;
7870   mp->sport = sport;
7871   mp->dport = dport;
7872   mp->proto = proto;
7873   mp->reverse = reverse;
7874   mp->vrf_id = ntohl (vrf_id);
7875   mp->is_ipv6 = is_ipv6;
7876
7877   S (mp);
7878   W (ret);
7879   return ret;
7880 }
7881
7882 static int
7883 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7884 {
7885   unformat_input_t *i = vam->input;
7886   vl_api_sw_interface_ip6_enable_disable_t *mp;
7887   u32 sw_if_index;
7888   u8 sw_if_index_set = 0;
7889   u8 enable = 0;
7890   int ret;
7891
7892   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7893     {
7894       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7895         sw_if_index_set = 1;
7896       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7897         sw_if_index_set = 1;
7898       else if (unformat (i, "enable"))
7899         enable = 1;
7900       else if (unformat (i, "disable"))
7901         enable = 0;
7902       else
7903         {
7904           clib_warning ("parse error '%U'", format_unformat_error, i);
7905           return -99;
7906         }
7907     }
7908
7909   if (sw_if_index_set == 0)
7910     {
7911       errmsg ("missing interface name or sw_if_index");
7912       return -99;
7913     }
7914
7915   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
7916
7917   mp->sw_if_index = ntohl (sw_if_index);
7918   mp->enable = enable;
7919
7920   S (mp);
7921   W (ret);
7922   return ret;
7923 }
7924
7925 static int
7926 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7927 {
7928   unformat_input_t *i = vam->input;
7929   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7930   u32 sw_if_index;
7931   u8 sw_if_index_set = 0;
7932   u8 v6_address_set = 0;
7933   ip6_address_t v6address;
7934   int ret;
7935
7936   /* Parse args required to build the message */
7937   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7938     {
7939       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7940         sw_if_index_set = 1;
7941       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7942         sw_if_index_set = 1;
7943       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
7944         v6_address_set = 1;
7945       else
7946         break;
7947     }
7948
7949   if (sw_if_index_set == 0)
7950     {
7951       errmsg ("missing interface name or sw_if_index");
7952       return -99;
7953     }
7954   if (!v6_address_set)
7955     {
7956       errmsg ("no address set");
7957       return -99;
7958     }
7959
7960   /* Construct the API message */
7961   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
7962
7963   mp->sw_if_index = ntohl (sw_if_index);
7964   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7965
7966   /* send it... */
7967   S (mp);
7968
7969   /* Wait for a reply, return good/bad news  */
7970   W (ret);
7971   return ret;
7972 }
7973
7974 static int
7975 api_ip6nd_proxy_add_del (vat_main_t * vam)
7976 {
7977   unformat_input_t *i = vam->input;
7978   vl_api_ip6nd_proxy_add_del_t *mp;
7979   u32 sw_if_index = ~0;
7980   u8 v6_address_set = 0;
7981   ip6_address_t v6address;
7982   u8 is_del = 0;
7983   int ret;
7984
7985   /* Parse args required to build the message */
7986   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7987     {
7988       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7989         ;
7990       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7991         ;
7992       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
7993         v6_address_set = 1;
7994       if (unformat (i, "del"))
7995         is_del = 1;
7996       else
7997         {
7998           clib_warning ("parse error '%U'", format_unformat_error, i);
7999           return -99;
8000         }
8001     }
8002
8003   if (sw_if_index == ~0)
8004     {
8005       errmsg ("missing interface name or sw_if_index");
8006       return -99;
8007     }
8008   if (!v6_address_set)
8009     {
8010       errmsg ("no address set");
8011       return -99;
8012     }
8013
8014   /* Construct the API message */
8015   M (IP6ND_PROXY_ADD_DEL, mp);
8016
8017   mp->is_del = is_del;
8018   mp->sw_if_index = ntohl (sw_if_index);
8019   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8020
8021   /* send it... */
8022   S (mp);
8023
8024   /* Wait for a reply, return good/bad news  */
8025   W (ret);
8026   return ret;
8027 }
8028
8029 static int
8030 api_ip6nd_proxy_dump (vat_main_t * vam)
8031 {
8032   vl_api_ip6nd_proxy_dump_t *mp;
8033   vl_api_control_ping_t *mp_ping;
8034   int ret;
8035
8036   M (IP6ND_PROXY_DUMP, mp);
8037
8038   S (mp);
8039
8040   /* Use a control ping for synchronization */
8041   M (CONTROL_PING, mp_ping);
8042   S (mp_ping);
8043
8044   W (ret);
8045   return ret;
8046 }
8047
8048 static void vl_api_ip6nd_proxy_details_t_handler
8049   (vl_api_ip6nd_proxy_details_t * mp)
8050 {
8051   vat_main_t *vam = &vat_main;
8052
8053   print (vam->ofp, "host %U sw_if_index %d",
8054          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
8055 }
8056
8057 static void vl_api_ip6nd_proxy_details_t_handler_json
8058   (vl_api_ip6nd_proxy_details_t * mp)
8059 {
8060   vat_main_t *vam = &vat_main;
8061   struct in6_addr ip6;
8062   vat_json_node_t *node = NULL;
8063
8064   if (VAT_JSON_ARRAY != vam->json_tree.type)
8065     {
8066       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8067       vat_json_init_array (&vam->json_tree);
8068     }
8069   node = vat_json_array_add (&vam->json_tree);
8070
8071   vat_json_init_object (node);
8072   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
8073
8074   clib_memcpy (&ip6, mp->address, sizeof (ip6));
8075   vat_json_object_add_ip6 (node, "host", ip6);
8076 }
8077
8078 static int
8079 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
8080 {
8081   unformat_input_t *i = vam->input;
8082   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
8083   u32 sw_if_index;
8084   u8 sw_if_index_set = 0;
8085   u32 address_length = 0;
8086   u8 v6_address_set = 0;
8087   ip6_address_t v6address;
8088   u8 use_default = 0;
8089   u8 no_advertise = 0;
8090   u8 off_link = 0;
8091   u8 no_autoconfig = 0;
8092   u8 no_onlink = 0;
8093   u8 is_no = 0;
8094   u32 val_lifetime = 0;
8095   u32 pref_lifetime = 0;
8096   int ret;
8097
8098   /* Parse args required to build the message */
8099   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8100     {
8101       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8102         sw_if_index_set = 1;
8103       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8104         sw_if_index_set = 1;
8105       else if (unformat (i, "%U/%d",
8106                          unformat_ip6_address, &v6address, &address_length))
8107         v6_address_set = 1;
8108       else if (unformat (i, "val_life %d", &val_lifetime))
8109         ;
8110       else if (unformat (i, "pref_life %d", &pref_lifetime))
8111         ;
8112       else if (unformat (i, "def"))
8113         use_default = 1;
8114       else if (unformat (i, "noadv"))
8115         no_advertise = 1;
8116       else if (unformat (i, "offl"))
8117         off_link = 1;
8118       else if (unformat (i, "noauto"))
8119         no_autoconfig = 1;
8120       else if (unformat (i, "nolink"))
8121         no_onlink = 1;
8122       else if (unformat (i, "isno"))
8123         is_no = 1;
8124       else
8125         {
8126           clib_warning ("parse error '%U'", format_unformat_error, i);
8127           return -99;
8128         }
8129     }
8130
8131   if (sw_if_index_set == 0)
8132     {
8133       errmsg ("missing interface name or sw_if_index");
8134       return -99;
8135     }
8136   if (!v6_address_set)
8137     {
8138       errmsg ("no address set");
8139       return -99;
8140     }
8141
8142   /* Construct the API message */
8143   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
8144
8145   mp->sw_if_index = ntohl (sw_if_index);
8146   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8147   mp->address_length = address_length;
8148   mp->use_default = use_default;
8149   mp->no_advertise = no_advertise;
8150   mp->off_link = off_link;
8151   mp->no_autoconfig = no_autoconfig;
8152   mp->no_onlink = no_onlink;
8153   mp->is_no = is_no;
8154   mp->val_lifetime = ntohl (val_lifetime);
8155   mp->pref_lifetime = ntohl (pref_lifetime);
8156
8157   /* send it... */
8158   S (mp);
8159
8160   /* Wait for a reply, return good/bad news  */
8161   W (ret);
8162   return ret;
8163 }
8164
8165 static int
8166 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
8167 {
8168   unformat_input_t *i = vam->input;
8169   vl_api_sw_interface_ip6nd_ra_config_t *mp;
8170   u32 sw_if_index;
8171   u8 sw_if_index_set = 0;
8172   u8 suppress = 0;
8173   u8 managed = 0;
8174   u8 other = 0;
8175   u8 ll_option = 0;
8176   u8 send_unicast = 0;
8177   u8 cease = 0;
8178   u8 is_no = 0;
8179   u8 default_router = 0;
8180   u32 max_interval = 0;
8181   u32 min_interval = 0;
8182   u32 lifetime = 0;
8183   u32 initial_count = 0;
8184   u32 initial_interval = 0;
8185   int ret;
8186
8187
8188   /* Parse args required to build the message */
8189   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8190     {
8191       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8192         sw_if_index_set = 1;
8193       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8194         sw_if_index_set = 1;
8195       else if (unformat (i, "maxint %d", &max_interval))
8196         ;
8197       else if (unformat (i, "minint %d", &min_interval))
8198         ;
8199       else if (unformat (i, "life %d", &lifetime))
8200         ;
8201       else if (unformat (i, "count %d", &initial_count))
8202         ;
8203       else if (unformat (i, "interval %d", &initial_interval))
8204         ;
8205       else if (unformat (i, "suppress") || unformat (i, "surpress"))
8206         suppress = 1;
8207       else if (unformat (i, "managed"))
8208         managed = 1;
8209       else if (unformat (i, "other"))
8210         other = 1;
8211       else if (unformat (i, "ll"))
8212         ll_option = 1;
8213       else if (unformat (i, "send"))
8214         send_unicast = 1;
8215       else if (unformat (i, "cease"))
8216         cease = 1;
8217       else if (unformat (i, "isno"))
8218         is_no = 1;
8219       else if (unformat (i, "def"))
8220         default_router = 1;
8221       else
8222         {
8223           clib_warning ("parse error '%U'", format_unformat_error, i);
8224           return -99;
8225         }
8226     }
8227
8228   if (sw_if_index_set == 0)
8229     {
8230       errmsg ("missing interface name or sw_if_index");
8231       return -99;
8232     }
8233
8234   /* Construct the API message */
8235   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
8236
8237   mp->sw_if_index = ntohl (sw_if_index);
8238   mp->max_interval = ntohl (max_interval);
8239   mp->min_interval = ntohl (min_interval);
8240   mp->lifetime = ntohl (lifetime);
8241   mp->initial_count = ntohl (initial_count);
8242   mp->initial_interval = ntohl (initial_interval);
8243   mp->suppress = suppress;
8244   mp->managed = managed;
8245   mp->other = other;
8246   mp->ll_option = ll_option;
8247   mp->send_unicast = send_unicast;
8248   mp->cease = cease;
8249   mp->is_no = is_no;
8250   mp->default_router = default_router;
8251
8252   /* send it... */
8253   S (mp);
8254
8255   /* Wait for a reply, return good/bad news  */
8256   W (ret);
8257   return ret;
8258 }
8259
8260 static int
8261 api_set_arp_neighbor_limit (vat_main_t * vam)
8262 {
8263   unformat_input_t *i = vam->input;
8264   vl_api_set_arp_neighbor_limit_t *mp;
8265   u32 arp_nbr_limit;
8266   u8 limit_set = 0;
8267   u8 is_ipv6 = 0;
8268   int ret;
8269
8270   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8271     {
8272       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
8273         limit_set = 1;
8274       else if (unformat (i, "ipv6"))
8275         is_ipv6 = 1;
8276       else
8277         {
8278           clib_warning ("parse error '%U'", format_unformat_error, i);
8279           return -99;
8280         }
8281     }
8282
8283   if (limit_set == 0)
8284     {
8285       errmsg ("missing limit value");
8286       return -99;
8287     }
8288
8289   M (SET_ARP_NEIGHBOR_LIMIT, mp);
8290
8291   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
8292   mp->is_ipv6 = is_ipv6;
8293
8294   S (mp);
8295   W (ret);
8296   return ret;
8297 }
8298
8299 static int
8300 api_l2_patch_add_del (vat_main_t * vam)
8301 {
8302   unformat_input_t *i = vam->input;
8303   vl_api_l2_patch_add_del_t *mp;
8304   u32 rx_sw_if_index;
8305   u8 rx_sw_if_index_set = 0;
8306   u32 tx_sw_if_index;
8307   u8 tx_sw_if_index_set = 0;
8308   u8 is_add = 1;
8309   int ret;
8310
8311   /* Parse args required to build the message */
8312   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8313     {
8314       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
8315         rx_sw_if_index_set = 1;
8316       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
8317         tx_sw_if_index_set = 1;
8318       else if (unformat (i, "rx"))
8319         {
8320           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8321             {
8322               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8323                             &rx_sw_if_index))
8324                 rx_sw_if_index_set = 1;
8325             }
8326           else
8327             break;
8328         }
8329       else if (unformat (i, "tx"))
8330         {
8331           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8332             {
8333               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8334                             &tx_sw_if_index))
8335                 tx_sw_if_index_set = 1;
8336             }
8337           else
8338             break;
8339         }
8340       else if (unformat (i, "del"))
8341         is_add = 0;
8342       else
8343         break;
8344     }
8345
8346   if (rx_sw_if_index_set == 0)
8347     {
8348       errmsg ("missing rx interface name or rx_sw_if_index");
8349       return -99;
8350     }
8351
8352   if (tx_sw_if_index_set == 0)
8353     {
8354       errmsg ("missing tx interface name or tx_sw_if_index");
8355       return -99;
8356     }
8357
8358   M (L2_PATCH_ADD_DEL, mp);
8359
8360   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
8361   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
8362   mp->is_add = is_add;
8363
8364   S (mp);
8365   W (ret);
8366   return ret;
8367 }
8368
8369 u8 is_del;
8370 u8 localsid_addr[16];
8371 u8 end_psp;
8372 u8 behavior;
8373 u32 sw_if_index;
8374 u32 vlan_index;
8375 u32 fib_table;
8376 u8 nh_addr[16];
8377
8378 static int
8379 api_sr_localsid_add_del (vat_main_t * vam)
8380 {
8381   unformat_input_t *i = vam->input;
8382   vl_api_sr_localsid_add_del_t *mp;
8383
8384   u8 is_del;
8385   ip6_address_t localsid;
8386   u8 end_psp = 0;
8387   u8 behavior = ~0;
8388   u32 sw_if_index;
8389   u32 fib_table = ~(u32) 0;
8390   ip6_address_t next_hop;
8391
8392   bool nexthop_set = 0;
8393
8394   int ret;
8395
8396   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8397     {
8398       if (unformat (i, "del"))
8399         is_del = 1;
8400       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
8401       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
8402         nexthop_set = 1;
8403       else if (unformat (i, "behavior %u", &behavior));
8404       else if (unformat (i, "sw_if_index %u", &sw_if_index));
8405       else if (unformat (i, "fib-table %u", &fib_table));
8406       else if (unformat (i, "end.psp %u", &behavior));
8407       else
8408         break;
8409     }
8410
8411   M (SR_LOCALSID_ADD_DEL, mp);
8412
8413   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
8414   if (nexthop_set)
8415     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
8416   mp->behavior = behavior;
8417   mp->sw_if_index = ntohl (sw_if_index);
8418   mp->fib_table = ntohl (fib_table);
8419   mp->end_psp = end_psp;
8420   mp->is_del = is_del;
8421
8422   S (mp);
8423   W (ret);
8424   return ret;
8425 }
8426
8427 static int
8428 api_ioam_enable (vat_main_t * vam)
8429 {
8430   unformat_input_t *input = vam->input;
8431   vl_api_ioam_enable_t *mp;
8432   u32 id = 0;
8433   int has_trace_option = 0;
8434   int has_pot_option = 0;
8435   int has_seqno_option = 0;
8436   int has_analyse_option = 0;
8437   int ret;
8438
8439   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8440     {
8441       if (unformat (input, "trace"))
8442         has_trace_option = 1;
8443       else if (unformat (input, "pot"))
8444         has_pot_option = 1;
8445       else if (unformat (input, "seqno"))
8446         has_seqno_option = 1;
8447       else if (unformat (input, "analyse"))
8448         has_analyse_option = 1;
8449       else
8450         break;
8451     }
8452   M (IOAM_ENABLE, mp);
8453   mp->id = htons (id);
8454   mp->seqno = has_seqno_option;
8455   mp->analyse = has_analyse_option;
8456   mp->pot_enable = has_pot_option;
8457   mp->trace_enable = has_trace_option;
8458
8459   S (mp);
8460   W (ret);
8461   return ret;
8462 }
8463
8464
8465 static int
8466 api_ioam_disable (vat_main_t * vam)
8467 {
8468   vl_api_ioam_disable_t *mp;
8469   int ret;
8470
8471   M (IOAM_DISABLE, mp);
8472   S (mp);
8473   W (ret);
8474   return ret;
8475 }
8476
8477 #define foreach_tcp_proto_field                 \
8478 _(src_port)                                     \
8479 _(dst_port)
8480
8481 #define foreach_udp_proto_field                 \
8482 _(src_port)                                     \
8483 _(dst_port)
8484
8485 #define foreach_ip4_proto_field                 \
8486 _(src_address)                                  \
8487 _(dst_address)                                  \
8488 _(tos)                                          \
8489 _(length)                                       \
8490 _(fragment_id)                                  \
8491 _(ttl)                                          \
8492 _(protocol)                                     \
8493 _(checksum)
8494
8495 typedef struct
8496 {
8497   u16 src_port, dst_port;
8498 } tcpudp_header_t;
8499
8500 #if VPP_API_TEST_BUILTIN == 0
8501 uword
8502 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8503 {
8504   u8 **maskp = va_arg (*args, u8 **);
8505   u8 *mask = 0;
8506   u8 found_something = 0;
8507   tcp_header_t *tcp;
8508
8509 #define _(a) u8 a=0;
8510   foreach_tcp_proto_field;
8511 #undef _
8512
8513   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8514     {
8515       if (0);
8516 #define _(a) else if (unformat (input, #a)) a=1;
8517       foreach_tcp_proto_field
8518 #undef _
8519         else
8520         break;
8521     }
8522
8523 #define _(a) found_something += a;
8524   foreach_tcp_proto_field;
8525 #undef _
8526
8527   if (found_something == 0)
8528     return 0;
8529
8530   vec_validate (mask, sizeof (*tcp) - 1);
8531
8532   tcp = (tcp_header_t *) mask;
8533
8534 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8535   foreach_tcp_proto_field;
8536 #undef _
8537
8538   *maskp = mask;
8539   return 1;
8540 }
8541
8542 uword
8543 unformat_udp_mask (unformat_input_t * input, va_list * args)
8544 {
8545   u8 **maskp = va_arg (*args, u8 **);
8546   u8 *mask = 0;
8547   u8 found_something = 0;
8548   udp_header_t *udp;
8549
8550 #define _(a) u8 a=0;
8551   foreach_udp_proto_field;
8552 #undef _
8553
8554   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8555     {
8556       if (0);
8557 #define _(a) else if (unformat (input, #a)) a=1;
8558       foreach_udp_proto_field
8559 #undef _
8560         else
8561         break;
8562     }
8563
8564 #define _(a) found_something += a;
8565   foreach_udp_proto_field;
8566 #undef _
8567
8568   if (found_something == 0)
8569     return 0;
8570
8571   vec_validate (mask, sizeof (*udp) - 1);
8572
8573   udp = (udp_header_t *) mask;
8574
8575 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8576   foreach_udp_proto_field;
8577 #undef _
8578
8579   *maskp = mask;
8580   return 1;
8581 }
8582
8583 uword
8584 unformat_l4_mask (unformat_input_t * input, va_list * args)
8585 {
8586   u8 **maskp = va_arg (*args, u8 **);
8587   u16 src_port = 0, dst_port = 0;
8588   tcpudp_header_t *tcpudp;
8589
8590   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8591     {
8592       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8593         return 1;
8594       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8595         return 1;
8596       else if (unformat (input, "src_port"))
8597         src_port = 0xFFFF;
8598       else if (unformat (input, "dst_port"))
8599         dst_port = 0xFFFF;
8600       else
8601         return 0;
8602     }
8603
8604   if (!src_port && !dst_port)
8605     return 0;
8606
8607   u8 *mask = 0;
8608   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8609
8610   tcpudp = (tcpudp_header_t *) mask;
8611   tcpudp->src_port = src_port;
8612   tcpudp->dst_port = dst_port;
8613
8614   *maskp = mask;
8615
8616   return 1;
8617 }
8618
8619 uword
8620 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8621 {
8622   u8 **maskp = va_arg (*args, u8 **);
8623   u8 *mask = 0;
8624   u8 found_something = 0;
8625   ip4_header_t *ip;
8626
8627 #define _(a) u8 a=0;
8628   foreach_ip4_proto_field;
8629 #undef _
8630   u8 version = 0;
8631   u8 hdr_length = 0;
8632
8633
8634   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8635     {
8636       if (unformat (input, "version"))
8637         version = 1;
8638       else if (unformat (input, "hdr_length"))
8639         hdr_length = 1;
8640       else if (unformat (input, "src"))
8641         src_address = 1;
8642       else if (unformat (input, "dst"))
8643         dst_address = 1;
8644       else if (unformat (input, "proto"))
8645         protocol = 1;
8646
8647 #define _(a) else if (unformat (input, #a)) a=1;
8648       foreach_ip4_proto_field
8649 #undef _
8650         else
8651         break;
8652     }
8653
8654 #define _(a) found_something += a;
8655   foreach_ip4_proto_field;
8656 #undef _
8657
8658   if (found_something == 0)
8659     return 0;
8660
8661   vec_validate (mask, sizeof (*ip) - 1);
8662
8663   ip = (ip4_header_t *) mask;
8664
8665 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8666   foreach_ip4_proto_field;
8667 #undef _
8668
8669   ip->ip_version_and_header_length = 0;
8670
8671   if (version)
8672     ip->ip_version_and_header_length |= 0xF0;
8673
8674   if (hdr_length)
8675     ip->ip_version_and_header_length |= 0x0F;
8676
8677   *maskp = mask;
8678   return 1;
8679 }
8680
8681 #define foreach_ip6_proto_field                 \
8682 _(src_address)                                  \
8683 _(dst_address)                                  \
8684 _(payload_length)                               \
8685 _(hop_limit)                                    \
8686 _(protocol)
8687
8688 uword
8689 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8690 {
8691   u8 **maskp = va_arg (*args, u8 **);
8692   u8 *mask = 0;
8693   u8 found_something = 0;
8694   ip6_header_t *ip;
8695   u32 ip_version_traffic_class_and_flow_label;
8696
8697 #define _(a) u8 a=0;
8698   foreach_ip6_proto_field;
8699 #undef _
8700   u8 version = 0;
8701   u8 traffic_class = 0;
8702   u8 flow_label = 0;
8703
8704   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8705     {
8706       if (unformat (input, "version"))
8707         version = 1;
8708       else if (unformat (input, "traffic-class"))
8709         traffic_class = 1;
8710       else if (unformat (input, "flow-label"))
8711         flow_label = 1;
8712       else if (unformat (input, "src"))
8713         src_address = 1;
8714       else if (unformat (input, "dst"))
8715         dst_address = 1;
8716       else if (unformat (input, "proto"))
8717         protocol = 1;
8718
8719 #define _(a) else if (unformat (input, #a)) a=1;
8720       foreach_ip6_proto_field
8721 #undef _
8722         else
8723         break;
8724     }
8725
8726 #define _(a) found_something += a;
8727   foreach_ip6_proto_field;
8728 #undef _
8729
8730   if (found_something == 0)
8731     return 0;
8732
8733   vec_validate (mask, sizeof (*ip) - 1);
8734
8735   ip = (ip6_header_t *) mask;
8736
8737 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8738   foreach_ip6_proto_field;
8739 #undef _
8740
8741   ip_version_traffic_class_and_flow_label = 0;
8742
8743   if (version)
8744     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8745
8746   if (traffic_class)
8747     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8748
8749   if (flow_label)
8750     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8751
8752   ip->ip_version_traffic_class_and_flow_label =
8753     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8754
8755   *maskp = mask;
8756   return 1;
8757 }
8758
8759 uword
8760 unformat_l3_mask (unformat_input_t * input, va_list * args)
8761 {
8762   u8 **maskp = va_arg (*args, u8 **);
8763
8764   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8765     {
8766       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8767         return 1;
8768       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8769         return 1;
8770       else
8771         break;
8772     }
8773   return 0;
8774 }
8775
8776 uword
8777 unformat_l2_mask (unformat_input_t * input, va_list * args)
8778 {
8779   u8 **maskp = va_arg (*args, u8 **);
8780   u8 *mask = 0;
8781   u8 src = 0;
8782   u8 dst = 0;
8783   u8 proto = 0;
8784   u8 tag1 = 0;
8785   u8 tag2 = 0;
8786   u8 ignore_tag1 = 0;
8787   u8 ignore_tag2 = 0;
8788   u8 cos1 = 0;
8789   u8 cos2 = 0;
8790   u8 dot1q = 0;
8791   u8 dot1ad = 0;
8792   int len = 14;
8793
8794   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8795     {
8796       if (unformat (input, "src"))
8797         src = 1;
8798       else if (unformat (input, "dst"))
8799         dst = 1;
8800       else if (unformat (input, "proto"))
8801         proto = 1;
8802       else if (unformat (input, "tag1"))
8803         tag1 = 1;
8804       else if (unformat (input, "tag2"))
8805         tag2 = 1;
8806       else if (unformat (input, "ignore-tag1"))
8807         ignore_tag1 = 1;
8808       else if (unformat (input, "ignore-tag2"))
8809         ignore_tag2 = 1;
8810       else if (unformat (input, "cos1"))
8811         cos1 = 1;
8812       else if (unformat (input, "cos2"))
8813         cos2 = 1;
8814       else if (unformat (input, "dot1q"))
8815         dot1q = 1;
8816       else if (unformat (input, "dot1ad"))
8817         dot1ad = 1;
8818       else
8819         break;
8820     }
8821   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8822        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8823     return 0;
8824
8825   if (tag1 || ignore_tag1 || cos1 || dot1q)
8826     len = 18;
8827   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8828     len = 22;
8829
8830   vec_validate (mask, len - 1);
8831
8832   if (dst)
8833     memset (mask, 0xff, 6);
8834
8835   if (src)
8836     memset (mask + 6, 0xff, 6);
8837
8838   if (tag2 || dot1ad)
8839     {
8840       /* inner vlan tag */
8841       if (tag2)
8842         {
8843           mask[19] = 0xff;
8844           mask[18] = 0x0f;
8845         }
8846       if (cos2)
8847         mask[18] |= 0xe0;
8848       if (proto)
8849         mask[21] = mask[20] = 0xff;
8850       if (tag1)
8851         {
8852           mask[15] = 0xff;
8853           mask[14] = 0x0f;
8854         }
8855       if (cos1)
8856         mask[14] |= 0xe0;
8857       *maskp = mask;
8858       return 1;
8859     }
8860   if (tag1 | dot1q)
8861     {
8862       if (tag1)
8863         {
8864           mask[15] = 0xff;
8865           mask[14] = 0x0f;
8866         }
8867       if (cos1)
8868         mask[14] |= 0xe0;
8869       if (proto)
8870         mask[16] = mask[17] = 0xff;
8871
8872       *maskp = mask;
8873       return 1;
8874     }
8875   if (cos2)
8876     mask[18] |= 0xe0;
8877   if (cos1)
8878     mask[14] |= 0xe0;
8879   if (proto)
8880     mask[12] = mask[13] = 0xff;
8881
8882   *maskp = mask;
8883   return 1;
8884 }
8885
8886 uword
8887 unformat_classify_mask (unformat_input_t * input, va_list * args)
8888 {
8889   u8 **maskp = va_arg (*args, u8 **);
8890   u32 *skipp = va_arg (*args, u32 *);
8891   u32 *matchp = va_arg (*args, u32 *);
8892   u32 match;
8893   u8 *mask = 0;
8894   u8 *l2 = 0;
8895   u8 *l3 = 0;
8896   u8 *l4 = 0;
8897   int i;
8898
8899   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8900     {
8901       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8902         ;
8903       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8904         ;
8905       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8906         ;
8907       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8908         ;
8909       else
8910         break;
8911     }
8912
8913   if (l4 && !l3)
8914     {
8915       vec_free (mask);
8916       vec_free (l2);
8917       vec_free (l4);
8918       return 0;
8919     }
8920
8921   if (mask || l2 || l3 || l4)
8922     {
8923       if (l2 || l3 || l4)
8924         {
8925           /* "With a free Ethernet header in every package" */
8926           if (l2 == 0)
8927             vec_validate (l2, 13);
8928           mask = l2;
8929           if (vec_len (l3))
8930             {
8931               vec_append (mask, l3);
8932               vec_free (l3);
8933             }
8934           if (vec_len (l4))
8935             {
8936               vec_append (mask, l4);
8937               vec_free (l4);
8938             }
8939         }
8940
8941       /* Scan forward looking for the first significant mask octet */
8942       for (i = 0; i < vec_len (mask); i++)
8943         if (mask[i])
8944           break;
8945
8946       /* compute (skip, match) params */
8947       *skipp = i / sizeof (u32x4);
8948       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8949
8950       /* Pad mask to an even multiple of the vector size */
8951       while (vec_len (mask) % sizeof (u32x4))
8952         vec_add1 (mask, 0);
8953
8954       match = vec_len (mask) / sizeof (u32x4);
8955
8956       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8957         {
8958           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8959           if (*tmp || *(tmp + 1))
8960             break;
8961           match--;
8962         }
8963       if (match == 0)
8964         clib_warning ("BUG: match 0");
8965
8966       _vec_len (mask) = match * sizeof (u32x4);
8967
8968       *matchp = match;
8969       *maskp = mask;
8970
8971       return 1;
8972     }
8973
8974   return 0;
8975 }
8976 #endif /* VPP_API_TEST_BUILTIN */
8977
8978 #define foreach_l2_next                         \
8979 _(drop, DROP)                                   \
8980 _(ethernet, ETHERNET_INPUT)                     \
8981 _(ip4, IP4_INPUT)                               \
8982 _(ip6, IP6_INPUT)
8983
8984 uword
8985 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8986 {
8987   u32 *miss_next_indexp = va_arg (*args, u32 *);
8988   u32 next_index = 0;
8989   u32 tmp;
8990
8991 #define _(n,N) \
8992   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8993   foreach_l2_next;
8994 #undef _
8995
8996   if (unformat (input, "%d", &tmp))
8997     {
8998       next_index = tmp;
8999       goto out;
9000     }
9001
9002   return 0;
9003
9004 out:
9005   *miss_next_indexp = next_index;
9006   return 1;
9007 }
9008
9009 #define foreach_ip_next                         \
9010 _(drop, DROP)                                   \
9011 _(local, LOCAL)                                 \
9012 _(rewrite, REWRITE)
9013
9014 uword
9015 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9016 {
9017   u32 *miss_next_indexp = va_arg (*args, u32 *);
9018   u32 next_index = 0;
9019   u32 tmp;
9020
9021 #define _(n,N) \
9022   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9023   foreach_ip_next;
9024 #undef _
9025
9026   if (unformat (input, "%d", &tmp))
9027     {
9028       next_index = tmp;
9029       goto out;
9030     }
9031
9032   return 0;
9033
9034 out:
9035   *miss_next_indexp = next_index;
9036   return 1;
9037 }
9038
9039 #define foreach_acl_next                        \
9040 _(deny, DENY)
9041
9042 uword
9043 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9044 {
9045   u32 *miss_next_indexp = va_arg (*args, u32 *);
9046   u32 next_index = 0;
9047   u32 tmp;
9048
9049 #define _(n,N) \
9050   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9051   foreach_acl_next;
9052 #undef _
9053
9054   if (unformat (input, "permit"))
9055     {
9056       next_index = ~0;
9057       goto out;
9058     }
9059   else if (unformat (input, "%d", &tmp))
9060     {
9061       next_index = tmp;
9062       goto out;
9063     }
9064
9065   return 0;
9066
9067 out:
9068   *miss_next_indexp = next_index;
9069   return 1;
9070 }
9071
9072 uword
9073 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9074 {
9075   u32 *r = va_arg (*args, u32 *);
9076
9077   if (unformat (input, "conform-color"))
9078     *r = POLICE_CONFORM;
9079   else if (unformat (input, "exceed-color"))
9080     *r = POLICE_EXCEED;
9081   else
9082     return 0;
9083
9084   return 1;
9085 }
9086
9087 static int
9088 api_classify_add_del_table (vat_main_t * vam)
9089 {
9090   unformat_input_t *i = vam->input;
9091   vl_api_classify_add_del_table_t *mp;
9092
9093   u32 nbuckets = 2;
9094   u32 skip = ~0;
9095   u32 match = ~0;
9096   int is_add = 1;
9097   int del_chain = 0;
9098   u32 table_index = ~0;
9099   u32 next_table_index = ~0;
9100   u32 miss_next_index = ~0;
9101   u32 memory_size = 32 << 20;
9102   u8 *mask = 0;
9103   u32 current_data_flag = 0;
9104   int current_data_offset = 0;
9105   int ret;
9106
9107   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9108     {
9109       if (unformat (i, "del"))
9110         is_add = 0;
9111       else if (unformat (i, "del-chain"))
9112         {
9113           is_add = 0;
9114           del_chain = 1;
9115         }
9116       else if (unformat (i, "buckets %d", &nbuckets))
9117         ;
9118       else if (unformat (i, "memory_size %d", &memory_size))
9119         ;
9120       else if (unformat (i, "skip %d", &skip))
9121         ;
9122       else if (unformat (i, "match %d", &match))
9123         ;
9124       else if (unformat (i, "table %d", &table_index))
9125         ;
9126       else if (unformat (i, "mask %U", unformat_classify_mask,
9127                          &mask, &skip, &match))
9128         ;
9129       else if (unformat (i, "next-table %d", &next_table_index))
9130         ;
9131       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
9132                          &miss_next_index))
9133         ;
9134       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
9135                          &miss_next_index))
9136         ;
9137       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
9138                          &miss_next_index))
9139         ;
9140       else if (unformat (i, "current-data-flag %d", &current_data_flag))
9141         ;
9142       else if (unformat (i, "current-data-offset %d", &current_data_offset))
9143         ;
9144       else
9145         break;
9146     }
9147
9148   if (is_add && mask == 0)
9149     {
9150       errmsg ("Mask required");
9151       return -99;
9152     }
9153
9154   if (is_add && skip == ~0)
9155     {
9156       errmsg ("skip count required");
9157       return -99;
9158     }
9159
9160   if (is_add && match == ~0)
9161     {
9162       errmsg ("match count required");
9163       return -99;
9164     }
9165
9166   if (!is_add && table_index == ~0)
9167     {
9168       errmsg ("table index required for delete");
9169       return -99;
9170     }
9171
9172   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
9173
9174   mp->is_add = is_add;
9175   mp->del_chain = del_chain;
9176   mp->table_index = ntohl (table_index);
9177   mp->nbuckets = ntohl (nbuckets);
9178   mp->memory_size = ntohl (memory_size);
9179   mp->skip_n_vectors = ntohl (skip);
9180   mp->match_n_vectors = ntohl (match);
9181   mp->next_table_index = ntohl (next_table_index);
9182   mp->miss_next_index = ntohl (miss_next_index);
9183   mp->current_data_flag = ntohl (current_data_flag);
9184   mp->current_data_offset = ntohl (current_data_offset);
9185   clib_memcpy (mp->mask, mask, vec_len (mask));
9186
9187   vec_free (mask);
9188
9189   S (mp);
9190   W (ret);
9191   return ret;
9192 }
9193
9194 #if VPP_API_TEST_BUILTIN == 0
9195 uword
9196 unformat_l4_match (unformat_input_t * input, va_list * args)
9197 {
9198   u8 **matchp = va_arg (*args, u8 **);
9199
9200   u8 *proto_header = 0;
9201   int src_port = 0;
9202   int dst_port = 0;
9203
9204   tcpudp_header_t h;
9205
9206   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9207     {
9208       if (unformat (input, "src_port %d", &src_port))
9209         ;
9210       else if (unformat (input, "dst_port %d", &dst_port))
9211         ;
9212       else
9213         return 0;
9214     }
9215
9216   h.src_port = clib_host_to_net_u16 (src_port);
9217   h.dst_port = clib_host_to_net_u16 (dst_port);
9218   vec_validate (proto_header, sizeof (h) - 1);
9219   memcpy (proto_header, &h, sizeof (h));
9220
9221   *matchp = proto_header;
9222
9223   return 1;
9224 }
9225
9226 uword
9227 unformat_ip4_match (unformat_input_t * input, va_list * args)
9228 {
9229   u8 **matchp = va_arg (*args, u8 **);
9230   u8 *match = 0;
9231   ip4_header_t *ip;
9232   int version = 0;
9233   u32 version_val;
9234   int hdr_length = 0;
9235   u32 hdr_length_val;
9236   int src = 0, dst = 0;
9237   ip4_address_t src_val, dst_val;
9238   int proto = 0;
9239   u32 proto_val;
9240   int tos = 0;
9241   u32 tos_val;
9242   int length = 0;
9243   u32 length_val;
9244   int fragment_id = 0;
9245   u32 fragment_id_val;
9246   int ttl = 0;
9247   int ttl_val;
9248   int checksum = 0;
9249   u32 checksum_val;
9250
9251   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9252     {
9253       if (unformat (input, "version %d", &version_val))
9254         version = 1;
9255       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9256         hdr_length = 1;
9257       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9258         src = 1;
9259       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9260         dst = 1;
9261       else if (unformat (input, "proto %d", &proto_val))
9262         proto = 1;
9263       else if (unformat (input, "tos %d", &tos_val))
9264         tos = 1;
9265       else if (unformat (input, "length %d", &length_val))
9266         length = 1;
9267       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9268         fragment_id = 1;
9269       else if (unformat (input, "ttl %d", &ttl_val))
9270         ttl = 1;
9271       else if (unformat (input, "checksum %d", &checksum_val))
9272         checksum = 1;
9273       else
9274         break;
9275     }
9276
9277   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9278       + ttl + checksum == 0)
9279     return 0;
9280
9281   /*
9282    * Aligned because we use the real comparison functions
9283    */
9284   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9285
9286   ip = (ip4_header_t *) match;
9287
9288   /* These are realistically matched in practice */
9289   if (src)
9290     ip->src_address.as_u32 = src_val.as_u32;
9291
9292   if (dst)
9293     ip->dst_address.as_u32 = dst_val.as_u32;
9294
9295   if (proto)
9296     ip->protocol = proto_val;
9297
9298
9299   /* These are not, but they're included for completeness */
9300   if (version)
9301     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9302
9303   if (hdr_length)
9304     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9305
9306   if (tos)
9307     ip->tos = tos_val;
9308
9309   if (length)
9310     ip->length = clib_host_to_net_u16 (length_val);
9311
9312   if (ttl)
9313     ip->ttl = ttl_val;
9314
9315   if (checksum)
9316     ip->checksum = clib_host_to_net_u16 (checksum_val);
9317
9318   *matchp = match;
9319   return 1;
9320 }
9321
9322 uword
9323 unformat_ip6_match (unformat_input_t * input, va_list * args)
9324 {
9325   u8 **matchp = va_arg (*args, u8 **);
9326   u8 *match = 0;
9327   ip6_header_t *ip;
9328   int version = 0;
9329   u32 version_val;
9330   u8 traffic_class = 0;
9331   u32 traffic_class_val = 0;
9332   u8 flow_label = 0;
9333   u8 flow_label_val;
9334   int src = 0, dst = 0;
9335   ip6_address_t src_val, dst_val;
9336   int proto = 0;
9337   u32 proto_val;
9338   int payload_length = 0;
9339   u32 payload_length_val;
9340   int hop_limit = 0;
9341   int hop_limit_val;
9342   u32 ip_version_traffic_class_and_flow_label;
9343
9344   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9345     {
9346       if (unformat (input, "version %d", &version_val))
9347         version = 1;
9348       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9349         traffic_class = 1;
9350       else if (unformat (input, "flow_label %d", &flow_label_val))
9351         flow_label = 1;
9352       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9353         src = 1;
9354       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9355         dst = 1;
9356       else if (unformat (input, "proto %d", &proto_val))
9357         proto = 1;
9358       else if (unformat (input, "payload_length %d", &payload_length_val))
9359         payload_length = 1;
9360       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9361         hop_limit = 1;
9362       else
9363         break;
9364     }
9365
9366   if (version + traffic_class + flow_label + src + dst + proto +
9367       payload_length + hop_limit == 0)
9368     return 0;
9369
9370   /*
9371    * Aligned because we use the real comparison functions
9372    */
9373   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9374
9375   ip = (ip6_header_t *) match;
9376
9377   if (src)
9378     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9379
9380   if (dst)
9381     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9382
9383   if (proto)
9384     ip->protocol = proto_val;
9385
9386   ip_version_traffic_class_and_flow_label = 0;
9387
9388   if (version)
9389     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9390
9391   if (traffic_class)
9392     ip_version_traffic_class_and_flow_label |=
9393       (traffic_class_val & 0xFF) << 20;
9394
9395   if (flow_label)
9396     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9397
9398   ip->ip_version_traffic_class_and_flow_label =
9399     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9400
9401   if (payload_length)
9402     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9403
9404   if (hop_limit)
9405     ip->hop_limit = hop_limit_val;
9406
9407   *matchp = match;
9408   return 1;
9409 }
9410
9411 uword
9412 unformat_l3_match (unformat_input_t * input, va_list * args)
9413 {
9414   u8 **matchp = va_arg (*args, u8 **);
9415
9416   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9417     {
9418       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9419         return 1;
9420       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9421         return 1;
9422       else
9423         break;
9424     }
9425   return 0;
9426 }
9427
9428 uword
9429 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9430 {
9431   u8 *tagp = va_arg (*args, u8 *);
9432   u32 tag;
9433
9434   if (unformat (input, "%d", &tag))
9435     {
9436       tagp[0] = (tag >> 8) & 0x0F;
9437       tagp[1] = tag & 0xFF;
9438       return 1;
9439     }
9440
9441   return 0;
9442 }
9443
9444 uword
9445 unformat_l2_match (unformat_input_t * input, va_list * args)
9446 {
9447   u8 **matchp = va_arg (*args, u8 **);
9448   u8 *match = 0;
9449   u8 src = 0;
9450   u8 src_val[6];
9451   u8 dst = 0;
9452   u8 dst_val[6];
9453   u8 proto = 0;
9454   u16 proto_val;
9455   u8 tag1 = 0;
9456   u8 tag1_val[2];
9457   u8 tag2 = 0;
9458   u8 tag2_val[2];
9459   int len = 14;
9460   u8 ignore_tag1 = 0;
9461   u8 ignore_tag2 = 0;
9462   u8 cos1 = 0;
9463   u8 cos2 = 0;
9464   u32 cos1_val = 0;
9465   u32 cos2_val = 0;
9466
9467   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9468     {
9469       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9470         src = 1;
9471       else
9472         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9473         dst = 1;
9474       else if (unformat (input, "proto %U",
9475                          unformat_ethernet_type_host_byte_order, &proto_val))
9476         proto = 1;
9477       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9478         tag1 = 1;
9479       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9480         tag2 = 1;
9481       else if (unformat (input, "ignore-tag1"))
9482         ignore_tag1 = 1;
9483       else if (unformat (input, "ignore-tag2"))
9484         ignore_tag2 = 1;
9485       else if (unformat (input, "cos1 %d", &cos1_val))
9486         cos1 = 1;
9487       else if (unformat (input, "cos2 %d", &cos2_val))
9488         cos2 = 1;
9489       else
9490         break;
9491     }
9492   if ((src + dst + proto + tag1 + tag2 +
9493        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9494     return 0;
9495
9496   if (tag1 || ignore_tag1 || cos1)
9497     len = 18;
9498   if (tag2 || ignore_tag2 || cos2)
9499     len = 22;
9500
9501   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9502
9503   if (dst)
9504     clib_memcpy (match, dst_val, 6);
9505
9506   if (src)
9507     clib_memcpy (match + 6, src_val, 6);
9508
9509   if (tag2)
9510     {
9511       /* inner vlan tag */
9512       match[19] = tag2_val[1];
9513       match[18] = tag2_val[0];
9514       if (cos2)
9515         match[18] |= (cos2_val & 0x7) << 5;
9516       if (proto)
9517         {
9518           match[21] = proto_val & 0xff;
9519           match[20] = proto_val >> 8;
9520         }
9521       if (tag1)
9522         {
9523           match[15] = tag1_val[1];
9524           match[14] = tag1_val[0];
9525         }
9526       if (cos1)
9527         match[14] |= (cos1_val & 0x7) << 5;
9528       *matchp = match;
9529       return 1;
9530     }
9531   if (tag1)
9532     {
9533       match[15] = tag1_val[1];
9534       match[14] = tag1_val[0];
9535       if (proto)
9536         {
9537           match[17] = proto_val & 0xff;
9538           match[16] = proto_val >> 8;
9539         }
9540       if (cos1)
9541         match[14] |= (cos1_val & 0x7) << 5;
9542
9543       *matchp = match;
9544       return 1;
9545     }
9546   if (cos2)
9547     match[18] |= (cos2_val & 0x7) << 5;
9548   if (cos1)
9549     match[14] |= (cos1_val & 0x7) << 5;
9550   if (proto)
9551     {
9552       match[13] = proto_val & 0xff;
9553       match[12] = proto_val >> 8;
9554     }
9555
9556   *matchp = match;
9557   return 1;
9558 }
9559 #endif
9560
9561 uword
9562 api_unformat_classify_match (unformat_input_t * input, va_list * args)
9563 {
9564   u8 **matchp = va_arg (*args, u8 **);
9565   u32 skip_n_vectors = va_arg (*args, u32);
9566   u32 match_n_vectors = va_arg (*args, u32);
9567
9568   u8 *match = 0;
9569   u8 *l2 = 0;
9570   u8 *l3 = 0;
9571   u8 *l4 = 0;
9572
9573   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9574     {
9575       if (unformat (input, "hex %U", unformat_hex_string, &match))
9576         ;
9577       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9578         ;
9579       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9580         ;
9581       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9582         ;
9583       else
9584         break;
9585     }
9586
9587   if (l4 && !l3)
9588     {
9589       vec_free (match);
9590       vec_free (l2);
9591       vec_free (l4);
9592       return 0;
9593     }
9594
9595   if (match || l2 || l3 || l4)
9596     {
9597       if (l2 || l3 || l4)
9598         {
9599           /* "Win a free Ethernet header in every packet" */
9600           if (l2 == 0)
9601             vec_validate_aligned (l2, 13, sizeof (u32x4));
9602           match = l2;
9603           if (vec_len (l3))
9604             {
9605               vec_append_aligned (match, l3, sizeof (u32x4));
9606               vec_free (l3);
9607             }
9608           if (vec_len (l4))
9609             {
9610               vec_append_aligned (match, l4, sizeof (u32x4));
9611               vec_free (l4);
9612             }
9613         }
9614
9615       /* Make sure the vector is big enough even if key is all 0's */
9616       vec_validate_aligned
9617         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9618          sizeof (u32x4));
9619
9620       /* Set size, include skipped vectors */
9621       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9622
9623       *matchp = match;
9624
9625       return 1;
9626     }
9627
9628   return 0;
9629 }
9630
9631 static int
9632 api_classify_add_del_session (vat_main_t * vam)
9633 {
9634   unformat_input_t *i = vam->input;
9635   vl_api_classify_add_del_session_t *mp;
9636   int is_add = 1;
9637   u32 table_index = ~0;
9638   u32 hit_next_index = ~0;
9639   u32 opaque_index = ~0;
9640   u8 *match = 0;
9641   i32 advance = 0;
9642   u32 skip_n_vectors = 0;
9643   u32 match_n_vectors = 0;
9644   u32 action = 0;
9645   u32 metadata = 0;
9646   int ret;
9647
9648   /*
9649    * Warning: you have to supply skip_n and match_n
9650    * because the API client cant simply look at the classify
9651    * table object.
9652    */
9653
9654   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9655     {
9656       if (unformat (i, "del"))
9657         is_add = 0;
9658       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
9659                          &hit_next_index))
9660         ;
9661       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9662                          &hit_next_index))
9663         ;
9664       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
9665                          &hit_next_index))
9666         ;
9667       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9668         ;
9669       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9670         ;
9671       else if (unformat (i, "opaque-index %d", &opaque_index))
9672         ;
9673       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9674         ;
9675       else if (unformat (i, "match_n %d", &match_n_vectors))
9676         ;
9677       else if (unformat (i, "match %U", api_unformat_classify_match,
9678                          &match, skip_n_vectors, match_n_vectors))
9679         ;
9680       else if (unformat (i, "advance %d", &advance))
9681         ;
9682       else if (unformat (i, "table-index %d", &table_index))
9683         ;
9684       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9685         action = 1;
9686       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9687         action = 2;
9688       else if (unformat (i, "action %d", &action))
9689         ;
9690       else if (unformat (i, "metadata %d", &metadata))
9691         ;
9692       else
9693         break;
9694     }
9695
9696   if (table_index == ~0)
9697     {
9698       errmsg ("Table index required");
9699       return -99;
9700     }
9701
9702   if (is_add && match == 0)
9703     {
9704       errmsg ("Match value required");
9705       return -99;
9706     }
9707
9708   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
9709
9710   mp->is_add = is_add;
9711   mp->table_index = ntohl (table_index);
9712   mp->hit_next_index = ntohl (hit_next_index);
9713   mp->opaque_index = ntohl (opaque_index);
9714   mp->advance = ntohl (advance);
9715   mp->action = action;
9716   mp->metadata = ntohl (metadata);
9717   clib_memcpy (mp->match, match, vec_len (match));
9718   vec_free (match);
9719
9720   S (mp);
9721   W (ret);
9722   return ret;
9723 }
9724
9725 static int
9726 api_classify_set_interface_ip_table (vat_main_t * vam)
9727 {
9728   unformat_input_t *i = vam->input;
9729   vl_api_classify_set_interface_ip_table_t *mp;
9730   u32 sw_if_index;
9731   int sw_if_index_set;
9732   u32 table_index = ~0;
9733   u8 is_ipv6 = 0;
9734   int ret;
9735
9736   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9737     {
9738       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9739         sw_if_index_set = 1;
9740       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9741         sw_if_index_set = 1;
9742       else if (unformat (i, "table %d", &table_index))
9743         ;
9744       else
9745         {
9746           clib_warning ("parse error '%U'", format_unformat_error, i);
9747           return -99;
9748         }
9749     }
9750
9751   if (sw_if_index_set == 0)
9752     {
9753       errmsg ("missing interface name or sw_if_index");
9754       return -99;
9755     }
9756
9757
9758   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
9759
9760   mp->sw_if_index = ntohl (sw_if_index);
9761   mp->table_index = ntohl (table_index);
9762   mp->is_ipv6 = is_ipv6;
9763
9764   S (mp);
9765   W (ret);
9766   return ret;
9767 }
9768
9769 static int
9770 api_classify_set_interface_l2_tables (vat_main_t * vam)
9771 {
9772   unformat_input_t *i = vam->input;
9773   vl_api_classify_set_interface_l2_tables_t *mp;
9774   u32 sw_if_index;
9775   int sw_if_index_set;
9776   u32 ip4_table_index = ~0;
9777   u32 ip6_table_index = ~0;
9778   u32 other_table_index = ~0;
9779   u32 is_input = 1;
9780   int ret;
9781
9782   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9783     {
9784       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9785         sw_if_index_set = 1;
9786       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9787         sw_if_index_set = 1;
9788       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9789         ;
9790       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9791         ;
9792       else if (unformat (i, "other-table %d", &other_table_index))
9793         ;
9794       else if (unformat (i, "is-input %d", &is_input))
9795         ;
9796       else
9797         {
9798           clib_warning ("parse error '%U'", format_unformat_error, i);
9799           return -99;
9800         }
9801     }
9802
9803   if (sw_if_index_set == 0)
9804     {
9805       errmsg ("missing interface name or sw_if_index");
9806       return -99;
9807     }
9808
9809
9810   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
9811
9812   mp->sw_if_index = ntohl (sw_if_index);
9813   mp->ip4_table_index = ntohl (ip4_table_index);
9814   mp->ip6_table_index = ntohl (ip6_table_index);
9815   mp->other_table_index = ntohl (other_table_index);
9816   mp->is_input = (u8) is_input;
9817
9818   S (mp);
9819   W (ret);
9820   return ret;
9821 }
9822
9823 static int
9824 api_set_ipfix_exporter (vat_main_t * vam)
9825 {
9826   unformat_input_t *i = vam->input;
9827   vl_api_set_ipfix_exporter_t *mp;
9828   ip4_address_t collector_address;
9829   u8 collector_address_set = 0;
9830   u32 collector_port = ~0;
9831   ip4_address_t src_address;
9832   u8 src_address_set = 0;
9833   u32 vrf_id = ~0;
9834   u32 path_mtu = ~0;
9835   u32 template_interval = ~0;
9836   u8 udp_checksum = 0;
9837   int ret;
9838
9839   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9840     {
9841       if (unformat (i, "collector_address %U", unformat_ip4_address,
9842                     &collector_address))
9843         collector_address_set = 1;
9844       else if (unformat (i, "collector_port %d", &collector_port))
9845         ;
9846       else if (unformat (i, "src_address %U", unformat_ip4_address,
9847                          &src_address))
9848         src_address_set = 1;
9849       else if (unformat (i, "vrf_id %d", &vrf_id))
9850         ;
9851       else if (unformat (i, "path_mtu %d", &path_mtu))
9852         ;
9853       else if (unformat (i, "template_interval %d", &template_interval))
9854         ;
9855       else if (unformat (i, "udp_checksum"))
9856         udp_checksum = 1;
9857       else
9858         break;
9859     }
9860
9861   if (collector_address_set == 0)
9862     {
9863       errmsg ("collector_address required");
9864       return -99;
9865     }
9866
9867   if (src_address_set == 0)
9868     {
9869       errmsg ("src_address required");
9870       return -99;
9871     }
9872
9873   M (SET_IPFIX_EXPORTER, mp);
9874
9875   memcpy (mp->collector_address, collector_address.data,
9876           sizeof (collector_address.data));
9877   mp->collector_port = htons ((u16) collector_port);
9878   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9879   mp->vrf_id = htonl (vrf_id);
9880   mp->path_mtu = htonl (path_mtu);
9881   mp->template_interval = htonl (template_interval);
9882   mp->udp_checksum = udp_checksum;
9883
9884   S (mp);
9885   W (ret);
9886   return ret;
9887 }
9888
9889 static int
9890 api_set_ipfix_classify_stream (vat_main_t * vam)
9891 {
9892   unformat_input_t *i = vam->input;
9893   vl_api_set_ipfix_classify_stream_t *mp;
9894   u32 domain_id = 0;
9895   u32 src_port = UDP_DST_PORT_ipfix;
9896   int ret;
9897
9898   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9899     {
9900       if (unformat (i, "domain %d", &domain_id))
9901         ;
9902       else if (unformat (i, "src_port %d", &src_port))
9903         ;
9904       else
9905         {
9906           errmsg ("unknown input `%U'", format_unformat_error, i);
9907           return -99;
9908         }
9909     }
9910
9911   M (SET_IPFIX_CLASSIFY_STREAM, mp);
9912
9913   mp->domain_id = htonl (domain_id);
9914   mp->src_port = htons ((u16) src_port);
9915
9916   S (mp);
9917   W (ret);
9918   return ret;
9919 }
9920
9921 static int
9922 api_ipfix_classify_table_add_del (vat_main_t * vam)
9923 {
9924   unformat_input_t *i = vam->input;
9925   vl_api_ipfix_classify_table_add_del_t *mp;
9926   int is_add = -1;
9927   u32 classify_table_index = ~0;
9928   u8 ip_version = 0;
9929   u8 transport_protocol = 255;
9930   int ret;
9931
9932   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9933     {
9934       if (unformat (i, "add"))
9935         is_add = 1;
9936       else if (unformat (i, "del"))
9937         is_add = 0;
9938       else if (unformat (i, "table %d", &classify_table_index))
9939         ;
9940       else if (unformat (i, "ip4"))
9941         ip_version = 4;
9942       else if (unformat (i, "ip6"))
9943         ip_version = 6;
9944       else if (unformat (i, "tcp"))
9945         transport_protocol = 6;
9946       else if (unformat (i, "udp"))
9947         transport_protocol = 17;
9948       else
9949         {
9950           errmsg ("unknown input `%U'", format_unformat_error, i);
9951           return -99;
9952         }
9953     }
9954
9955   if (is_add == -1)
9956     {
9957       errmsg ("expecting: add|del");
9958       return -99;
9959     }
9960   if (classify_table_index == ~0)
9961     {
9962       errmsg ("classifier table not specified");
9963       return -99;
9964     }
9965   if (ip_version == 0)
9966     {
9967       errmsg ("IP version not specified");
9968       return -99;
9969     }
9970
9971   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
9972
9973   mp->is_add = is_add;
9974   mp->table_id = htonl (classify_table_index);
9975   mp->ip_version = ip_version;
9976   mp->transport_protocol = transport_protocol;
9977
9978   S (mp);
9979   W (ret);
9980   return ret;
9981 }
9982
9983 static int
9984 api_get_node_index (vat_main_t * vam)
9985 {
9986   unformat_input_t *i = vam->input;
9987   vl_api_get_node_index_t *mp;
9988   u8 *name = 0;
9989   int ret;
9990
9991   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9992     {
9993       if (unformat (i, "node %s", &name))
9994         ;
9995       else
9996         break;
9997     }
9998   if (name == 0)
9999     {
10000       errmsg ("node name required");
10001       return -99;
10002     }
10003   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10004     {
10005       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10006       return -99;
10007     }
10008
10009   M (GET_NODE_INDEX, mp);
10010   clib_memcpy (mp->node_name, name, vec_len (name));
10011   vec_free (name);
10012
10013   S (mp);
10014   W (ret);
10015   return ret;
10016 }
10017
10018 static int
10019 api_get_next_index (vat_main_t * vam)
10020 {
10021   unformat_input_t *i = vam->input;
10022   vl_api_get_next_index_t *mp;
10023   u8 *node_name = 0, *next_node_name = 0;
10024   int ret;
10025
10026   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10027     {
10028       if (unformat (i, "node-name %s", &node_name))
10029         ;
10030       else if (unformat (i, "next-node-name %s", &next_node_name))
10031         break;
10032     }
10033
10034   if (node_name == 0)
10035     {
10036       errmsg ("node name required");
10037       return -99;
10038     }
10039   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10040     {
10041       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10042       return -99;
10043     }
10044
10045   if (next_node_name == 0)
10046     {
10047       errmsg ("next node name required");
10048       return -99;
10049     }
10050   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10051     {
10052       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10053       return -99;
10054     }
10055
10056   M (GET_NEXT_INDEX, mp);
10057   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10058   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10059   vec_free (node_name);
10060   vec_free (next_node_name);
10061
10062   S (mp);
10063   W (ret);
10064   return ret;
10065 }
10066
10067 static int
10068 api_add_node_next (vat_main_t * vam)
10069 {
10070   unformat_input_t *i = vam->input;
10071   vl_api_add_node_next_t *mp;
10072   u8 *name = 0;
10073   u8 *next = 0;
10074   int ret;
10075
10076   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10077     {
10078       if (unformat (i, "node %s", &name))
10079         ;
10080       else if (unformat (i, "next %s", &next))
10081         ;
10082       else
10083         break;
10084     }
10085   if (name == 0)
10086     {
10087       errmsg ("node name required");
10088       return -99;
10089     }
10090   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10091     {
10092       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10093       return -99;
10094     }
10095   if (next == 0)
10096     {
10097       errmsg ("next node required");
10098       return -99;
10099     }
10100   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10101     {
10102       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10103       return -99;
10104     }
10105
10106   M (ADD_NODE_NEXT, mp);
10107   clib_memcpy (mp->node_name, name, vec_len (name));
10108   clib_memcpy (mp->next_name, next, vec_len (next));
10109   vec_free (name);
10110   vec_free (next);
10111
10112   S (mp);
10113   W (ret);
10114   return ret;
10115 }
10116
10117 static int
10118 api_l2tpv3_create_tunnel (vat_main_t * vam)
10119 {
10120   unformat_input_t *i = vam->input;
10121   ip6_address_t client_address, our_address;
10122   int client_address_set = 0;
10123   int our_address_set = 0;
10124   u32 local_session_id = 0;
10125   u32 remote_session_id = 0;
10126   u64 local_cookie = 0;
10127   u64 remote_cookie = 0;
10128   u8 l2_sublayer_present = 0;
10129   vl_api_l2tpv3_create_tunnel_t *mp;
10130   int ret;
10131
10132   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10133     {
10134       if (unformat (i, "client_address %U", unformat_ip6_address,
10135                     &client_address))
10136         client_address_set = 1;
10137       else if (unformat (i, "our_address %U", unformat_ip6_address,
10138                          &our_address))
10139         our_address_set = 1;
10140       else if (unformat (i, "local_session_id %d", &local_session_id))
10141         ;
10142       else if (unformat (i, "remote_session_id %d", &remote_session_id))
10143         ;
10144       else if (unformat (i, "local_cookie %lld", &local_cookie))
10145         ;
10146       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10147         ;
10148       else if (unformat (i, "l2-sublayer-present"))
10149         l2_sublayer_present = 1;
10150       else
10151         break;
10152     }
10153
10154   if (client_address_set == 0)
10155     {
10156       errmsg ("client_address required");
10157       return -99;
10158     }
10159
10160   if (our_address_set == 0)
10161     {
10162       errmsg ("our_address required");
10163       return -99;
10164     }
10165
10166   M (L2TPV3_CREATE_TUNNEL, mp);
10167
10168   clib_memcpy (mp->client_address, client_address.as_u8,
10169                sizeof (mp->client_address));
10170
10171   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10172
10173   mp->local_session_id = ntohl (local_session_id);
10174   mp->remote_session_id = ntohl (remote_session_id);
10175   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10176   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10177   mp->l2_sublayer_present = l2_sublayer_present;
10178   mp->is_ipv6 = 1;
10179
10180   S (mp);
10181   W (ret);
10182   return ret;
10183 }
10184
10185 static int
10186 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10187 {
10188   unformat_input_t *i = vam->input;
10189   u32 sw_if_index;
10190   u8 sw_if_index_set = 0;
10191   u64 new_local_cookie = 0;
10192   u64 new_remote_cookie = 0;
10193   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10194   int ret;
10195
10196   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10197     {
10198       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10199         sw_if_index_set = 1;
10200       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10201         sw_if_index_set = 1;
10202       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10203         ;
10204       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10205         ;
10206       else
10207         break;
10208     }
10209
10210   if (sw_if_index_set == 0)
10211     {
10212       errmsg ("missing interface name or sw_if_index");
10213       return -99;
10214     }
10215
10216   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
10217
10218   mp->sw_if_index = ntohl (sw_if_index);
10219   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10220   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10221
10222   S (mp);
10223   W (ret);
10224   return ret;
10225 }
10226
10227 static int
10228 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10229 {
10230   unformat_input_t *i = vam->input;
10231   vl_api_l2tpv3_interface_enable_disable_t *mp;
10232   u32 sw_if_index;
10233   u8 sw_if_index_set = 0;
10234   u8 enable_disable = 1;
10235   int ret;
10236
10237   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10238     {
10239       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10240         sw_if_index_set = 1;
10241       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10242         sw_if_index_set = 1;
10243       else if (unformat (i, "enable"))
10244         enable_disable = 1;
10245       else if (unformat (i, "disable"))
10246         enable_disable = 0;
10247       else
10248         break;
10249     }
10250
10251   if (sw_if_index_set == 0)
10252     {
10253       errmsg ("missing interface name or sw_if_index");
10254       return -99;
10255     }
10256
10257   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
10258
10259   mp->sw_if_index = ntohl (sw_if_index);
10260   mp->enable_disable = enable_disable;
10261
10262   S (mp);
10263   W (ret);
10264   return ret;
10265 }
10266
10267 static int
10268 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10269 {
10270   unformat_input_t *i = vam->input;
10271   vl_api_l2tpv3_set_lookup_key_t *mp;
10272   u8 key = ~0;
10273   int ret;
10274
10275   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10276     {
10277       if (unformat (i, "lookup_v6_src"))
10278         key = L2T_LOOKUP_SRC_ADDRESS;
10279       else if (unformat (i, "lookup_v6_dst"))
10280         key = L2T_LOOKUP_DST_ADDRESS;
10281       else if (unformat (i, "lookup_session_id"))
10282         key = L2T_LOOKUP_SESSION_ID;
10283       else
10284         break;
10285     }
10286
10287   if (key == (u8) ~ 0)
10288     {
10289       errmsg ("l2tp session lookup key unset");
10290       return -99;
10291     }
10292
10293   M (L2TPV3_SET_LOOKUP_KEY, mp);
10294
10295   mp->key = key;
10296
10297   S (mp);
10298   W (ret);
10299   return ret;
10300 }
10301
10302 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10303   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10304 {
10305   vat_main_t *vam = &vat_main;
10306
10307   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10308          format_ip6_address, mp->our_address,
10309          format_ip6_address, mp->client_address,
10310          clib_net_to_host_u32 (mp->sw_if_index));
10311
10312   print (vam->ofp,
10313          "   local cookies %016llx %016llx remote cookie %016llx",
10314          clib_net_to_host_u64 (mp->local_cookie[0]),
10315          clib_net_to_host_u64 (mp->local_cookie[1]),
10316          clib_net_to_host_u64 (mp->remote_cookie));
10317
10318   print (vam->ofp, "   local session-id %d remote session-id %d",
10319          clib_net_to_host_u32 (mp->local_session_id),
10320          clib_net_to_host_u32 (mp->remote_session_id));
10321
10322   print (vam->ofp, "   l2 specific sublayer %s\n",
10323          mp->l2_sublayer_present ? "preset" : "absent");
10324
10325 }
10326
10327 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10328   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10329 {
10330   vat_main_t *vam = &vat_main;
10331   vat_json_node_t *node = NULL;
10332   struct in6_addr addr;
10333
10334   if (VAT_JSON_ARRAY != vam->json_tree.type)
10335     {
10336       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10337       vat_json_init_array (&vam->json_tree);
10338     }
10339   node = vat_json_array_add (&vam->json_tree);
10340
10341   vat_json_init_object (node);
10342
10343   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10344   vat_json_object_add_ip6 (node, "our_address", addr);
10345   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10346   vat_json_object_add_ip6 (node, "client_address", addr);
10347
10348   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10349   vat_json_init_array (lc);
10350   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10351   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10352   vat_json_object_add_uint (node, "remote_cookie",
10353                             clib_net_to_host_u64 (mp->remote_cookie));
10354
10355   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10356   vat_json_object_add_uint (node, "local_session_id",
10357                             clib_net_to_host_u32 (mp->local_session_id));
10358   vat_json_object_add_uint (node, "remote_session_id",
10359                             clib_net_to_host_u32 (mp->remote_session_id));
10360   vat_json_object_add_string_copy (node, "l2_sublayer",
10361                                    mp->l2_sublayer_present ? (u8 *) "present"
10362                                    : (u8 *) "absent");
10363 }
10364
10365 static int
10366 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10367 {
10368   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10369   vl_api_control_ping_t *mp_ping;
10370   int ret;
10371
10372   /* Get list of l2tpv3-tunnel interfaces */
10373   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
10374   S (mp);
10375
10376   /* Use a control ping for synchronization */
10377   M (CONTROL_PING, mp_ping);
10378   S (mp_ping);
10379
10380   W (ret);
10381   return ret;
10382 }
10383
10384
10385 static void vl_api_sw_interface_tap_details_t_handler
10386   (vl_api_sw_interface_tap_details_t * mp)
10387 {
10388   vat_main_t *vam = &vat_main;
10389
10390   print (vam->ofp, "%-16s %d",
10391          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10392 }
10393
10394 static void vl_api_sw_interface_tap_details_t_handler_json
10395   (vl_api_sw_interface_tap_details_t * mp)
10396 {
10397   vat_main_t *vam = &vat_main;
10398   vat_json_node_t *node = NULL;
10399
10400   if (VAT_JSON_ARRAY != vam->json_tree.type)
10401     {
10402       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10403       vat_json_init_array (&vam->json_tree);
10404     }
10405   node = vat_json_array_add (&vam->json_tree);
10406
10407   vat_json_init_object (node);
10408   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10409   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10410 }
10411
10412 static int
10413 api_sw_interface_tap_dump (vat_main_t * vam)
10414 {
10415   vl_api_sw_interface_tap_dump_t *mp;
10416   vl_api_control_ping_t *mp_ping;
10417   int ret;
10418
10419   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10420   /* Get list of tap interfaces */
10421   M (SW_INTERFACE_TAP_DUMP, mp);
10422   S (mp);
10423
10424   /* Use a control ping for synchronization */
10425   M (CONTROL_PING, mp_ping);
10426   S (mp_ping);
10427
10428   W (ret);
10429   return ret;
10430 }
10431
10432 static uword unformat_vxlan_decap_next
10433   (unformat_input_t * input, va_list * args)
10434 {
10435   u32 *result = va_arg (*args, u32 *);
10436   u32 tmp;
10437
10438   if (unformat (input, "l2"))
10439     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10440   else if (unformat (input, "%d", &tmp))
10441     *result = tmp;
10442   else
10443     return 0;
10444   return 1;
10445 }
10446
10447 static int
10448 api_vxlan_add_del_tunnel (vat_main_t * vam)
10449 {
10450   unformat_input_t *line_input = vam->input;
10451   vl_api_vxlan_add_del_tunnel_t *mp;
10452   ip46_address_t src, dst;
10453   u8 is_add = 1;
10454   u8 ipv4_set = 0, ipv6_set = 0;
10455   u8 src_set = 0;
10456   u8 dst_set = 0;
10457   u8 grp_set = 0;
10458   u32 mcast_sw_if_index = ~0;
10459   u32 encap_vrf_id = 0;
10460   u32 decap_next_index = ~0;
10461   u32 vni = 0;
10462   int ret;
10463
10464   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10465   memset (&src, 0, sizeof src);
10466   memset (&dst, 0, sizeof dst);
10467
10468   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10469     {
10470       if (unformat (line_input, "del"))
10471         is_add = 0;
10472       else
10473         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10474         {
10475           ipv4_set = 1;
10476           src_set = 1;
10477         }
10478       else
10479         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10480         {
10481           ipv4_set = 1;
10482           dst_set = 1;
10483         }
10484       else
10485         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10486         {
10487           ipv6_set = 1;
10488           src_set = 1;
10489         }
10490       else
10491         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10492         {
10493           ipv6_set = 1;
10494           dst_set = 1;
10495         }
10496       else if (unformat (line_input, "group %U %U",
10497                          unformat_ip4_address, &dst.ip4,
10498                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10499         {
10500           grp_set = dst_set = 1;
10501           ipv4_set = 1;
10502         }
10503       else if (unformat (line_input, "group %U",
10504                          unformat_ip4_address, &dst.ip4))
10505         {
10506           grp_set = dst_set = 1;
10507           ipv4_set = 1;
10508         }
10509       else if (unformat (line_input, "group %U %U",
10510                          unformat_ip6_address, &dst.ip6,
10511                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10512         {
10513           grp_set = dst_set = 1;
10514           ipv6_set = 1;
10515         }
10516       else if (unformat (line_input, "group %U",
10517                          unformat_ip6_address, &dst.ip6))
10518         {
10519           grp_set = dst_set = 1;
10520           ipv6_set = 1;
10521         }
10522       else
10523         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10524         ;
10525       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10526         ;
10527       else if (unformat (line_input, "decap-next %U",
10528                          unformat_vxlan_decap_next, &decap_next_index))
10529         ;
10530       else if (unformat (line_input, "vni %d", &vni))
10531         ;
10532       else
10533         {
10534           errmsg ("parse error '%U'", format_unformat_error, line_input);
10535           return -99;
10536         }
10537     }
10538
10539   if (src_set == 0)
10540     {
10541       errmsg ("tunnel src address not specified");
10542       return -99;
10543     }
10544   if (dst_set == 0)
10545     {
10546       errmsg ("tunnel dst address not specified");
10547       return -99;
10548     }
10549
10550   if (grp_set && !ip46_address_is_multicast (&dst))
10551     {
10552       errmsg ("tunnel group address not multicast");
10553       return -99;
10554     }
10555   if (grp_set && mcast_sw_if_index == ~0)
10556     {
10557       errmsg ("tunnel nonexistent multicast device");
10558       return -99;
10559     }
10560   if (grp_set == 0 && ip46_address_is_multicast (&dst))
10561     {
10562       errmsg ("tunnel dst address must be unicast");
10563       return -99;
10564     }
10565
10566
10567   if (ipv4_set && ipv6_set)
10568     {
10569       errmsg ("both IPv4 and IPv6 addresses specified");
10570       return -99;
10571     }
10572
10573   if ((vni == 0) || (vni >> 24))
10574     {
10575       errmsg ("vni not specified or out of range");
10576       return -99;
10577     }
10578
10579   M (VXLAN_ADD_DEL_TUNNEL, mp);
10580
10581   if (ipv6_set)
10582     {
10583       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10584       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10585     }
10586   else
10587     {
10588       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10589       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10590     }
10591   mp->encap_vrf_id = ntohl (encap_vrf_id);
10592   mp->decap_next_index = ntohl (decap_next_index);
10593   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10594   mp->vni = ntohl (vni);
10595   mp->is_add = is_add;
10596   mp->is_ipv6 = ipv6_set;
10597
10598   S (mp);
10599   W (ret);
10600   return ret;
10601 }
10602
10603 static void vl_api_vxlan_tunnel_details_t_handler
10604   (vl_api_vxlan_tunnel_details_t * mp)
10605 {
10606   vat_main_t *vam = &vat_main;
10607   ip46_address_t src, dst;
10608
10609   ip46_from_addr_buf (mp->is_ipv6, mp->src_address, &src);
10610   ip46_from_addr_buf (mp->is_ipv6, mp->dst_address, &dst);
10611
10612   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
10613          ntohl (mp->sw_if_index),
10614          format_ip46_address, &src, IP46_TYPE_ANY,
10615          format_ip46_address, &dst, IP46_TYPE_ANY,
10616          ntohl (mp->encap_vrf_id),
10617          ntohl (mp->decap_next_index), ntohl (mp->vni),
10618          ntohl (mp->mcast_sw_if_index));
10619 }
10620
10621 static void vl_api_vxlan_tunnel_details_t_handler_json
10622   (vl_api_vxlan_tunnel_details_t * mp)
10623 {
10624   vat_main_t *vam = &vat_main;
10625   vat_json_node_t *node = NULL;
10626
10627   if (VAT_JSON_ARRAY != vam->json_tree.type)
10628     {
10629       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10630       vat_json_init_array (&vam->json_tree);
10631     }
10632   node = vat_json_array_add (&vam->json_tree);
10633
10634   vat_json_init_object (node);
10635   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10636   if (mp->is_ipv6)
10637     {
10638       struct in6_addr ip6;
10639
10640       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10641       vat_json_object_add_ip6 (node, "src_address", ip6);
10642       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10643       vat_json_object_add_ip6 (node, "dst_address", ip6);
10644     }
10645   else
10646     {
10647       struct in_addr ip4;
10648
10649       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10650       vat_json_object_add_ip4 (node, "src_address", ip4);
10651       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10652       vat_json_object_add_ip4 (node, "dst_address", ip4);
10653     }
10654   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10655   vat_json_object_add_uint (node, "decap_next_index",
10656                             ntohl (mp->decap_next_index));
10657   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10658   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10659   vat_json_object_add_uint (node, "mcast_sw_if_index",
10660                             ntohl (mp->mcast_sw_if_index));
10661 }
10662
10663 static int
10664 api_vxlan_tunnel_dump (vat_main_t * vam)
10665 {
10666   unformat_input_t *i = vam->input;
10667   vl_api_vxlan_tunnel_dump_t *mp;
10668   vl_api_control_ping_t *mp_ping;
10669   u32 sw_if_index;
10670   u8 sw_if_index_set = 0;
10671   int ret;
10672
10673   /* Parse args required to build the message */
10674   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10675     {
10676       if (unformat (i, "sw_if_index %d", &sw_if_index))
10677         sw_if_index_set = 1;
10678       else
10679         break;
10680     }
10681
10682   if (sw_if_index_set == 0)
10683     {
10684       sw_if_index = ~0;
10685     }
10686
10687   if (!vam->json_output)
10688     {
10689       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
10690              "sw_if_index", "src_address", "dst_address",
10691              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
10692     }
10693
10694   /* Get list of vxlan-tunnel interfaces */
10695   M (VXLAN_TUNNEL_DUMP, mp);
10696
10697   mp->sw_if_index = htonl (sw_if_index);
10698
10699   S (mp);
10700
10701   /* Use a control ping for synchronization */
10702   M (CONTROL_PING, mp_ping);
10703   S (mp_ping);
10704
10705   W (ret);
10706   return ret;
10707 }
10708
10709 static int
10710 api_gre_add_del_tunnel (vat_main_t * vam)
10711 {
10712   unformat_input_t *line_input = vam->input;
10713   vl_api_gre_add_del_tunnel_t *mp;
10714   ip4_address_t src4, dst4;
10715   u8 is_add = 1;
10716   u8 teb = 0;
10717   u8 src_set = 0;
10718   u8 dst_set = 0;
10719   u32 outer_fib_id = 0;
10720   int ret;
10721
10722   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10723     {
10724       if (unformat (line_input, "del"))
10725         is_add = 0;
10726       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10727         src_set = 1;
10728       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10729         dst_set = 1;
10730       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10731         ;
10732       else if (unformat (line_input, "teb"))
10733         teb = 1;
10734       else
10735         {
10736           errmsg ("parse error '%U'", format_unformat_error, line_input);
10737           return -99;
10738         }
10739     }
10740
10741   if (src_set == 0)
10742     {
10743       errmsg ("tunnel src address not specified");
10744       return -99;
10745     }
10746   if (dst_set == 0)
10747     {
10748       errmsg ("tunnel dst address not specified");
10749       return -99;
10750     }
10751
10752
10753   M (GRE_ADD_DEL_TUNNEL, mp);
10754
10755   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10756   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10757   mp->outer_fib_id = ntohl (outer_fib_id);
10758   mp->is_add = is_add;
10759   mp->teb = teb;
10760
10761   S (mp);
10762   W (ret);
10763   return ret;
10764 }
10765
10766 static void vl_api_gre_tunnel_details_t_handler
10767   (vl_api_gre_tunnel_details_t * mp)
10768 {
10769   vat_main_t *vam = &vat_main;
10770
10771   print (vam->ofp, "%11d%15U%15U%6d%14d",
10772          ntohl (mp->sw_if_index),
10773          format_ip4_address, &mp->src_address,
10774          format_ip4_address, &mp->dst_address,
10775          mp->teb, ntohl (mp->outer_fib_id));
10776 }
10777
10778 static void vl_api_gre_tunnel_details_t_handler_json
10779   (vl_api_gre_tunnel_details_t * mp)
10780 {
10781   vat_main_t *vam = &vat_main;
10782   vat_json_node_t *node = NULL;
10783   struct in_addr ip4;
10784
10785   if (VAT_JSON_ARRAY != vam->json_tree.type)
10786     {
10787       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10788       vat_json_init_array (&vam->json_tree);
10789     }
10790   node = vat_json_array_add (&vam->json_tree);
10791
10792   vat_json_init_object (node);
10793   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10794   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10795   vat_json_object_add_ip4 (node, "src_address", ip4);
10796   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10797   vat_json_object_add_ip4 (node, "dst_address", ip4);
10798   vat_json_object_add_uint (node, "teb", mp->teb);
10799   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10800 }
10801
10802 static int
10803 api_gre_tunnel_dump (vat_main_t * vam)
10804 {
10805   unformat_input_t *i = vam->input;
10806   vl_api_gre_tunnel_dump_t *mp;
10807   vl_api_control_ping_t *mp_ping;
10808   u32 sw_if_index;
10809   u8 sw_if_index_set = 0;
10810   int ret;
10811
10812   /* Parse args required to build the message */
10813   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10814     {
10815       if (unformat (i, "sw_if_index %d", &sw_if_index))
10816         sw_if_index_set = 1;
10817       else
10818         break;
10819     }
10820
10821   if (sw_if_index_set == 0)
10822     {
10823       sw_if_index = ~0;
10824     }
10825
10826   if (!vam->json_output)
10827     {
10828       print (vam->ofp, "%11s%15s%15s%6s%14s",
10829              "sw_if_index", "src_address", "dst_address", "teb",
10830              "outer_fib_id");
10831     }
10832
10833   /* Get list of gre-tunnel interfaces */
10834   M (GRE_TUNNEL_DUMP, mp);
10835
10836   mp->sw_if_index = htonl (sw_if_index);
10837
10838   S (mp);
10839
10840   /* Use a control ping for synchronization */
10841   M (CONTROL_PING, mp_ping);
10842   S (mp_ping);
10843
10844   W (ret);
10845   return ret;
10846 }
10847
10848 static int
10849 api_l2_fib_clear_table (vat_main_t * vam)
10850 {
10851 //  unformat_input_t * i = vam->input;
10852   vl_api_l2_fib_clear_table_t *mp;
10853   int ret;
10854
10855   M (L2_FIB_CLEAR_TABLE, mp);
10856
10857   S (mp);
10858   W (ret);
10859   return ret;
10860 }
10861
10862 static int
10863 api_l2_interface_efp_filter (vat_main_t * vam)
10864 {
10865   unformat_input_t *i = vam->input;
10866   vl_api_l2_interface_efp_filter_t *mp;
10867   u32 sw_if_index;
10868   u8 enable = 1;
10869   u8 sw_if_index_set = 0;
10870   int ret;
10871
10872   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10873     {
10874       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10875         sw_if_index_set = 1;
10876       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10877         sw_if_index_set = 1;
10878       else if (unformat (i, "enable"))
10879         enable = 1;
10880       else if (unformat (i, "disable"))
10881         enable = 0;
10882       else
10883         {
10884           clib_warning ("parse error '%U'", format_unformat_error, i);
10885           return -99;
10886         }
10887     }
10888
10889   if (sw_if_index_set == 0)
10890     {
10891       errmsg ("missing sw_if_index");
10892       return -99;
10893     }
10894
10895   M (L2_INTERFACE_EFP_FILTER, mp);
10896
10897   mp->sw_if_index = ntohl (sw_if_index);
10898   mp->enable_disable = enable;
10899
10900   S (mp);
10901   W (ret);
10902   return ret;
10903 }
10904
10905 #define foreach_vtr_op                          \
10906 _("disable",  L2_VTR_DISABLED)                  \
10907 _("push-1",  L2_VTR_PUSH_1)                     \
10908 _("push-2",  L2_VTR_PUSH_2)                     \
10909 _("pop-1",  L2_VTR_POP_1)                       \
10910 _("pop-2",  L2_VTR_POP_2)                       \
10911 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10912 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10913 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10914 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10915
10916 static int
10917 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10918 {
10919   unformat_input_t *i = vam->input;
10920   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10921   u32 sw_if_index;
10922   u8 sw_if_index_set = 0;
10923   u8 vtr_op_set = 0;
10924   u32 vtr_op = 0;
10925   u32 push_dot1q = 1;
10926   u32 tag1 = ~0;
10927   u32 tag2 = ~0;
10928   int ret;
10929
10930   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10931     {
10932       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10933         sw_if_index_set = 1;
10934       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10935         sw_if_index_set = 1;
10936       else if (unformat (i, "vtr_op %d", &vtr_op))
10937         vtr_op_set = 1;
10938 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
10939       foreach_vtr_op
10940 #undef _
10941         else if (unformat (i, "push_dot1q %d", &push_dot1q))
10942         ;
10943       else if (unformat (i, "tag1 %d", &tag1))
10944         ;
10945       else if (unformat (i, "tag2 %d", &tag2))
10946         ;
10947       else
10948         {
10949           clib_warning ("parse error '%U'", format_unformat_error, i);
10950           return -99;
10951         }
10952     }
10953
10954   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
10955     {
10956       errmsg ("missing vtr operation or sw_if_index");
10957       return -99;
10958     }
10959
10960   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
10961   mp->sw_if_index = ntohl (sw_if_index);
10962   mp->vtr_op = ntohl (vtr_op);
10963   mp->push_dot1q = ntohl (push_dot1q);
10964   mp->tag1 = ntohl (tag1);
10965   mp->tag2 = ntohl (tag2);
10966
10967   S (mp);
10968   W (ret);
10969   return ret;
10970 }
10971
10972 static int
10973 api_create_vhost_user_if (vat_main_t * vam)
10974 {
10975   unformat_input_t *i = vam->input;
10976   vl_api_create_vhost_user_if_t *mp;
10977   u8 *file_name;
10978   u8 is_server = 0;
10979   u8 file_name_set = 0;
10980   u32 custom_dev_instance = ~0;
10981   u8 hwaddr[6];
10982   u8 use_custom_mac = 0;
10983   u8 *tag = 0;
10984   int ret;
10985
10986   /* Shut up coverity */
10987   memset (hwaddr, 0, sizeof (hwaddr));
10988
10989   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10990     {
10991       if (unformat (i, "socket %s", &file_name))
10992         {
10993           file_name_set = 1;
10994         }
10995       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10996         ;
10997       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10998         use_custom_mac = 1;
10999       else if (unformat (i, "server"))
11000         is_server = 1;
11001       else if (unformat (i, "tag %s", &tag))
11002         ;
11003       else
11004         break;
11005     }
11006
11007   if (file_name_set == 0)
11008     {
11009       errmsg ("missing socket file name");
11010       return -99;
11011     }
11012
11013   if (vec_len (file_name) > 255)
11014     {
11015       errmsg ("socket file name too long");
11016       return -99;
11017     }
11018   vec_add1 (file_name, 0);
11019
11020   M (CREATE_VHOST_USER_IF, mp);
11021
11022   mp->is_server = is_server;
11023   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11024   vec_free (file_name);
11025   if (custom_dev_instance != ~0)
11026     {
11027       mp->renumber = 1;
11028       mp->custom_dev_instance = ntohl (custom_dev_instance);
11029     }
11030   mp->use_custom_mac = use_custom_mac;
11031   clib_memcpy (mp->mac_address, hwaddr, 6);
11032   if (tag)
11033     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
11034   vec_free (tag);
11035
11036   S (mp);
11037   W (ret);
11038   return ret;
11039 }
11040
11041 static int
11042 api_modify_vhost_user_if (vat_main_t * vam)
11043 {
11044   unformat_input_t *i = vam->input;
11045   vl_api_modify_vhost_user_if_t *mp;
11046   u8 *file_name;
11047   u8 is_server = 0;
11048   u8 file_name_set = 0;
11049   u32 custom_dev_instance = ~0;
11050   u8 sw_if_index_set = 0;
11051   u32 sw_if_index = (u32) ~ 0;
11052   int ret;
11053
11054   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11055     {
11056       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11057         sw_if_index_set = 1;
11058       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11059         sw_if_index_set = 1;
11060       else if (unformat (i, "socket %s", &file_name))
11061         {
11062           file_name_set = 1;
11063         }
11064       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11065         ;
11066       else if (unformat (i, "server"))
11067         is_server = 1;
11068       else
11069         break;
11070     }
11071
11072   if (sw_if_index_set == 0)
11073     {
11074       errmsg ("missing sw_if_index or interface name");
11075       return -99;
11076     }
11077
11078   if (file_name_set == 0)
11079     {
11080       errmsg ("missing socket file name");
11081       return -99;
11082     }
11083
11084   if (vec_len (file_name) > 255)
11085     {
11086       errmsg ("socket file name too long");
11087       return -99;
11088     }
11089   vec_add1 (file_name, 0);
11090
11091   M (MODIFY_VHOST_USER_IF, mp);
11092
11093   mp->sw_if_index = ntohl (sw_if_index);
11094   mp->is_server = is_server;
11095   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11096   vec_free (file_name);
11097   if (custom_dev_instance != ~0)
11098     {
11099       mp->renumber = 1;
11100       mp->custom_dev_instance = ntohl (custom_dev_instance);
11101     }
11102
11103   S (mp);
11104   W (ret);
11105   return ret;
11106 }
11107
11108 static int
11109 api_delete_vhost_user_if (vat_main_t * vam)
11110 {
11111   unformat_input_t *i = vam->input;
11112   vl_api_delete_vhost_user_if_t *mp;
11113   u32 sw_if_index = ~0;
11114   u8 sw_if_index_set = 0;
11115   int ret;
11116
11117   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11118     {
11119       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11120         sw_if_index_set = 1;
11121       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11122         sw_if_index_set = 1;
11123       else
11124         break;
11125     }
11126
11127   if (sw_if_index_set == 0)
11128     {
11129       errmsg ("missing sw_if_index or interface name");
11130       return -99;
11131     }
11132
11133
11134   M (DELETE_VHOST_USER_IF, mp);
11135
11136   mp->sw_if_index = ntohl (sw_if_index);
11137
11138   S (mp);
11139   W (ret);
11140   return ret;
11141 }
11142
11143 static void vl_api_sw_interface_vhost_user_details_t_handler
11144   (vl_api_sw_interface_vhost_user_details_t * mp)
11145 {
11146   vat_main_t *vam = &vat_main;
11147
11148   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
11149          (char *) mp->interface_name,
11150          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11151          clib_net_to_host_u64 (mp->features), mp->is_server,
11152          ntohl (mp->num_regions), (char *) mp->sock_filename);
11153   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
11154 }
11155
11156 static void vl_api_sw_interface_vhost_user_details_t_handler_json
11157   (vl_api_sw_interface_vhost_user_details_t * mp)
11158 {
11159   vat_main_t *vam = &vat_main;
11160   vat_json_node_t *node = NULL;
11161
11162   if (VAT_JSON_ARRAY != vam->json_tree.type)
11163     {
11164       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11165       vat_json_init_array (&vam->json_tree);
11166     }
11167   node = vat_json_array_add (&vam->json_tree);
11168
11169   vat_json_init_object (node);
11170   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11171   vat_json_object_add_string_copy (node, "interface_name",
11172                                    mp->interface_name);
11173   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11174                             ntohl (mp->virtio_net_hdr_sz));
11175   vat_json_object_add_uint (node, "features",
11176                             clib_net_to_host_u64 (mp->features));
11177   vat_json_object_add_uint (node, "is_server", mp->is_server);
11178   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11179   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11180   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11181 }
11182
11183 static int
11184 api_sw_interface_vhost_user_dump (vat_main_t * vam)
11185 {
11186   vl_api_sw_interface_vhost_user_dump_t *mp;
11187   vl_api_control_ping_t *mp_ping;
11188   int ret;
11189   print (vam->ofp,
11190          "Interface name           idx hdr_sz features server regions filename");
11191
11192   /* Get list of vhost-user interfaces */
11193   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
11194   S (mp);
11195
11196   /* Use a control ping for synchronization */
11197   M (CONTROL_PING, mp_ping);
11198   S (mp_ping);
11199
11200   W (ret);
11201   return ret;
11202 }
11203
11204 static int
11205 api_show_version (vat_main_t * vam)
11206 {
11207   vl_api_show_version_t *mp;
11208   int ret;
11209
11210   M (SHOW_VERSION, mp);
11211
11212   S (mp);
11213   W (ret);
11214   return ret;
11215 }
11216
11217
11218 static int
11219 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11220 {
11221   unformat_input_t *line_input = vam->input;
11222   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11223   ip4_address_t local4, remote4;
11224   ip6_address_t local6, remote6;
11225   u8 is_add = 1;
11226   u8 ipv4_set = 0, ipv6_set = 0;
11227   u8 local_set = 0;
11228   u8 remote_set = 0;
11229   u32 encap_vrf_id = 0;
11230   u32 decap_vrf_id = 0;
11231   u8 protocol = ~0;
11232   u32 vni;
11233   u8 vni_set = 0;
11234   int ret;
11235
11236   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11237     {
11238       if (unformat (line_input, "del"))
11239         is_add = 0;
11240       else if (unformat (line_input, "local %U",
11241                          unformat_ip4_address, &local4))
11242         {
11243           local_set = 1;
11244           ipv4_set = 1;
11245         }
11246       else if (unformat (line_input, "remote %U",
11247                          unformat_ip4_address, &remote4))
11248         {
11249           remote_set = 1;
11250           ipv4_set = 1;
11251         }
11252       else if (unformat (line_input, "local %U",
11253                          unformat_ip6_address, &local6))
11254         {
11255           local_set = 1;
11256           ipv6_set = 1;
11257         }
11258       else if (unformat (line_input, "remote %U",
11259                          unformat_ip6_address, &remote6))
11260         {
11261           remote_set = 1;
11262           ipv6_set = 1;
11263         }
11264       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11265         ;
11266       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11267         ;
11268       else if (unformat (line_input, "vni %d", &vni))
11269         vni_set = 1;
11270       else if (unformat (line_input, "next-ip4"))
11271         protocol = 1;
11272       else if (unformat (line_input, "next-ip6"))
11273         protocol = 2;
11274       else if (unformat (line_input, "next-ethernet"))
11275         protocol = 3;
11276       else if (unformat (line_input, "next-nsh"))
11277         protocol = 4;
11278       else
11279         {
11280           errmsg ("parse error '%U'", format_unformat_error, line_input);
11281           return -99;
11282         }
11283     }
11284
11285   if (local_set == 0)
11286     {
11287       errmsg ("tunnel local address not specified");
11288       return -99;
11289     }
11290   if (remote_set == 0)
11291     {
11292       errmsg ("tunnel remote address not specified");
11293       return -99;
11294     }
11295   if (ipv4_set && ipv6_set)
11296     {
11297       errmsg ("both IPv4 and IPv6 addresses specified");
11298       return -99;
11299     }
11300
11301   if (vni_set == 0)
11302     {
11303       errmsg ("vni not specified");
11304       return -99;
11305     }
11306
11307   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
11308
11309
11310   if (ipv6_set)
11311     {
11312       clib_memcpy (&mp->local, &local6, sizeof (local6));
11313       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11314     }
11315   else
11316     {
11317       clib_memcpy (&mp->local, &local4, sizeof (local4));
11318       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11319     }
11320
11321   mp->encap_vrf_id = ntohl (encap_vrf_id);
11322   mp->decap_vrf_id = ntohl (decap_vrf_id);
11323   mp->protocol = protocol;
11324   mp->vni = ntohl (vni);
11325   mp->is_add = is_add;
11326   mp->is_ipv6 = ipv6_set;
11327
11328   S (mp);
11329   W (ret);
11330   return ret;
11331 }
11332
11333 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11334   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11335 {
11336   vat_main_t *vam = &vat_main;
11337
11338   print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11339          ntohl (mp->sw_if_index),
11340          format_ip46_address, &(mp->local[0]),
11341          format_ip46_address, &(mp->remote[0]),
11342          ntohl (mp->vni),
11343          ntohl (mp->protocol),
11344          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11345 }
11346
11347 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11348   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11349 {
11350   vat_main_t *vam = &vat_main;
11351   vat_json_node_t *node = NULL;
11352   struct in_addr ip4;
11353   struct in6_addr ip6;
11354
11355   if (VAT_JSON_ARRAY != vam->json_tree.type)
11356     {
11357       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11358       vat_json_init_array (&vam->json_tree);
11359     }
11360   node = vat_json_array_add (&vam->json_tree);
11361
11362   vat_json_init_object (node);
11363   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11364   if (mp->is_ipv6)
11365     {
11366       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11367       vat_json_object_add_ip6 (node, "local", ip6);
11368       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11369       vat_json_object_add_ip6 (node, "remote", ip6);
11370     }
11371   else
11372     {
11373       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11374       vat_json_object_add_ip4 (node, "local", ip4);
11375       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11376       vat_json_object_add_ip4 (node, "remote", ip4);
11377     }
11378   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11379   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11380   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11381   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11382   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11383 }
11384
11385 static int
11386 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11387 {
11388   unformat_input_t *i = vam->input;
11389   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11390   vl_api_control_ping_t *mp_ping;
11391   u32 sw_if_index;
11392   u8 sw_if_index_set = 0;
11393   int ret;
11394
11395   /* Parse args required to build the message */
11396   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11397     {
11398       if (unformat (i, "sw_if_index %d", &sw_if_index))
11399         sw_if_index_set = 1;
11400       else
11401         break;
11402     }
11403
11404   if (sw_if_index_set == 0)
11405     {
11406       sw_if_index = ~0;
11407     }
11408
11409   if (!vam->json_output)
11410     {
11411       print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11412              "sw_if_index", "local", "remote", "vni",
11413              "protocol", "encap_vrf_id", "decap_vrf_id");
11414     }
11415
11416   /* Get list of vxlan-tunnel interfaces */
11417   M (VXLAN_GPE_TUNNEL_DUMP, mp);
11418
11419   mp->sw_if_index = htonl (sw_if_index);
11420
11421   S (mp);
11422
11423   /* Use a control ping for synchronization */
11424   M (CONTROL_PING, mp_ping);
11425   S (mp_ping);
11426
11427   W (ret);
11428   return ret;
11429 }
11430
11431 u8 *
11432 format_l2_fib_mac_address (u8 * s, va_list * args)
11433 {
11434   u8 *a = va_arg (*args, u8 *);
11435
11436   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11437                  a[2], a[3], a[4], a[5], a[6], a[7]);
11438 }
11439
11440 static void vl_api_l2_fib_table_entry_t_handler
11441   (vl_api_l2_fib_table_entry_t * mp)
11442 {
11443   vat_main_t *vam = &vat_main;
11444
11445   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11446          "       %d       %d     %d",
11447          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11448          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11449          mp->bvi_mac);
11450 }
11451
11452 static void vl_api_l2_fib_table_entry_t_handler_json
11453   (vl_api_l2_fib_table_entry_t * mp)
11454 {
11455   vat_main_t *vam = &vat_main;
11456   vat_json_node_t *node = NULL;
11457
11458   if (VAT_JSON_ARRAY != vam->json_tree.type)
11459     {
11460       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11461       vat_json_init_array (&vam->json_tree);
11462     }
11463   node = vat_json_array_add (&vam->json_tree);
11464
11465   vat_json_init_object (node);
11466   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11467   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11468   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11469   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11470   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11471   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11472 }
11473
11474 static int
11475 api_l2_fib_table_dump (vat_main_t * vam)
11476 {
11477   unformat_input_t *i = vam->input;
11478   vl_api_l2_fib_table_dump_t *mp;
11479   vl_api_control_ping_t *mp_ping;
11480   u32 bd_id;
11481   u8 bd_id_set = 0;
11482   int ret;
11483
11484   /* Parse args required to build the message */
11485   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11486     {
11487       if (unformat (i, "bd_id %d", &bd_id))
11488         bd_id_set = 1;
11489       else
11490         break;
11491     }
11492
11493   if (bd_id_set == 0)
11494     {
11495       errmsg ("missing bridge domain");
11496       return -99;
11497     }
11498
11499   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
11500
11501   /* Get list of l2 fib entries */
11502   M (L2_FIB_TABLE_DUMP, mp);
11503
11504   mp->bd_id = ntohl (bd_id);
11505   S (mp);
11506
11507   /* Use a control ping for synchronization */
11508   M (CONTROL_PING, mp_ping);
11509   S (mp_ping);
11510
11511   W (ret);
11512   return ret;
11513 }
11514
11515
11516 static int
11517 api_interface_name_renumber (vat_main_t * vam)
11518 {
11519   unformat_input_t *line_input = vam->input;
11520   vl_api_interface_name_renumber_t *mp;
11521   u32 sw_if_index = ~0;
11522   u32 new_show_dev_instance = ~0;
11523   int ret;
11524
11525   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11526     {
11527       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
11528                     &sw_if_index))
11529         ;
11530       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11531         ;
11532       else if (unformat (line_input, "new_show_dev_instance %d",
11533                          &new_show_dev_instance))
11534         ;
11535       else
11536         break;
11537     }
11538
11539   if (sw_if_index == ~0)
11540     {
11541       errmsg ("missing interface name or sw_if_index");
11542       return -99;
11543     }
11544
11545   if (new_show_dev_instance == ~0)
11546     {
11547       errmsg ("missing new_show_dev_instance");
11548       return -99;
11549     }
11550
11551   M (INTERFACE_NAME_RENUMBER, mp);
11552
11553   mp->sw_if_index = ntohl (sw_if_index);
11554   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11555
11556   S (mp);
11557   W (ret);
11558   return ret;
11559 }
11560
11561 static int
11562 api_want_ip4_arp_events (vat_main_t * vam)
11563 {
11564   unformat_input_t *line_input = vam->input;
11565   vl_api_want_ip4_arp_events_t *mp;
11566   ip4_address_t address;
11567   int address_set = 0;
11568   u32 enable_disable = 1;
11569   int ret;
11570
11571   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11572     {
11573       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11574         address_set = 1;
11575       else if (unformat (line_input, "del"))
11576         enable_disable = 0;
11577       else
11578         break;
11579     }
11580
11581   if (address_set == 0)
11582     {
11583       errmsg ("missing addresses");
11584       return -99;
11585     }
11586
11587   M (WANT_IP4_ARP_EVENTS, mp);
11588   mp->enable_disable = enable_disable;
11589   mp->pid = getpid ();
11590   mp->address = address.as_u32;
11591
11592   S (mp);
11593   W (ret);
11594   return ret;
11595 }
11596
11597 static int
11598 api_want_ip6_nd_events (vat_main_t * vam)
11599 {
11600   unformat_input_t *line_input = vam->input;
11601   vl_api_want_ip6_nd_events_t *mp;
11602   ip6_address_t address;
11603   int address_set = 0;
11604   u32 enable_disable = 1;
11605   int ret;
11606
11607   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11608     {
11609       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11610         address_set = 1;
11611       else if (unformat (line_input, "del"))
11612         enable_disable = 0;
11613       else
11614         break;
11615     }
11616
11617   if (address_set == 0)
11618     {
11619       errmsg ("missing addresses");
11620       return -99;
11621     }
11622
11623   M (WANT_IP6_ND_EVENTS, mp);
11624   mp->enable_disable = enable_disable;
11625   mp->pid = getpid ();
11626   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11627
11628   S (mp);
11629   W (ret);
11630   return ret;
11631 }
11632
11633 static int
11634 api_input_acl_set_interface (vat_main_t * vam)
11635 {
11636   unformat_input_t *i = vam->input;
11637   vl_api_input_acl_set_interface_t *mp;
11638   u32 sw_if_index;
11639   int sw_if_index_set;
11640   u32 ip4_table_index = ~0;
11641   u32 ip6_table_index = ~0;
11642   u32 l2_table_index = ~0;
11643   u8 is_add = 1;
11644   int ret;
11645
11646   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11647     {
11648       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11649         sw_if_index_set = 1;
11650       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11651         sw_if_index_set = 1;
11652       else if (unformat (i, "del"))
11653         is_add = 0;
11654       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11655         ;
11656       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11657         ;
11658       else if (unformat (i, "l2-table %d", &l2_table_index))
11659         ;
11660       else
11661         {
11662           clib_warning ("parse error '%U'", format_unformat_error, i);
11663           return -99;
11664         }
11665     }
11666
11667   if (sw_if_index_set == 0)
11668     {
11669       errmsg ("missing interface name or sw_if_index");
11670       return -99;
11671     }
11672
11673   M (INPUT_ACL_SET_INTERFACE, mp);
11674
11675   mp->sw_if_index = ntohl (sw_if_index);
11676   mp->ip4_table_index = ntohl (ip4_table_index);
11677   mp->ip6_table_index = ntohl (ip6_table_index);
11678   mp->l2_table_index = ntohl (l2_table_index);
11679   mp->is_add = is_add;
11680
11681   S (mp);
11682   W (ret);
11683   return ret;
11684 }
11685
11686 static int
11687 api_ip_address_dump (vat_main_t * vam)
11688 {
11689   unformat_input_t *i = vam->input;
11690   vl_api_ip_address_dump_t *mp;
11691   vl_api_control_ping_t *mp_ping;
11692   u32 sw_if_index = ~0;
11693   u8 sw_if_index_set = 0;
11694   u8 ipv4_set = 0;
11695   u8 ipv6_set = 0;
11696   int ret;
11697
11698   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11699     {
11700       if (unformat (i, "sw_if_index %d", &sw_if_index))
11701         sw_if_index_set = 1;
11702       else
11703         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11704         sw_if_index_set = 1;
11705       else if (unformat (i, "ipv4"))
11706         ipv4_set = 1;
11707       else if (unformat (i, "ipv6"))
11708         ipv6_set = 1;
11709       else
11710         break;
11711     }
11712
11713   if (ipv4_set && ipv6_set)
11714     {
11715       errmsg ("ipv4 and ipv6 flags cannot be both set");
11716       return -99;
11717     }
11718
11719   if ((!ipv4_set) && (!ipv6_set))
11720     {
11721       errmsg ("no ipv4 nor ipv6 flag set");
11722       return -99;
11723     }
11724
11725   if (sw_if_index_set == 0)
11726     {
11727       errmsg ("missing interface name or sw_if_index");
11728       return -99;
11729     }
11730
11731   vam->current_sw_if_index = sw_if_index;
11732   vam->is_ipv6 = ipv6_set;
11733
11734   M (IP_ADDRESS_DUMP, mp);
11735   mp->sw_if_index = ntohl (sw_if_index);
11736   mp->is_ipv6 = ipv6_set;
11737   S (mp);
11738
11739   /* Use a control ping for synchronization */
11740   M (CONTROL_PING, mp_ping);
11741   S (mp_ping);
11742
11743   W (ret);
11744   return ret;
11745 }
11746
11747 static int
11748 api_ip_dump (vat_main_t * vam)
11749 {
11750   vl_api_ip_dump_t *mp;
11751   vl_api_control_ping_t *mp_ping;
11752   unformat_input_t *in = vam->input;
11753   int ipv4_set = 0;
11754   int ipv6_set = 0;
11755   int is_ipv6;
11756   int i;
11757   int ret;
11758
11759   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11760     {
11761       if (unformat (in, "ipv4"))
11762         ipv4_set = 1;
11763       else if (unformat (in, "ipv6"))
11764         ipv6_set = 1;
11765       else
11766         break;
11767     }
11768
11769   if (ipv4_set && ipv6_set)
11770     {
11771       errmsg ("ipv4 and ipv6 flags cannot be both set");
11772       return -99;
11773     }
11774
11775   if ((!ipv4_set) && (!ipv6_set))
11776     {
11777       errmsg ("no ipv4 nor ipv6 flag set");
11778       return -99;
11779     }
11780
11781   is_ipv6 = ipv6_set;
11782   vam->is_ipv6 = is_ipv6;
11783
11784   /* free old data */
11785   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11786     {
11787       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11788     }
11789   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11790
11791   M (IP_DUMP, mp);
11792   mp->is_ipv6 = ipv6_set;
11793   S (mp);
11794
11795   /* Use a control ping for synchronization */
11796   M (CONTROL_PING, mp_ping);
11797   S (mp_ping);
11798
11799   W (ret);
11800   return ret;
11801 }
11802
11803 static int
11804 api_ipsec_spd_add_del (vat_main_t * vam)
11805 {
11806   unformat_input_t *i = vam->input;
11807   vl_api_ipsec_spd_add_del_t *mp;
11808   u32 spd_id = ~0;
11809   u8 is_add = 1;
11810   int ret;
11811
11812   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11813     {
11814       if (unformat (i, "spd_id %d", &spd_id))
11815         ;
11816       else if (unformat (i, "del"))
11817         is_add = 0;
11818       else
11819         {
11820           clib_warning ("parse error '%U'", format_unformat_error, i);
11821           return -99;
11822         }
11823     }
11824   if (spd_id == ~0)
11825     {
11826       errmsg ("spd_id must be set");
11827       return -99;
11828     }
11829
11830   M (IPSEC_SPD_ADD_DEL, mp);
11831
11832   mp->spd_id = ntohl (spd_id);
11833   mp->is_add = is_add;
11834
11835   S (mp);
11836   W (ret);
11837   return ret;
11838 }
11839
11840 static int
11841 api_ipsec_interface_add_del_spd (vat_main_t * vam)
11842 {
11843   unformat_input_t *i = vam->input;
11844   vl_api_ipsec_interface_add_del_spd_t *mp;
11845   u32 sw_if_index;
11846   u8 sw_if_index_set = 0;
11847   u32 spd_id = (u32) ~ 0;
11848   u8 is_add = 1;
11849   int ret;
11850
11851   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11852     {
11853       if (unformat (i, "del"))
11854         is_add = 0;
11855       else if (unformat (i, "spd_id %d", &spd_id))
11856         ;
11857       else
11858         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11859         sw_if_index_set = 1;
11860       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11861         sw_if_index_set = 1;
11862       else
11863         {
11864           clib_warning ("parse error '%U'", format_unformat_error, i);
11865           return -99;
11866         }
11867
11868     }
11869
11870   if (spd_id == (u32) ~ 0)
11871     {
11872       errmsg ("spd_id must be set");
11873       return -99;
11874     }
11875
11876   if (sw_if_index_set == 0)
11877     {
11878       errmsg ("missing interface name or sw_if_index");
11879       return -99;
11880     }
11881
11882   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
11883
11884   mp->spd_id = ntohl (spd_id);
11885   mp->sw_if_index = ntohl (sw_if_index);
11886   mp->is_add = is_add;
11887
11888   S (mp);
11889   W (ret);
11890   return ret;
11891 }
11892
11893 static int
11894 api_ipsec_spd_add_del_entry (vat_main_t * vam)
11895 {
11896   unformat_input_t *i = vam->input;
11897   vl_api_ipsec_spd_add_del_entry_t *mp;
11898   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11899   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11900   i32 priority = 0;
11901   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11902   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11903   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11904   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11905   int ret;
11906
11907   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11908   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11909   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11910   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11911   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11912   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11913
11914   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11915     {
11916       if (unformat (i, "del"))
11917         is_add = 0;
11918       if (unformat (i, "outbound"))
11919         is_outbound = 1;
11920       if (unformat (i, "inbound"))
11921         is_outbound = 0;
11922       else if (unformat (i, "spd_id %d", &spd_id))
11923         ;
11924       else if (unformat (i, "sa_id %d", &sa_id))
11925         ;
11926       else if (unformat (i, "priority %d", &priority))
11927         ;
11928       else if (unformat (i, "protocol %d", &protocol))
11929         ;
11930       else if (unformat (i, "lport_start %d", &lport_start))
11931         ;
11932       else if (unformat (i, "lport_stop %d", &lport_stop))
11933         ;
11934       else if (unformat (i, "rport_start %d", &rport_start))
11935         ;
11936       else if (unformat (i, "rport_stop %d", &rport_stop))
11937         ;
11938       else
11939         if (unformat
11940             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
11941         {
11942           is_ipv6 = 0;
11943           is_ip_any = 0;
11944         }
11945       else
11946         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
11947         {
11948           is_ipv6 = 0;
11949           is_ip_any = 0;
11950         }
11951       else
11952         if (unformat
11953             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
11954         {
11955           is_ipv6 = 0;
11956           is_ip_any = 0;
11957         }
11958       else
11959         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11960         {
11961           is_ipv6 = 0;
11962           is_ip_any = 0;
11963         }
11964       else
11965         if (unformat
11966             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11967         {
11968           is_ipv6 = 1;
11969           is_ip_any = 0;
11970         }
11971       else
11972         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11973         {
11974           is_ipv6 = 1;
11975           is_ip_any = 0;
11976         }
11977       else
11978         if (unformat
11979             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11980         {
11981           is_ipv6 = 1;
11982           is_ip_any = 0;
11983         }
11984       else
11985         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11986         {
11987           is_ipv6 = 1;
11988           is_ip_any = 0;
11989         }
11990       else
11991         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11992         {
11993           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11994             {
11995               clib_warning ("unsupported action: 'resolve'");
11996               return -99;
11997             }
11998         }
11999       else
12000         {
12001           clib_warning ("parse error '%U'", format_unformat_error, i);
12002           return -99;
12003         }
12004
12005     }
12006
12007   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
12008
12009   mp->spd_id = ntohl (spd_id);
12010   mp->priority = ntohl (priority);
12011   mp->is_outbound = is_outbound;
12012
12013   mp->is_ipv6 = is_ipv6;
12014   if (is_ipv6 || is_ip_any)
12015     {
12016       clib_memcpy (mp->remote_address_start, &raddr6_start,
12017                    sizeof (ip6_address_t));
12018       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
12019                    sizeof (ip6_address_t));
12020       clib_memcpy (mp->local_address_start, &laddr6_start,
12021                    sizeof (ip6_address_t));
12022       clib_memcpy (mp->local_address_stop, &laddr6_stop,
12023                    sizeof (ip6_address_t));
12024     }
12025   else
12026     {
12027       clib_memcpy (mp->remote_address_start, &raddr4_start,
12028                    sizeof (ip4_address_t));
12029       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
12030                    sizeof (ip4_address_t));
12031       clib_memcpy (mp->local_address_start, &laddr4_start,
12032                    sizeof (ip4_address_t));
12033       clib_memcpy (mp->local_address_stop, &laddr4_stop,
12034                    sizeof (ip4_address_t));
12035     }
12036   mp->protocol = (u8) protocol;
12037   mp->local_port_start = ntohs ((u16) lport_start);
12038   mp->local_port_stop = ntohs ((u16) lport_stop);
12039   mp->remote_port_start = ntohs ((u16) rport_start);
12040   mp->remote_port_stop = ntohs ((u16) rport_stop);
12041   mp->policy = (u8) policy;
12042   mp->sa_id = ntohl (sa_id);
12043   mp->is_add = is_add;
12044   mp->is_ip_any = is_ip_any;
12045   S (mp);
12046   W (ret);
12047   return ret;
12048 }
12049
12050 static int
12051 api_ipsec_sad_add_del_entry (vat_main_t * vam)
12052 {
12053   unformat_input_t *i = vam->input;
12054   vl_api_ipsec_sad_add_del_entry_t *mp;
12055   u32 sad_id = 0, spi = 0;
12056   u8 *ck = 0, *ik = 0;
12057   u8 is_add = 1;
12058
12059   u8 protocol = IPSEC_PROTOCOL_AH;
12060   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
12061   u32 crypto_alg = 0, integ_alg = 0;
12062   ip4_address_t tun_src4;
12063   ip4_address_t tun_dst4;
12064   ip6_address_t tun_src6;
12065   ip6_address_t tun_dst6;
12066   int ret;
12067
12068   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12069     {
12070       if (unformat (i, "del"))
12071         is_add = 0;
12072       else if (unformat (i, "sad_id %d", &sad_id))
12073         ;
12074       else if (unformat (i, "spi %d", &spi))
12075         ;
12076       else if (unformat (i, "esp"))
12077         protocol = IPSEC_PROTOCOL_ESP;
12078       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
12079         {
12080           is_tunnel = 1;
12081           is_tunnel_ipv6 = 0;
12082         }
12083       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
12084         {
12085           is_tunnel = 1;
12086           is_tunnel_ipv6 = 0;
12087         }
12088       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
12089         {
12090           is_tunnel = 1;
12091           is_tunnel_ipv6 = 1;
12092         }
12093       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
12094         {
12095           is_tunnel = 1;
12096           is_tunnel_ipv6 = 1;
12097         }
12098       else
12099         if (unformat
12100             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12101         {
12102           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12103               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12104             {
12105               clib_warning ("unsupported crypto-alg: '%U'",
12106                             format_ipsec_crypto_alg, crypto_alg);
12107               return -99;
12108             }
12109         }
12110       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12111         ;
12112       else
12113         if (unformat
12114             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12115         {
12116           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12117               integ_alg >= IPSEC_INTEG_N_ALG)
12118             {
12119               clib_warning ("unsupported integ-alg: '%U'",
12120                             format_ipsec_integ_alg, integ_alg);
12121               return -99;
12122             }
12123         }
12124       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12125         ;
12126       else
12127         {
12128           clib_warning ("parse error '%U'", format_unformat_error, i);
12129           return -99;
12130         }
12131
12132     }
12133
12134   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
12135
12136   mp->sad_id = ntohl (sad_id);
12137   mp->is_add = is_add;
12138   mp->protocol = protocol;
12139   mp->spi = ntohl (spi);
12140   mp->is_tunnel = is_tunnel;
12141   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12142   mp->crypto_algorithm = crypto_alg;
12143   mp->integrity_algorithm = integ_alg;
12144   mp->crypto_key_length = vec_len (ck);
12145   mp->integrity_key_length = vec_len (ik);
12146
12147   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12148     mp->crypto_key_length = sizeof (mp->crypto_key);
12149
12150   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12151     mp->integrity_key_length = sizeof (mp->integrity_key);
12152
12153   if (ck)
12154     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12155   if (ik)
12156     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12157
12158   if (is_tunnel)
12159     {
12160       if (is_tunnel_ipv6)
12161         {
12162           clib_memcpy (mp->tunnel_src_address, &tun_src6,
12163                        sizeof (ip6_address_t));
12164           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12165                        sizeof (ip6_address_t));
12166         }
12167       else
12168         {
12169           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12170                        sizeof (ip4_address_t));
12171           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12172                        sizeof (ip4_address_t));
12173         }
12174     }
12175
12176   S (mp);
12177   W (ret);
12178   return ret;
12179 }
12180
12181 static int
12182 api_ipsec_sa_set_key (vat_main_t * vam)
12183 {
12184   unformat_input_t *i = vam->input;
12185   vl_api_ipsec_sa_set_key_t *mp;
12186   u32 sa_id;
12187   u8 *ck = 0, *ik = 0;
12188   int ret;
12189
12190   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12191     {
12192       if (unformat (i, "sa_id %d", &sa_id))
12193         ;
12194       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12195         ;
12196       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12197         ;
12198       else
12199         {
12200           clib_warning ("parse error '%U'", format_unformat_error, i);
12201           return -99;
12202         }
12203     }
12204
12205   M (IPSEC_SA_SET_KEY, mp);
12206
12207   mp->sa_id = ntohl (sa_id);
12208   mp->crypto_key_length = vec_len (ck);
12209   mp->integrity_key_length = vec_len (ik);
12210
12211   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12212     mp->crypto_key_length = sizeof (mp->crypto_key);
12213
12214   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12215     mp->integrity_key_length = sizeof (mp->integrity_key);
12216
12217   if (ck)
12218     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12219   if (ik)
12220     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12221
12222   S (mp);
12223   W (ret);
12224   return ret;
12225 }
12226
12227 static int
12228 api_ikev2_profile_add_del (vat_main_t * vam)
12229 {
12230   unformat_input_t *i = vam->input;
12231   vl_api_ikev2_profile_add_del_t *mp;
12232   u8 is_add = 1;
12233   u8 *name = 0;
12234   int ret;
12235
12236   const char *valid_chars = "a-zA-Z0-9_";
12237
12238   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12239     {
12240       if (unformat (i, "del"))
12241         is_add = 0;
12242       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12243         vec_add1 (name, 0);
12244       else
12245         {
12246           errmsg ("parse error '%U'", format_unformat_error, i);
12247           return -99;
12248         }
12249     }
12250
12251   if (!vec_len (name))
12252     {
12253       errmsg ("profile name must be specified");
12254       return -99;
12255     }
12256
12257   if (vec_len (name) > 64)
12258     {
12259       errmsg ("profile name too long");
12260       return -99;
12261     }
12262
12263   M (IKEV2_PROFILE_ADD_DEL, mp);
12264
12265   clib_memcpy (mp->name, name, vec_len (name));
12266   mp->is_add = is_add;
12267   vec_free (name);
12268
12269   S (mp);
12270   W (ret);
12271   return ret;
12272 }
12273
12274 static int
12275 api_ikev2_profile_set_auth (vat_main_t * vam)
12276 {
12277   unformat_input_t *i = vam->input;
12278   vl_api_ikev2_profile_set_auth_t *mp;
12279   u8 *name = 0;
12280   u8 *data = 0;
12281   u32 auth_method = 0;
12282   u8 is_hex = 0;
12283   int ret;
12284
12285   const char *valid_chars = "a-zA-Z0-9_";
12286
12287   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12288     {
12289       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12290         vec_add1 (name, 0);
12291       else if (unformat (i, "auth_method %U",
12292                          unformat_ikev2_auth_method, &auth_method))
12293         ;
12294       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12295         is_hex = 1;
12296       else if (unformat (i, "auth_data %v", &data))
12297         ;
12298       else
12299         {
12300           errmsg ("parse error '%U'", format_unformat_error, i);
12301           return -99;
12302         }
12303     }
12304
12305   if (!vec_len (name))
12306     {
12307       errmsg ("profile name must be specified");
12308       return -99;
12309     }
12310
12311   if (vec_len (name) > 64)
12312     {
12313       errmsg ("profile name too long");
12314       return -99;
12315     }
12316
12317   if (!vec_len (data))
12318     {
12319       errmsg ("auth_data must be specified");
12320       return -99;
12321     }
12322
12323   if (!auth_method)
12324     {
12325       errmsg ("auth_method must be specified");
12326       return -99;
12327     }
12328
12329   M (IKEV2_PROFILE_SET_AUTH, mp);
12330
12331   mp->is_hex = is_hex;
12332   mp->auth_method = (u8) auth_method;
12333   mp->data_len = vec_len (data);
12334   clib_memcpy (mp->name, name, vec_len (name));
12335   clib_memcpy (mp->data, data, vec_len (data));
12336   vec_free (name);
12337   vec_free (data);
12338
12339   S (mp);
12340   W (ret);
12341   return ret;
12342 }
12343
12344 static int
12345 api_ikev2_profile_set_id (vat_main_t * vam)
12346 {
12347   unformat_input_t *i = vam->input;
12348   vl_api_ikev2_profile_set_id_t *mp;
12349   u8 *name = 0;
12350   u8 *data = 0;
12351   u8 is_local = 0;
12352   u32 id_type = 0;
12353   ip4_address_t ip4;
12354   int ret;
12355
12356   const char *valid_chars = "a-zA-Z0-9_";
12357
12358   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12359     {
12360       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12361         vec_add1 (name, 0);
12362       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12363         ;
12364       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12365         {
12366           data = vec_new (u8, 4);
12367           clib_memcpy (data, ip4.as_u8, 4);
12368         }
12369       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12370         ;
12371       else if (unformat (i, "id_data %v", &data))
12372         ;
12373       else if (unformat (i, "local"))
12374         is_local = 1;
12375       else if (unformat (i, "remote"))
12376         is_local = 0;
12377       else
12378         {
12379           errmsg ("parse error '%U'", format_unformat_error, i);
12380           return -99;
12381         }
12382     }
12383
12384   if (!vec_len (name))
12385     {
12386       errmsg ("profile name must be specified");
12387       return -99;
12388     }
12389
12390   if (vec_len (name) > 64)
12391     {
12392       errmsg ("profile name too long");
12393       return -99;
12394     }
12395
12396   if (!vec_len (data))
12397     {
12398       errmsg ("id_data must be specified");
12399       return -99;
12400     }
12401
12402   if (!id_type)
12403     {
12404       errmsg ("id_type must be specified");
12405       return -99;
12406     }
12407
12408   M (IKEV2_PROFILE_SET_ID, mp);
12409
12410   mp->is_local = is_local;
12411   mp->id_type = (u8) id_type;
12412   mp->data_len = vec_len (data);
12413   clib_memcpy (mp->name, name, vec_len (name));
12414   clib_memcpy (mp->data, data, vec_len (data));
12415   vec_free (name);
12416   vec_free (data);
12417
12418   S (mp);
12419   W (ret);
12420   return ret;
12421 }
12422
12423 static int
12424 api_ikev2_profile_set_ts (vat_main_t * vam)
12425 {
12426   unformat_input_t *i = vam->input;
12427   vl_api_ikev2_profile_set_ts_t *mp;
12428   u8 *name = 0;
12429   u8 is_local = 0;
12430   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12431   ip4_address_t start_addr, end_addr;
12432
12433   const char *valid_chars = "a-zA-Z0-9_";
12434   int ret;
12435
12436   start_addr.as_u32 = 0;
12437   end_addr.as_u32 = (u32) ~ 0;
12438
12439   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12440     {
12441       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12442         vec_add1 (name, 0);
12443       else if (unformat (i, "protocol %d", &proto))
12444         ;
12445       else if (unformat (i, "start_port %d", &start_port))
12446         ;
12447       else if (unformat (i, "end_port %d", &end_port))
12448         ;
12449       else
12450         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12451         ;
12452       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12453         ;
12454       else if (unformat (i, "local"))
12455         is_local = 1;
12456       else if (unformat (i, "remote"))
12457         is_local = 0;
12458       else
12459         {
12460           errmsg ("parse error '%U'", format_unformat_error, i);
12461           return -99;
12462         }
12463     }
12464
12465   if (!vec_len (name))
12466     {
12467       errmsg ("profile name must be specified");
12468       return -99;
12469     }
12470
12471   if (vec_len (name) > 64)
12472     {
12473       errmsg ("profile name too long");
12474       return -99;
12475     }
12476
12477   M (IKEV2_PROFILE_SET_TS, mp);
12478
12479   mp->is_local = is_local;
12480   mp->proto = (u8) proto;
12481   mp->start_port = (u16) start_port;
12482   mp->end_port = (u16) end_port;
12483   mp->start_addr = start_addr.as_u32;
12484   mp->end_addr = end_addr.as_u32;
12485   clib_memcpy (mp->name, name, vec_len (name));
12486   vec_free (name);
12487
12488   S (mp);
12489   W (ret);
12490   return ret;
12491 }
12492
12493 static int
12494 api_ikev2_set_local_key (vat_main_t * vam)
12495 {
12496   unformat_input_t *i = vam->input;
12497   vl_api_ikev2_set_local_key_t *mp;
12498   u8 *file = 0;
12499   int ret;
12500
12501   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12502     {
12503       if (unformat (i, "file %v", &file))
12504         vec_add1 (file, 0);
12505       else
12506         {
12507           errmsg ("parse error '%U'", format_unformat_error, i);
12508           return -99;
12509         }
12510     }
12511
12512   if (!vec_len (file))
12513     {
12514       errmsg ("RSA key file must be specified");
12515       return -99;
12516     }
12517
12518   if (vec_len (file) > 256)
12519     {
12520       errmsg ("file name too long");
12521       return -99;
12522     }
12523
12524   M (IKEV2_SET_LOCAL_KEY, mp);
12525
12526   clib_memcpy (mp->key_file, file, vec_len (file));
12527   vec_free (file);
12528
12529   S (mp);
12530   W (ret);
12531   return ret;
12532 }
12533
12534 static int
12535 api_ikev2_set_responder (vat_main_t * vam)
12536 {
12537   unformat_input_t *i = vam->input;
12538   vl_api_ikev2_set_responder_t *mp;
12539   int ret;
12540   u8 *name = 0;
12541   u32 sw_if_index = ~0;
12542   ip4_address_t address;
12543
12544   const char *valid_chars = "a-zA-Z0-9_";
12545
12546   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12547     {
12548       if (unformat
12549           (i, "%U interface %d address %U", unformat_token, valid_chars,
12550            &name, &sw_if_index, unformat_ip4_address, &address))
12551         vec_add1 (name, 0);
12552       else
12553         {
12554           errmsg ("parse error '%U'", format_unformat_error, i);
12555           return -99;
12556         }
12557     }
12558
12559   if (!vec_len (name))
12560     {
12561       errmsg ("profile name must be specified");
12562       return -99;
12563     }
12564
12565   if (vec_len (name) > 64)
12566     {
12567       errmsg ("profile name too long");
12568       return -99;
12569     }
12570
12571   M (IKEV2_SET_RESPONDER, mp);
12572
12573   clib_memcpy (mp->name, name, vec_len (name));
12574   vec_free (name);
12575
12576   mp->sw_if_index = sw_if_index;
12577   clib_memcpy (mp->address, &address, sizeof (address));
12578
12579   S (mp);
12580   W (ret);
12581   return ret;
12582 }
12583
12584 static int
12585 api_ikev2_set_ike_transforms (vat_main_t * vam)
12586 {
12587   unformat_input_t *i = vam->input;
12588   vl_api_ikev2_set_ike_transforms_t *mp;
12589   int ret;
12590   u8 *name = 0;
12591   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
12592
12593   const char *valid_chars = "a-zA-Z0-9_";
12594
12595   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12596     {
12597       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
12598                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
12599         vec_add1 (name, 0);
12600       else
12601         {
12602           errmsg ("parse error '%U'", format_unformat_error, i);
12603           return -99;
12604         }
12605     }
12606
12607   if (!vec_len (name))
12608     {
12609       errmsg ("profile name must be specified");
12610       return -99;
12611     }
12612
12613   if (vec_len (name) > 64)
12614     {
12615       errmsg ("profile name too long");
12616       return -99;
12617     }
12618
12619   M (IKEV2_SET_IKE_TRANSFORMS, mp);
12620
12621   clib_memcpy (mp->name, name, vec_len (name));
12622   vec_free (name);
12623   mp->crypto_alg = crypto_alg;
12624   mp->crypto_key_size = crypto_key_size;
12625   mp->integ_alg = integ_alg;
12626   mp->dh_group = dh_group;
12627
12628   S (mp);
12629   W (ret);
12630   return ret;
12631 }
12632
12633
12634 static int
12635 api_ikev2_set_esp_transforms (vat_main_t * vam)
12636 {
12637   unformat_input_t *i = vam->input;
12638   vl_api_ikev2_set_esp_transforms_t *mp;
12639   int ret;
12640   u8 *name = 0;
12641   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
12642
12643   const char *valid_chars = "a-zA-Z0-9_";
12644
12645   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12646     {
12647       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
12648                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
12649         vec_add1 (name, 0);
12650       else
12651         {
12652           errmsg ("parse error '%U'", format_unformat_error, i);
12653           return -99;
12654         }
12655     }
12656
12657   if (!vec_len (name))
12658     {
12659       errmsg ("profile name must be specified");
12660       return -99;
12661     }
12662
12663   if (vec_len (name) > 64)
12664     {
12665       errmsg ("profile name too long");
12666       return -99;
12667     }
12668
12669   M (IKEV2_SET_ESP_TRANSFORMS, mp);
12670
12671   clib_memcpy (mp->name, name, vec_len (name));
12672   vec_free (name);
12673   mp->crypto_alg = crypto_alg;
12674   mp->crypto_key_size = crypto_key_size;
12675   mp->integ_alg = integ_alg;
12676   mp->dh_group = dh_group;
12677
12678   S (mp);
12679   W (ret);
12680   return ret;
12681 }
12682
12683 static int
12684 api_ikev2_set_sa_lifetime (vat_main_t * vam)
12685 {
12686   unformat_input_t *i = vam->input;
12687   vl_api_ikev2_set_sa_lifetime_t *mp;
12688   int ret;
12689   u8 *name = 0;
12690   u64 lifetime, lifetime_maxdata;
12691   u32 lifetime_jitter, handover;
12692
12693   const char *valid_chars = "a-zA-Z0-9_";
12694
12695   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12696     {
12697       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
12698                     &lifetime, &lifetime_jitter, &handover,
12699                     &lifetime_maxdata))
12700         vec_add1 (name, 0);
12701       else
12702         {
12703           errmsg ("parse error '%U'", format_unformat_error, i);
12704           return -99;
12705         }
12706     }
12707
12708   if (!vec_len (name))
12709     {
12710       errmsg ("profile name must be specified");
12711       return -99;
12712     }
12713
12714   if (vec_len (name) > 64)
12715     {
12716       errmsg ("profile name too long");
12717       return -99;
12718     }
12719
12720   M (IKEV2_SET_SA_LIFETIME, mp);
12721
12722   clib_memcpy (mp->name, name, vec_len (name));
12723   vec_free (name);
12724   mp->lifetime = lifetime;
12725   mp->lifetime_jitter = lifetime_jitter;
12726   mp->handover = handover;
12727   mp->lifetime_maxdata = lifetime_maxdata;
12728
12729   S (mp);
12730   W (ret);
12731   return ret;
12732 }
12733
12734 static int
12735 api_ikev2_initiate_sa_init (vat_main_t * vam)
12736 {
12737   unformat_input_t *i = vam->input;
12738   vl_api_ikev2_initiate_sa_init_t *mp;
12739   int ret;
12740   u8 *name = 0;
12741
12742   const char *valid_chars = "a-zA-Z0-9_";
12743
12744   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12745     {
12746       if (unformat (i, "%U", unformat_token, valid_chars, &name))
12747         vec_add1 (name, 0);
12748       else
12749         {
12750           errmsg ("parse error '%U'", format_unformat_error, i);
12751           return -99;
12752         }
12753     }
12754
12755   if (!vec_len (name))
12756     {
12757       errmsg ("profile name must be specified");
12758       return -99;
12759     }
12760
12761   if (vec_len (name) > 64)
12762     {
12763       errmsg ("profile name too long");
12764       return -99;
12765     }
12766
12767   M (IKEV2_INITIATE_SA_INIT, mp);
12768
12769   clib_memcpy (mp->name, name, vec_len (name));
12770   vec_free (name);
12771
12772   S (mp);
12773   W (ret);
12774   return ret;
12775 }
12776
12777 static int
12778 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
12779 {
12780   unformat_input_t *i = vam->input;
12781   vl_api_ikev2_initiate_del_ike_sa_t *mp;
12782   int ret;
12783   u64 ispi;
12784
12785
12786   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12787     {
12788       if (unformat (i, "%lx", &ispi))
12789         ;
12790       else
12791         {
12792           errmsg ("parse error '%U'", format_unformat_error, i);
12793           return -99;
12794         }
12795     }
12796
12797   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
12798
12799   mp->ispi = ispi;
12800
12801   S (mp);
12802   W (ret);
12803   return ret;
12804 }
12805
12806 static int
12807 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
12808 {
12809   unformat_input_t *i = vam->input;
12810   vl_api_ikev2_initiate_del_child_sa_t *mp;
12811   int ret;
12812   u32 ispi;
12813
12814
12815   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12816     {
12817       if (unformat (i, "%x", &ispi))
12818         ;
12819       else
12820         {
12821           errmsg ("parse error '%U'", format_unformat_error, i);
12822           return -99;
12823         }
12824     }
12825
12826   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
12827
12828   mp->ispi = ispi;
12829
12830   S (mp);
12831   W (ret);
12832   return ret;
12833 }
12834
12835 static int
12836 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
12837 {
12838   unformat_input_t *i = vam->input;
12839   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
12840   int ret;
12841   u32 ispi;
12842
12843
12844   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12845     {
12846       if (unformat (i, "%x", &ispi))
12847         ;
12848       else
12849         {
12850           errmsg ("parse error '%U'", format_unformat_error, i);
12851           return -99;
12852         }
12853     }
12854
12855   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
12856
12857   mp->ispi = ispi;
12858
12859   S (mp);
12860   W (ret);
12861   return ret;
12862 }
12863
12864 /*
12865  * MAP
12866  */
12867 static int
12868 api_map_add_domain (vat_main_t * vam)
12869 {
12870   unformat_input_t *i = vam->input;
12871   vl_api_map_add_domain_t *mp;
12872
12873   ip4_address_t ip4_prefix;
12874   ip6_address_t ip6_prefix;
12875   ip6_address_t ip6_src;
12876   u32 num_m_args = 0;
12877   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12878     0, psid_length = 0;
12879   u8 is_translation = 0;
12880   u32 mtu = 0;
12881   u32 ip6_src_len = 128;
12882   int ret;
12883
12884   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12885     {
12886       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12887                     &ip4_prefix, &ip4_prefix_len))
12888         num_m_args++;
12889       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12890                          &ip6_prefix, &ip6_prefix_len))
12891         num_m_args++;
12892       else
12893         if (unformat
12894             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12895              &ip6_src_len))
12896         num_m_args++;
12897       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12898         num_m_args++;
12899       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12900         num_m_args++;
12901       else if (unformat (i, "psid-offset %d", &psid_offset))
12902         num_m_args++;
12903       else if (unformat (i, "psid-len %d", &psid_length))
12904         num_m_args++;
12905       else if (unformat (i, "mtu %d", &mtu))
12906         num_m_args++;
12907       else if (unformat (i, "map-t"))
12908         is_translation = 1;
12909       else
12910         {
12911           clib_warning ("parse error '%U'", format_unformat_error, i);
12912           return -99;
12913         }
12914     }
12915
12916   if (num_m_args < 3)
12917     {
12918       errmsg ("mandatory argument(s) missing");
12919       return -99;
12920     }
12921
12922   /* Construct the API message */
12923   M (MAP_ADD_DOMAIN, mp);
12924
12925   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12926   mp->ip4_prefix_len = ip4_prefix_len;
12927
12928   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12929   mp->ip6_prefix_len = ip6_prefix_len;
12930
12931   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12932   mp->ip6_src_prefix_len = ip6_src_len;
12933
12934   mp->ea_bits_len = ea_bits_len;
12935   mp->psid_offset = psid_offset;
12936   mp->psid_length = psid_length;
12937   mp->is_translation = is_translation;
12938   mp->mtu = htons (mtu);
12939
12940   /* send it... */
12941   S (mp);
12942
12943   /* Wait for a reply, return good/bad news  */
12944   W (ret);
12945   return ret;
12946 }
12947
12948 static int
12949 api_map_del_domain (vat_main_t * vam)
12950 {
12951   unformat_input_t *i = vam->input;
12952   vl_api_map_del_domain_t *mp;
12953
12954   u32 num_m_args = 0;
12955   u32 index;
12956   int ret;
12957
12958   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12959     {
12960       if (unformat (i, "index %d", &index))
12961         num_m_args++;
12962       else
12963         {
12964           clib_warning ("parse error '%U'", format_unformat_error, i);
12965           return -99;
12966         }
12967     }
12968
12969   if (num_m_args != 1)
12970     {
12971       errmsg ("mandatory argument(s) missing");
12972       return -99;
12973     }
12974
12975   /* Construct the API message */
12976   M (MAP_DEL_DOMAIN, mp);
12977
12978   mp->index = ntohl (index);
12979
12980   /* send it... */
12981   S (mp);
12982
12983   /* Wait for a reply, return good/bad news  */
12984   W (ret);
12985   return ret;
12986 }
12987
12988 static int
12989 api_map_add_del_rule (vat_main_t * vam)
12990 {
12991   unformat_input_t *i = vam->input;
12992   vl_api_map_add_del_rule_t *mp;
12993   u8 is_add = 1;
12994   ip6_address_t ip6_dst;
12995   u32 num_m_args = 0, index, psid = 0;
12996   int ret;
12997
12998   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12999     {
13000       if (unformat (i, "index %d", &index))
13001         num_m_args++;
13002       else if (unformat (i, "psid %d", &psid))
13003         num_m_args++;
13004       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
13005         num_m_args++;
13006       else if (unformat (i, "del"))
13007         {
13008           is_add = 0;
13009         }
13010       else
13011         {
13012           clib_warning ("parse error '%U'", format_unformat_error, i);
13013           return -99;
13014         }
13015     }
13016
13017   /* Construct the API message */
13018   M (MAP_ADD_DEL_RULE, mp);
13019
13020   mp->index = ntohl (index);
13021   mp->is_add = is_add;
13022   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
13023   mp->psid = ntohs (psid);
13024
13025   /* send it... */
13026   S (mp);
13027
13028   /* Wait for a reply, return good/bad news  */
13029   W (ret);
13030   return ret;
13031 }
13032
13033 static int
13034 api_map_domain_dump (vat_main_t * vam)
13035 {
13036   vl_api_map_domain_dump_t *mp;
13037   vl_api_control_ping_t *mp_ping;
13038   int ret;
13039
13040   /* Construct the API message */
13041   M (MAP_DOMAIN_DUMP, mp);
13042
13043   /* send it... */
13044   S (mp);
13045
13046   /* Use a control ping for synchronization */
13047   M (CONTROL_PING, mp_ping);
13048   S (mp_ping);
13049
13050   W (ret);
13051   return ret;
13052 }
13053
13054 static int
13055 api_map_rule_dump (vat_main_t * vam)
13056 {
13057   unformat_input_t *i = vam->input;
13058   vl_api_map_rule_dump_t *mp;
13059   vl_api_control_ping_t *mp_ping;
13060   u32 domain_index = ~0;
13061   int ret;
13062
13063   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13064     {
13065       if (unformat (i, "index %u", &domain_index))
13066         ;
13067       else
13068         break;
13069     }
13070
13071   if (domain_index == ~0)
13072     {
13073       clib_warning ("parse error: domain index expected");
13074       return -99;
13075     }
13076
13077   /* Construct the API message */
13078   M (MAP_RULE_DUMP, mp);
13079
13080   mp->domain_index = htonl (domain_index);
13081
13082   /* send it... */
13083   S (mp);
13084
13085   /* Use a control ping for synchronization */
13086   M (CONTROL_PING, mp_ping);
13087   S (mp_ping);
13088
13089   W (ret);
13090   return ret;
13091 }
13092
13093 static void vl_api_map_add_domain_reply_t_handler
13094   (vl_api_map_add_domain_reply_t * mp)
13095 {
13096   vat_main_t *vam = &vat_main;
13097   i32 retval = ntohl (mp->retval);
13098
13099   if (vam->async_mode)
13100     {
13101       vam->async_errors += (retval < 0);
13102     }
13103   else
13104     {
13105       vam->retval = retval;
13106       vam->result_ready = 1;
13107     }
13108 }
13109
13110 static void vl_api_map_add_domain_reply_t_handler_json
13111   (vl_api_map_add_domain_reply_t * mp)
13112 {
13113   vat_main_t *vam = &vat_main;
13114   vat_json_node_t node;
13115
13116   vat_json_init_object (&node);
13117   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
13118   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
13119
13120   vat_json_print (vam->ofp, &node);
13121   vat_json_free (&node);
13122
13123   vam->retval = ntohl (mp->retval);
13124   vam->result_ready = 1;
13125 }
13126
13127 static int
13128 api_get_first_msg_id (vat_main_t * vam)
13129 {
13130   vl_api_get_first_msg_id_t *mp;
13131   unformat_input_t *i = vam->input;
13132   u8 *name;
13133   u8 name_set = 0;
13134   int ret;
13135
13136   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13137     {
13138       if (unformat (i, "client %s", &name))
13139         name_set = 1;
13140       else
13141         break;
13142     }
13143
13144   if (name_set == 0)
13145     {
13146       errmsg ("missing client name");
13147       return -99;
13148     }
13149   vec_add1 (name, 0);
13150
13151   if (vec_len (name) > 63)
13152     {
13153       errmsg ("client name too long");
13154       return -99;
13155     }
13156
13157   M (GET_FIRST_MSG_ID, mp);
13158   clib_memcpy (mp->name, name, vec_len (name));
13159   S (mp);
13160   W (ret);
13161   return ret;
13162 }
13163
13164 static int
13165 api_cop_interface_enable_disable (vat_main_t * vam)
13166 {
13167   unformat_input_t *line_input = vam->input;
13168   vl_api_cop_interface_enable_disable_t *mp;
13169   u32 sw_if_index = ~0;
13170   u8 enable_disable = 1;
13171   int ret;
13172
13173   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13174     {
13175       if (unformat (line_input, "disable"))
13176         enable_disable = 0;
13177       if (unformat (line_input, "enable"))
13178         enable_disable = 1;
13179       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13180                          vam, &sw_if_index))
13181         ;
13182       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13183         ;
13184       else
13185         break;
13186     }
13187
13188   if (sw_if_index == ~0)
13189     {
13190       errmsg ("missing interface name or sw_if_index");
13191       return -99;
13192     }
13193
13194   /* Construct the API message */
13195   M (COP_INTERFACE_ENABLE_DISABLE, mp);
13196   mp->sw_if_index = ntohl (sw_if_index);
13197   mp->enable_disable = enable_disable;
13198
13199   /* send it... */
13200   S (mp);
13201   /* Wait for the reply */
13202   W (ret);
13203   return ret;
13204 }
13205
13206 static int
13207 api_cop_whitelist_enable_disable (vat_main_t * vam)
13208 {
13209   unformat_input_t *line_input = vam->input;
13210   vl_api_cop_whitelist_enable_disable_t *mp;
13211   u32 sw_if_index = ~0;
13212   u8 ip4 = 0, ip6 = 0, default_cop = 0;
13213   u32 fib_id = 0;
13214   int ret;
13215
13216   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13217     {
13218       if (unformat (line_input, "ip4"))
13219         ip4 = 1;
13220       else if (unformat (line_input, "ip6"))
13221         ip6 = 1;
13222       else if (unformat (line_input, "default"))
13223         default_cop = 1;
13224       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13225                          vam, &sw_if_index))
13226         ;
13227       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13228         ;
13229       else if (unformat (line_input, "fib-id %d", &fib_id))
13230         ;
13231       else
13232         break;
13233     }
13234
13235   if (sw_if_index == ~0)
13236     {
13237       errmsg ("missing interface name or sw_if_index");
13238       return -99;
13239     }
13240
13241   /* Construct the API message */
13242   M (COP_WHITELIST_ENABLE_DISABLE, mp);
13243   mp->sw_if_index = ntohl (sw_if_index);
13244   mp->fib_id = ntohl (fib_id);
13245   mp->ip4 = ip4;
13246   mp->ip6 = ip6;
13247   mp->default_cop = default_cop;
13248
13249   /* send it... */
13250   S (mp);
13251   /* Wait for the reply */
13252   W (ret);
13253   return ret;
13254 }
13255
13256 static int
13257 api_get_node_graph (vat_main_t * vam)
13258 {
13259   vl_api_get_node_graph_t *mp;
13260   int ret;
13261
13262   M (GET_NODE_GRAPH, mp);
13263
13264   /* send it... */
13265   S (mp);
13266   /* Wait for the reply */
13267   W (ret);
13268   return ret;
13269 }
13270
13271 /* *INDENT-OFF* */
13272 /** Used for parsing LISP eids */
13273 typedef CLIB_PACKED(struct{
13274   u8 addr[16];   /**< eid address */
13275   u32 len;       /**< prefix length if IP */
13276   u8 type;      /**< type of eid */
13277 }) lisp_eid_vat_t;
13278 /* *INDENT-ON* */
13279
13280 static uword
13281 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
13282 {
13283   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
13284
13285   memset (a, 0, sizeof (a[0]));
13286
13287   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
13288     {
13289       a->type = 0;              /* ipv4 type */
13290     }
13291   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
13292     {
13293       a->type = 1;              /* ipv6 type */
13294     }
13295   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
13296     {
13297       a->type = 2;              /* mac type */
13298     }
13299   else
13300     {
13301       return 0;
13302     }
13303
13304   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
13305     {
13306       return 0;
13307     }
13308
13309   return 1;
13310 }
13311
13312 static int
13313 lisp_eid_size_vat (u8 type)
13314 {
13315   switch (type)
13316     {
13317     case 0:
13318       return 4;
13319     case 1:
13320       return 16;
13321     case 2:
13322       return 6;
13323     }
13324   return 0;
13325 }
13326
13327 static void
13328 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
13329 {
13330   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
13331 }
13332
13333 static int
13334 api_one_add_del_locator_set (vat_main_t * vam)
13335 {
13336   unformat_input_t *input = vam->input;
13337   vl_api_one_add_del_locator_set_t *mp;
13338   u8 is_add = 1;
13339   u8 *locator_set_name = NULL;
13340   u8 locator_set_name_set = 0;
13341   vl_api_local_locator_t locator, *locators = 0;
13342   u32 sw_if_index, priority, weight;
13343   u32 data_len = 0;
13344
13345   int ret;
13346   /* Parse args required to build the message */
13347   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13348     {
13349       if (unformat (input, "del"))
13350         {
13351           is_add = 0;
13352         }
13353       else if (unformat (input, "locator-set %s", &locator_set_name))
13354         {
13355           locator_set_name_set = 1;
13356         }
13357       else if (unformat (input, "sw_if_index %u p %u w %u",
13358                          &sw_if_index, &priority, &weight))
13359         {
13360           locator.sw_if_index = htonl (sw_if_index);
13361           locator.priority = priority;
13362           locator.weight = weight;
13363           vec_add1 (locators, locator);
13364         }
13365       else
13366         if (unformat
13367             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
13368              &sw_if_index, &priority, &weight))
13369         {
13370           locator.sw_if_index = htonl (sw_if_index);
13371           locator.priority = priority;
13372           locator.weight = weight;
13373           vec_add1 (locators, locator);
13374         }
13375       else
13376         break;
13377     }
13378
13379   if (locator_set_name_set == 0)
13380     {
13381       errmsg ("missing locator-set name");
13382       vec_free (locators);
13383       return -99;
13384     }
13385
13386   if (vec_len (locator_set_name) > 64)
13387     {
13388       errmsg ("locator-set name too long");
13389       vec_free (locator_set_name);
13390       vec_free (locators);
13391       return -99;
13392     }
13393   vec_add1 (locator_set_name, 0);
13394
13395   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
13396
13397   /* Construct the API message */
13398   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
13399
13400   mp->is_add = is_add;
13401   clib_memcpy (mp->locator_set_name, locator_set_name,
13402                vec_len (locator_set_name));
13403   vec_free (locator_set_name);
13404
13405   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
13406   if (locators)
13407     clib_memcpy (mp->locators, locators, data_len);
13408   vec_free (locators);
13409
13410   /* send it... */
13411   S (mp);
13412
13413   /* Wait for a reply... */
13414   W (ret);
13415   return ret;
13416 }
13417
13418 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
13419
13420 static int
13421 api_one_add_del_locator (vat_main_t * vam)
13422 {
13423   unformat_input_t *input = vam->input;
13424   vl_api_one_add_del_locator_t *mp;
13425   u32 tmp_if_index = ~0;
13426   u32 sw_if_index = ~0;
13427   u8 sw_if_index_set = 0;
13428   u8 sw_if_index_if_name_set = 0;
13429   u32 priority = ~0;
13430   u8 priority_set = 0;
13431   u32 weight = ~0;
13432   u8 weight_set = 0;
13433   u8 is_add = 1;
13434   u8 *locator_set_name = NULL;
13435   u8 locator_set_name_set = 0;
13436   int ret;
13437
13438   /* Parse args required to build the message */
13439   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13440     {
13441       if (unformat (input, "del"))
13442         {
13443           is_add = 0;
13444         }
13445       else if (unformat (input, "locator-set %s", &locator_set_name))
13446         {
13447           locator_set_name_set = 1;
13448         }
13449       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
13450                          &tmp_if_index))
13451         {
13452           sw_if_index_if_name_set = 1;
13453           sw_if_index = tmp_if_index;
13454         }
13455       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
13456         {
13457           sw_if_index_set = 1;
13458           sw_if_index = tmp_if_index;
13459         }
13460       else if (unformat (input, "p %d", &priority))
13461         {
13462           priority_set = 1;
13463         }
13464       else if (unformat (input, "w %d", &weight))
13465         {
13466           weight_set = 1;
13467         }
13468       else
13469         break;
13470     }
13471
13472   if (locator_set_name_set == 0)
13473     {
13474       errmsg ("missing locator-set name");
13475       return -99;
13476     }
13477
13478   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
13479     {
13480       errmsg ("missing sw_if_index");
13481       vec_free (locator_set_name);
13482       return -99;
13483     }
13484
13485   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
13486     {
13487       errmsg ("cannot use both params interface name and sw_if_index");
13488       vec_free (locator_set_name);
13489       return -99;
13490     }
13491
13492   if (priority_set == 0)
13493     {
13494       errmsg ("missing locator-set priority");
13495       vec_free (locator_set_name);
13496       return -99;
13497     }
13498
13499   if (weight_set == 0)
13500     {
13501       errmsg ("missing locator-set weight");
13502       vec_free (locator_set_name);
13503       return -99;
13504     }
13505
13506   if (vec_len (locator_set_name) > 64)
13507     {
13508       errmsg ("locator-set name too long");
13509       vec_free (locator_set_name);
13510       return -99;
13511     }
13512   vec_add1 (locator_set_name, 0);
13513
13514   /* Construct the API message */
13515   M (ONE_ADD_DEL_LOCATOR, mp);
13516
13517   mp->is_add = is_add;
13518   mp->sw_if_index = ntohl (sw_if_index);
13519   mp->priority = priority;
13520   mp->weight = weight;
13521   clib_memcpy (mp->locator_set_name, locator_set_name,
13522                vec_len (locator_set_name));
13523   vec_free (locator_set_name);
13524
13525   /* send it... */
13526   S (mp);
13527
13528   /* Wait for a reply... */
13529   W (ret);
13530   return ret;
13531 }
13532
13533 #define api_lisp_add_del_locator api_one_add_del_locator
13534
13535 uword
13536 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
13537 {
13538   u32 *key_id = va_arg (*args, u32 *);
13539   u8 *s = 0;
13540
13541   if (unformat (input, "%s", &s))
13542     {
13543       if (!strcmp ((char *) s, "sha1"))
13544         key_id[0] = HMAC_SHA_1_96;
13545       else if (!strcmp ((char *) s, "sha256"))
13546         key_id[0] = HMAC_SHA_256_128;
13547       else
13548         {
13549           clib_warning ("invalid key_id: '%s'", s);
13550           key_id[0] = HMAC_NO_KEY;
13551         }
13552     }
13553   else
13554     return 0;
13555
13556   vec_free (s);
13557   return 1;
13558 }
13559
13560 static int
13561 api_one_add_del_local_eid (vat_main_t * vam)
13562 {
13563   unformat_input_t *input = vam->input;
13564   vl_api_one_add_del_local_eid_t *mp;
13565   u8 is_add = 1;
13566   u8 eid_set = 0;
13567   lisp_eid_vat_t _eid, *eid = &_eid;
13568   u8 *locator_set_name = 0;
13569   u8 locator_set_name_set = 0;
13570   u32 vni = 0;
13571   u16 key_id = 0;
13572   u8 *key = 0;
13573   int ret;
13574
13575   /* Parse args required to build the message */
13576   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13577     {
13578       if (unformat (input, "del"))
13579         {
13580           is_add = 0;
13581         }
13582       else if (unformat (input, "vni %d", &vni))
13583         {
13584           ;
13585         }
13586       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13587         {
13588           eid_set = 1;
13589         }
13590       else if (unformat (input, "locator-set %s", &locator_set_name))
13591         {
13592           locator_set_name_set = 1;
13593         }
13594       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
13595         ;
13596       else if (unformat (input, "secret-key %_%v%_", &key))
13597         ;
13598       else
13599         break;
13600     }
13601
13602   if (locator_set_name_set == 0)
13603     {
13604       errmsg ("missing locator-set name");
13605       return -99;
13606     }
13607
13608   if (0 == eid_set)
13609     {
13610       errmsg ("EID address not set!");
13611       vec_free (locator_set_name);
13612       return -99;
13613     }
13614
13615   if (key && (0 == key_id))
13616     {
13617       errmsg ("invalid key_id!");
13618       return -99;
13619     }
13620
13621   if (vec_len (key) > 64)
13622     {
13623       errmsg ("key too long");
13624       vec_free (key);
13625       return -99;
13626     }
13627
13628   if (vec_len (locator_set_name) > 64)
13629     {
13630       errmsg ("locator-set name too long");
13631       vec_free (locator_set_name);
13632       return -99;
13633     }
13634   vec_add1 (locator_set_name, 0);
13635
13636   /* Construct the API message */
13637   M (ONE_ADD_DEL_LOCAL_EID, mp);
13638
13639   mp->is_add = is_add;
13640   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13641   mp->eid_type = eid->type;
13642   mp->prefix_len = eid->len;
13643   mp->vni = clib_host_to_net_u32 (vni);
13644   mp->key_id = clib_host_to_net_u16 (key_id);
13645   clib_memcpy (mp->locator_set_name, locator_set_name,
13646                vec_len (locator_set_name));
13647   clib_memcpy (mp->key, key, vec_len (key));
13648
13649   vec_free (locator_set_name);
13650   vec_free (key);
13651
13652   /* send it... */
13653   S (mp);
13654
13655   /* Wait for a reply... */
13656   W (ret);
13657   return ret;
13658 }
13659
13660 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
13661
13662 static int
13663 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
13664 {
13665   u32 dp_table = 0, vni = 0;;
13666   unformat_input_t *input = vam->input;
13667   vl_api_gpe_add_del_fwd_entry_t *mp;
13668   u8 is_add = 1;
13669   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
13670   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
13671   u8 rmt_eid_set = 0, lcl_eid_set = 0;
13672   u32 action = ~0, w;
13673   ip4_address_t rmt_rloc4, lcl_rloc4;
13674   ip6_address_t rmt_rloc6, lcl_rloc6;
13675   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
13676   int ret;
13677
13678   memset (&rloc, 0, sizeof (rloc));
13679
13680   /* Parse args required to build the message */
13681   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13682     {
13683       if (unformat (input, "del"))
13684         is_add = 0;
13685       else if (unformat (input, "add"))
13686         is_add = 1;
13687       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
13688         {
13689           rmt_eid_set = 1;
13690         }
13691       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
13692         {
13693           lcl_eid_set = 1;
13694         }
13695       else if (unformat (input, "vrf %d", &dp_table))
13696         ;
13697       else if (unformat (input, "bd %d", &dp_table))
13698         ;
13699       else if (unformat (input, "vni %d", &vni))
13700         ;
13701       else if (unformat (input, "w %d", &w))
13702         {
13703           if (!curr_rloc)
13704             {
13705               errmsg ("No RLOC configured for setting priority/weight!");
13706               return -99;
13707             }
13708           curr_rloc->weight = w;
13709         }
13710       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
13711                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
13712         {
13713           rloc.is_ip4 = 1;
13714
13715           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
13716           rloc.weight = 0;
13717           vec_add1 (lcl_locs, rloc);
13718
13719           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
13720           vec_add1 (rmt_locs, rloc);
13721           /* weight saved in rmt loc */
13722           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13723         }
13724       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
13725                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
13726         {
13727           rloc.is_ip4 = 0;
13728           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
13729           rloc.weight = 0;
13730           vec_add1 (lcl_locs, rloc);
13731
13732           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13733           vec_add1 (rmt_locs, rloc);
13734           /* weight saved in rmt loc */
13735           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13736         }
13737       else if (unformat (input, "action %d", &action))
13738         {
13739           ;
13740         }
13741       else
13742         {
13743           clib_warning ("parse error '%U'", format_unformat_error, input);
13744           return -99;
13745         }
13746     }
13747
13748   if (!rmt_eid_set)
13749     {
13750       errmsg ("remote eid addresses not set");
13751       return -99;
13752     }
13753
13754   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13755     {
13756       errmsg ("eid types don't match");
13757       return -99;
13758     }
13759
13760   if (0 == rmt_locs && (u32) ~ 0 == action)
13761     {
13762       errmsg ("action not set for negative mapping");
13763       return -99;
13764     }
13765
13766   /* Construct the API message */
13767   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
13768       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
13769
13770   mp->is_add = is_add;
13771   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13772   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13773   mp->eid_type = rmt_eid->type;
13774   mp->dp_table = clib_host_to_net_u32 (dp_table);
13775   mp->vni = clib_host_to_net_u32 (vni);
13776   mp->rmt_len = rmt_eid->len;
13777   mp->lcl_len = lcl_eid->len;
13778   mp->action = action;
13779
13780   if (0 != rmt_locs && 0 != lcl_locs)
13781     {
13782       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
13783       clib_memcpy (mp->locs, lcl_locs,
13784                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
13785
13786       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
13787       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
13788                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
13789     }
13790   vec_free (lcl_locs);
13791   vec_free (rmt_locs);
13792
13793   /* send it... */
13794   S (mp);
13795
13796   /* Wait for a reply... */
13797   W (ret);
13798   return ret;
13799 }
13800
13801 static int
13802 api_one_add_del_map_server (vat_main_t * vam)
13803 {
13804   unformat_input_t *input = vam->input;
13805   vl_api_one_add_del_map_server_t *mp;
13806   u8 is_add = 1;
13807   u8 ipv4_set = 0;
13808   u8 ipv6_set = 0;
13809   ip4_address_t ipv4;
13810   ip6_address_t ipv6;
13811   int ret;
13812
13813   /* Parse args required to build the message */
13814   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13815     {
13816       if (unformat (input, "del"))
13817         {
13818           is_add = 0;
13819         }
13820       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13821         {
13822           ipv4_set = 1;
13823         }
13824       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13825         {
13826           ipv6_set = 1;
13827         }
13828       else
13829         break;
13830     }
13831
13832   if (ipv4_set && ipv6_set)
13833     {
13834       errmsg ("both eid v4 and v6 addresses set");
13835       return -99;
13836     }
13837
13838   if (!ipv4_set && !ipv6_set)
13839     {
13840       errmsg ("eid addresses not set");
13841       return -99;
13842     }
13843
13844   /* Construct the API message */
13845   M (ONE_ADD_DEL_MAP_SERVER, mp);
13846
13847   mp->is_add = is_add;
13848   if (ipv6_set)
13849     {
13850       mp->is_ipv6 = 1;
13851       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13852     }
13853   else
13854     {
13855       mp->is_ipv6 = 0;
13856       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13857     }
13858
13859   /* send it... */
13860   S (mp);
13861
13862   /* Wait for a reply... */
13863   W (ret);
13864   return ret;
13865 }
13866
13867 #define api_lisp_add_del_map_server api_one_add_del_map_server
13868
13869 static int
13870 api_one_add_del_map_resolver (vat_main_t * vam)
13871 {
13872   unformat_input_t *input = vam->input;
13873   vl_api_one_add_del_map_resolver_t *mp;
13874   u8 is_add = 1;
13875   u8 ipv4_set = 0;
13876   u8 ipv6_set = 0;
13877   ip4_address_t ipv4;
13878   ip6_address_t ipv6;
13879   int ret;
13880
13881   /* Parse args required to build the message */
13882   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13883     {
13884       if (unformat (input, "del"))
13885         {
13886           is_add = 0;
13887         }
13888       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13889         {
13890           ipv4_set = 1;
13891         }
13892       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13893         {
13894           ipv6_set = 1;
13895         }
13896       else
13897         break;
13898     }
13899
13900   if (ipv4_set && ipv6_set)
13901     {
13902       errmsg ("both eid v4 and v6 addresses set");
13903       return -99;
13904     }
13905
13906   if (!ipv4_set && !ipv6_set)
13907     {
13908       errmsg ("eid addresses not set");
13909       return -99;
13910     }
13911
13912   /* Construct the API message */
13913   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
13914
13915   mp->is_add = is_add;
13916   if (ipv6_set)
13917     {
13918       mp->is_ipv6 = 1;
13919       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13920     }
13921   else
13922     {
13923       mp->is_ipv6 = 0;
13924       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13925     }
13926
13927   /* send it... */
13928   S (mp);
13929
13930   /* Wait for a reply... */
13931   W (ret);
13932   return ret;
13933 }
13934
13935 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
13936
13937 static int
13938 api_lisp_gpe_enable_disable (vat_main_t * vam)
13939 {
13940   unformat_input_t *input = vam->input;
13941   vl_api_gpe_enable_disable_t *mp;
13942   u8 is_set = 0;
13943   u8 is_en = 1;
13944   int ret;
13945
13946   /* Parse args required to build the message */
13947   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13948     {
13949       if (unformat (input, "enable"))
13950         {
13951           is_set = 1;
13952           is_en = 1;
13953         }
13954       else if (unformat (input, "disable"))
13955         {
13956           is_set = 1;
13957           is_en = 0;
13958         }
13959       else
13960         break;
13961     }
13962
13963   if (is_set == 0)
13964     {
13965       errmsg ("Value not set");
13966       return -99;
13967     }
13968
13969   /* Construct the API message */
13970   M (GPE_ENABLE_DISABLE, mp);
13971
13972   mp->is_en = is_en;
13973
13974   /* send it... */
13975   S (mp);
13976
13977   /* Wait for a reply... */
13978   W (ret);
13979   return ret;
13980 }
13981
13982 static int
13983 api_one_rloc_probe_enable_disable (vat_main_t * vam)
13984 {
13985   unformat_input_t *input = vam->input;
13986   vl_api_one_rloc_probe_enable_disable_t *mp;
13987   u8 is_set = 0;
13988   u8 is_en = 0;
13989   int ret;
13990
13991   /* Parse args required to build the message */
13992   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13993     {
13994       if (unformat (input, "enable"))
13995         {
13996           is_set = 1;
13997           is_en = 1;
13998         }
13999       else if (unformat (input, "disable"))
14000         is_set = 1;
14001       else
14002         break;
14003     }
14004
14005   if (!is_set)
14006     {
14007       errmsg ("Value not set");
14008       return -99;
14009     }
14010
14011   /* Construct the API message */
14012   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14013
14014   mp->is_enabled = is_en;
14015
14016   /* send it... */
14017   S (mp);
14018
14019   /* Wait for a reply... */
14020   W (ret);
14021   return ret;
14022 }
14023
14024 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14025
14026 static int
14027 api_one_map_register_enable_disable (vat_main_t * vam)
14028 {
14029   unformat_input_t *input = vam->input;
14030   vl_api_one_map_register_enable_disable_t *mp;
14031   u8 is_set = 0;
14032   u8 is_en = 0;
14033   int ret;
14034
14035   /* Parse args required to build the message */
14036   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14037     {
14038       if (unformat (input, "enable"))
14039         {
14040           is_set = 1;
14041           is_en = 1;
14042         }
14043       else if (unformat (input, "disable"))
14044         is_set = 1;
14045       else
14046         break;
14047     }
14048
14049   if (!is_set)
14050     {
14051       errmsg ("Value not set");
14052       return -99;
14053     }
14054
14055   /* Construct the API message */
14056   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14057
14058   mp->is_enabled = is_en;
14059
14060   /* send it... */
14061   S (mp);
14062
14063   /* Wait for a reply... */
14064   W (ret);
14065   return ret;
14066 }
14067
14068 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14069
14070 static int
14071 api_one_enable_disable (vat_main_t * vam)
14072 {
14073   unformat_input_t *input = vam->input;
14074   vl_api_one_enable_disable_t *mp;
14075   u8 is_set = 0;
14076   u8 is_en = 0;
14077   int ret;
14078
14079   /* Parse args required to build the message */
14080   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14081     {
14082       if (unformat (input, "enable"))
14083         {
14084           is_set = 1;
14085           is_en = 1;
14086         }
14087       else if (unformat (input, "disable"))
14088         {
14089           is_set = 1;
14090         }
14091       else
14092         break;
14093     }
14094
14095   if (!is_set)
14096     {
14097       errmsg ("Value not set");
14098       return -99;
14099     }
14100
14101   /* Construct the API message */
14102   M (ONE_ENABLE_DISABLE, mp);
14103
14104   mp->is_en = is_en;
14105
14106   /* send it... */
14107   S (mp);
14108
14109   /* Wait for a reply... */
14110   W (ret);
14111   return ret;
14112 }
14113
14114 #define api_lisp_enable_disable api_one_enable_disable
14115
14116 static int
14117 api_show_one_map_register_state (vat_main_t * vam)
14118 {
14119   vl_api_show_one_map_register_state_t *mp;
14120   int ret;
14121
14122   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
14123
14124   /* send */
14125   S (mp);
14126
14127   /* wait for reply */
14128   W (ret);
14129   return ret;
14130 }
14131
14132 #define api_show_lisp_map_register_state api_show_one_map_register_state
14133
14134 static int
14135 api_show_one_rloc_probe_state (vat_main_t * vam)
14136 {
14137   vl_api_show_one_rloc_probe_state_t *mp;
14138   int ret;
14139
14140   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
14141
14142   /* send */
14143   S (mp);
14144
14145   /* wait for reply */
14146   W (ret);
14147   return ret;
14148 }
14149
14150 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
14151
14152 static int
14153 api_show_one_map_request_mode (vat_main_t * vam)
14154 {
14155   vl_api_show_one_map_request_mode_t *mp;
14156   int ret;
14157
14158   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
14159
14160   /* send */
14161   S (mp);
14162
14163   /* wait for reply */
14164   W (ret);
14165   return ret;
14166 }
14167
14168 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
14169
14170 static int
14171 api_one_map_request_mode (vat_main_t * vam)
14172 {
14173   unformat_input_t *input = vam->input;
14174   vl_api_one_map_request_mode_t *mp;
14175   u8 mode = 0;
14176   int ret;
14177
14178   /* Parse args required to build the message */
14179   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14180     {
14181       if (unformat (input, "dst-only"))
14182         mode = 0;
14183       else if (unformat (input, "src-dst"))
14184         mode = 1;
14185       else
14186         {
14187           errmsg ("parse error '%U'", format_unformat_error, input);
14188           return -99;
14189         }
14190     }
14191
14192   M (ONE_MAP_REQUEST_MODE, mp);
14193
14194   mp->mode = mode;
14195
14196   /* send */
14197   S (mp);
14198
14199   /* wait for reply */
14200   W (ret);
14201   return ret;
14202 }
14203
14204 #define api_lisp_map_request_mode api_one_map_request_mode
14205
14206 /**
14207  * Enable/disable ONE proxy ITR.
14208  *
14209  * @param vam vpp API test context
14210  * @return return code
14211  */
14212 static int
14213 api_one_pitr_set_locator_set (vat_main_t * vam)
14214 {
14215   u8 ls_name_set = 0;
14216   unformat_input_t *input = vam->input;
14217   vl_api_one_pitr_set_locator_set_t *mp;
14218   u8 is_add = 1;
14219   u8 *ls_name = 0;
14220   int ret;
14221
14222   /* Parse args required to build the message */
14223   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14224     {
14225       if (unformat (input, "del"))
14226         is_add = 0;
14227       else if (unformat (input, "locator-set %s", &ls_name))
14228         ls_name_set = 1;
14229       else
14230         {
14231           errmsg ("parse error '%U'", format_unformat_error, input);
14232           return -99;
14233         }
14234     }
14235
14236   if (!ls_name_set)
14237     {
14238       errmsg ("locator-set name not set!");
14239       return -99;
14240     }
14241
14242   M (ONE_PITR_SET_LOCATOR_SET, mp);
14243
14244   mp->is_add = is_add;
14245   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
14246   vec_free (ls_name);
14247
14248   /* send */
14249   S (mp);
14250
14251   /* wait for reply */
14252   W (ret);
14253   return ret;
14254 }
14255
14256 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
14257
14258 static int
14259 api_show_one_pitr (vat_main_t * vam)
14260 {
14261   vl_api_show_one_pitr_t *mp;
14262   int ret;
14263
14264   if (!vam->json_output)
14265     {
14266       print (vam->ofp, "%=20s", "lisp status:");
14267     }
14268
14269   M (SHOW_ONE_PITR, mp);
14270   /* send it... */
14271   S (mp);
14272
14273   /* Wait for a reply... */
14274   W (ret);
14275   return ret;
14276 }
14277
14278 #define api_show_lisp_pitr api_show_one_pitr
14279
14280 /**
14281  * Add/delete mapping between vni and vrf
14282  */
14283 static int
14284 api_one_eid_table_add_del_map (vat_main_t * vam)
14285 {
14286   unformat_input_t *input = vam->input;
14287   vl_api_one_eid_table_add_del_map_t *mp;
14288   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
14289   u32 vni, vrf, bd_index;
14290   int ret;
14291
14292   /* Parse args required to build the message */
14293   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14294     {
14295       if (unformat (input, "del"))
14296         is_add = 0;
14297       else if (unformat (input, "vrf %d", &vrf))
14298         vrf_set = 1;
14299       else if (unformat (input, "bd_index %d", &bd_index))
14300         bd_index_set = 1;
14301       else if (unformat (input, "vni %d", &vni))
14302         vni_set = 1;
14303       else
14304         break;
14305     }
14306
14307   if (!vni_set || (!vrf_set && !bd_index_set))
14308     {
14309       errmsg ("missing arguments!");
14310       return -99;
14311     }
14312
14313   if (vrf_set && bd_index_set)
14314     {
14315       errmsg ("error: both vrf and bd entered!");
14316       return -99;
14317     }
14318
14319   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
14320
14321   mp->is_add = is_add;
14322   mp->vni = htonl (vni);
14323   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
14324   mp->is_l2 = bd_index_set;
14325
14326   /* send */
14327   S (mp);
14328
14329   /* wait for reply */
14330   W (ret);
14331   return ret;
14332 }
14333
14334 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
14335
14336 uword
14337 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
14338 {
14339   u32 *action = va_arg (*args, u32 *);
14340   u8 *s = 0;
14341
14342   if (unformat (input, "%s", &s))
14343     {
14344       if (!strcmp ((char *) s, "no-action"))
14345         action[0] = 0;
14346       else if (!strcmp ((char *) s, "natively-forward"))
14347         action[0] = 1;
14348       else if (!strcmp ((char *) s, "send-map-request"))
14349         action[0] = 2;
14350       else if (!strcmp ((char *) s, "drop"))
14351         action[0] = 3;
14352       else
14353         {
14354           clib_warning ("invalid action: '%s'", s);
14355           action[0] = 3;
14356         }
14357     }
14358   else
14359     return 0;
14360
14361   vec_free (s);
14362   return 1;
14363 }
14364
14365 /**
14366  * Add/del remote mapping to/from ONE control plane
14367  *
14368  * @param vam vpp API test context
14369  * @return return code
14370  */
14371 static int
14372 api_one_add_del_remote_mapping (vat_main_t * vam)
14373 {
14374   unformat_input_t *input = vam->input;
14375   vl_api_one_add_del_remote_mapping_t *mp;
14376   u32 vni = 0;
14377   lisp_eid_vat_t _eid, *eid = &_eid;
14378   lisp_eid_vat_t _seid, *seid = &_seid;
14379   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
14380   u32 action = ~0, p, w, data_len;
14381   ip4_address_t rloc4;
14382   ip6_address_t rloc6;
14383   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
14384   int ret;
14385
14386   memset (&rloc, 0, sizeof (rloc));
14387
14388   /* Parse args required to build the message */
14389   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14390     {
14391       if (unformat (input, "del-all"))
14392         {
14393           del_all = 1;
14394         }
14395       else if (unformat (input, "del"))
14396         {
14397           is_add = 0;
14398         }
14399       else if (unformat (input, "add"))
14400         {
14401           is_add = 1;
14402         }
14403       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14404         {
14405           eid_set = 1;
14406         }
14407       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
14408         {
14409           seid_set = 1;
14410         }
14411       else if (unformat (input, "vni %d", &vni))
14412         {
14413           ;
14414         }
14415       else if (unformat (input, "p %d w %d", &p, &w))
14416         {
14417           if (!curr_rloc)
14418             {
14419               errmsg ("No RLOC configured for setting priority/weight!");
14420               return -99;
14421             }
14422           curr_rloc->priority = p;
14423           curr_rloc->weight = w;
14424         }
14425       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
14426         {
14427           rloc.is_ip4 = 1;
14428           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
14429           vec_add1 (rlocs, rloc);
14430           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14431         }
14432       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
14433         {
14434           rloc.is_ip4 = 0;
14435           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
14436           vec_add1 (rlocs, rloc);
14437           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14438         }
14439       else if (unformat (input, "action %U",
14440                          unformat_negative_mapping_action, &action))
14441         {
14442           ;
14443         }
14444       else
14445         {
14446           clib_warning ("parse error '%U'", format_unformat_error, input);
14447           return -99;
14448         }
14449     }
14450
14451   if (0 == eid_set)
14452     {
14453       errmsg ("missing params!");
14454       return -99;
14455     }
14456
14457   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
14458     {
14459       errmsg ("no action set for negative map-reply!");
14460       return -99;
14461     }
14462
14463   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
14464
14465   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
14466   mp->is_add = is_add;
14467   mp->vni = htonl (vni);
14468   mp->action = (u8) action;
14469   mp->is_src_dst = seid_set;
14470   mp->eid_len = eid->len;
14471   mp->seid_len = seid->len;
14472   mp->del_all = del_all;
14473   mp->eid_type = eid->type;
14474   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14475   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
14476
14477   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
14478   clib_memcpy (mp->rlocs, rlocs, data_len);
14479   vec_free (rlocs);
14480
14481   /* send it... */
14482   S (mp);
14483
14484   /* Wait for a reply... */
14485   W (ret);
14486   return ret;
14487 }
14488
14489 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
14490
14491 /**
14492  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
14493  * forwarding entries in data-plane accordingly.
14494  *
14495  * @param vam vpp API test context
14496  * @return return code
14497  */
14498 static int
14499 api_one_add_del_adjacency (vat_main_t * vam)
14500 {
14501   unformat_input_t *input = vam->input;
14502   vl_api_one_add_del_adjacency_t *mp;
14503   u32 vni = 0;
14504   ip4_address_t leid4, reid4;
14505   ip6_address_t leid6, reid6;
14506   u8 reid_mac[6] = { 0 };
14507   u8 leid_mac[6] = { 0 };
14508   u8 reid_type, leid_type;
14509   u32 leid_len = 0, reid_len = 0, len;
14510   u8 is_add = 1;
14511   int ret;
14512
14513   leid_type = reid_type = (u8) ~ 0;
14514
14515   /* Parse args required to build the message */
14516   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14517     {
14518       if (unformat (input, "del"))
14519         {
14520           is_add = 0;
14521         }
14522       else if (unformat (input, "add"))
14523         {
14524           is_add = 1;
14525         }
14526       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
14527                          &reid4, &len))
14528         {
14529           reid_type = 0;        /* ipv4 */
14530           reid_len = len;
14531         }
14532       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
14533                          &reid6, &len))
14534         {
14535           reid_type = 1;        /* ipv6 */
14536           reid_len = len;
14537         }
14538       else if (unformat (input, "reid %U", unformat_ethernet_address,
14539                          reid_mac))
14540         {
14541           reid_type = 2;        /* mac */
14542         }
14543       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
14544                          &leid4, &len))
14545         {
14546           leid_type = 0;        /* ipv4 */
14547           leid_len = len;
14548         }
14549       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
14550                          &leid6, &len))
14551         {
14552           leid_type = 1;        /* ipv6 */
14553           leid_len = len;
14554         }
14555       else if (unformat (input, "leid %U", unformat_ethernet_address,
14556                          leid_mac))
14557         {
14558           leid_type = 2;        /* mac */
14559         }
14560       else if (unformat (input, "vni %d", &vni))
14561         {
14562           ;
14563         }
14564       else
14565         {
14566           errmsg ("parse error '%U'", format_unformat_error, input);
14567           return -99;
14568         }
14569     }
14570
14571   if ((u8) ~ 0 == reid_type)
14572     {
14573       errmsg ("missing params!");
14574       return -99;
14575     }
14576
14577   if (leid_type != reid_type)
14578     {
14579       errmsg ("remote and local EIDs are of different types!");
14580       return -99;
14581     }
14582
14583   M (ONE_ADD_DEL_ADJACENCY, mp);
14584   mp->is_add = is_add;
14585   mp->vni = htonl (vni);
14586   mp->leid_len = leid_len;
14587   mp->reid_len = reid_len;
14588   mp->eid_type = reid_type;
14589
14590   switch (mp->eid_type)
14591     {
14592     case 0:
14593       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
14594       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
14595       break;
14596     case 1:
14597       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
14598       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
14599       break;
14600     case 2:
14601       clib_memcpy (mp->leid, leid_mac, 6);
14602       clib_memcpy (mp->reid, reid_mac, 6);
14603       break;
14604     default:
14605       errmsg ("unknown EID type %d!", mp->eid_type);
14606       return 0;
14607     }
14608
14609   /* send it... */
14610   S (mp);
14611
14612   /* Wait for a reply... */
14613   W (ret);
14614   return ret;
14615 }
14616
14617 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
14618
14619 uword
14620 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
14621 {
14622   u32 *mode = va_arg (*args, u32 *);
14623
14624   if (unformat (input, "lisp"))
14625     *mode = 0;
14626   else if (unformat (input, "vxlan"))
14627     *mode = 1;
14628   else
14629     return 0;
14630
14631   return 1;
14632 }
14633
14634 static int
14635 api_gpe_get_encap_mode (vat_main_t * vam)
14636 {
14637   vl_api_gpe_get_encap_mode_t *mp;
14638   int ret;
14639
14640   /* Construct the API message */
14641   M (GPE_GET_ENCAP_MODE, mp);
14642
14643   /* send it... */
14644   S (mp);
14645
14646   /* Wait for a reply... */
14647   W (ret);
14648   return ret;
14649 }
14650
14651 static int
14652 api_gpe_set_encap_mode (vat_main_t * vam)
14653 {
14654   unformat_input_t *input = vam->input;
14655   vl_api_gpe_set_encap_mode_t *mp;
14656   int ret;
14657   u32 mode = 0;
14658
14659   /* Parse args required to build the message */
14660   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14661     {
14662       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
14663         ;
14664       else
14665         break;
14666     }
14667
14668   /* Construct the API message */
14669   M (GPE_SET_ENCAP_MODE, mp);
14670
14671   mp->mode = mode;
14672
14673   /* send it... */
14674   S (mp);
14675
14676   /* Wait for a reply... */
14677   W (ret);
14678   return ret;
14679 }
14680
14681 static int
14682 api_lisp_gpe_add_del_iface (vat_main_t * vam)
14683 {
14684   unformat_input_t *input = vam->input;
14685   vl_api_gpe_add_del_iface_t *mp;
14686   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
14687   u32 dp_table = 0, vni = 0;
14688   int ret;
14689
14690   /* Parse args required to build the message */
14691   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14692     {
14693       if (unformat (input, "up"))
14694         {
14695           action_set = 1;
14696           is_add = 1;
14697         }
14698       else if (unformat (input, "down"))
14699         {
14700           action_set = 1;
14701           is_add = 0;
14702         }
14703       else if (unformat (input, "table_id %d", &dp_table))
14704         {
14705           dp_table_set = 1;
14706         }
14707       else if (unformat (input, "bd_id %d", &dp_table))
14708         {
14709           dp_table_set = 1;
14710           is_l2 = 1;
14711         }
14712       else if (unformat (input, "vni %d", &vni))
14713         {
14714           vni_set = 1;
14715         }
14716       else
14717         break;
14718     }
14719
14720   if (action_set == 0)
14721     {
14722       errmsg ("Action not set");
14723       return -99;
14724     }
14725   if (dp_table_set == 0 || vni_set == 0)
14726     {
14727       errmsg ("vni and dp_table must be set");
14728       return -99;
14729     }
14730
14731   /* Construct the API message */
14732   M (GPE_ADD_DEL_IFACE, mp);
14733
14734   mp->is_add = is_add;
14735   mp->dp_table = dp_table;
14736   mp->is_l2 = is_l2;
14737   mp->vni = vni;
14738
14739   /* send it... */
14740   S (mp);
14741
14742   /* Wait for a reply... */
14743   W (ret);
14744   return ret;
14745 }
14746
14747 /**
14748  * Add/del map request itr rlocs from ONE control plane and updates
14749  *
14750  * @param vam vpp API test context
14751  * @return return code
14752  */
14753 static int
14754 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
14755 {
14756   unformat_input_t *input = vam->input;
14757   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
14758   u8 *locator_set_name = 0;
14759   u8 locator_set_name_set = 0;
14760   u8 is_add = 1;
14761   int ret;
14762
14763   /* Parse args required to build the message */
14764   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14765     {
14766       if (unformat (input, "del"))
14767         {
14768           is_add = 0;
14769         }
14770       else if (unformat (input, "%_%v%_", &locator_set_name))
14771         {
14772           locator_set_name_set = 1;
14773         }
14774       else
14775         {
14776           clib_warning ("parse error '%U'", format_unformat_error, input);
14777           return -99;
14778         }
14779     }
14780
14781   if (is_add && !locator_set_name_set)
14782     {
14783       errmsg ("itr-rloc is not set!");
14784       return -99;
14785     }
14786
14787   if (is_add && vec_len (locator_set_name) > 64)
14788     {
14789       errmsg ("itr-rloc locator-set name too long");
14790       vec_free (locator_set_name);
14791       return -99;
14792     }
14793
14794   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
14795   mp->is_add = is_add;
14796   if (is_add)
14797     {
14798       clib_memcpy (mp->locator_set_name, locator_set_name,
14799                    vec_len (locator_set_name));
14800     }
14801   else
14802     {
14803       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
14804     }
14805   vec_free (locator_set_name);
14806
14807   /* send it... */
14808   S (mp);
14809
14810   /* Wait for a reply... */
14811   W (ret);
14812   return ret;
14813 }
14814
14815 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
14816
14817 static int
14818 api_one_locator_dump (vat_main_t * vam)
14819 {
14820   unformat_input_t *input = vam->input;
14821   vl_api_one_locator_dump_t *mp;
14822   vl_api_control_ping_t *mp_ping;
14823   u8 is_index_set = 0, is_name_set = 0;
14824   u8 *ls_name = 0;
14825   u32 ls_index = ~0;
14826   int ret;
14827
14828   /* Parse args required to build the message */
14829   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14830     {
14831       if (unformat (input, "ls_name %_%v%_", &ls_name))
14832         {
14833           is_name_set = 1;
14834         }
14835       else if (unformat (input, "ls_index %d", &ls_index))
14836         {
14837           is_index_set = 1;
14838         }
14839       else
14840         {
14841           errmsg ("parse error '%U'", format_unformat_error, input);
14842           return -99;
14843         }
14844     }
14845
14846   if (!is_index_set && !is_name_set)
14847     {
14848       errmsg ("error: expected one of index or name!");
14849       return -99;
14850     }
14851
14852   if (is_index_set && is_name_set)
14853     {
14854       errmsg ("error: only one param expected!");
14855       return -99;
14856     }
14857
14858   if (vec_len (ls_name) > 62)
14859     {
14860       errmsg ("error: locator set name too long!");
14861       return -99;
14862     }
14863
14864   if (!vam->json_output)
14865     {
14866       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
14867     }
14868
14869   M (ONE_LOCATOR_DUMP, mp);
14870   mp->is_index_set = is_index_set;
14871
14872   if (is_index_set)
14873     mp->ls_index = clib_host_to_net_u32 (ls_index);
14874   else
14875     {
14876       vec_add1 (ls_name, 0);
14877       strncpy ((char *) mp->ls_name, (char *) ls_name,
14878                sizeof (mp->ls_name) - 1);
14879     }
14880
14881   /* send it... */
14882   S (mp);
14883
14884   /* Use a control ping for synchronization */
14885   M (CONTROL_PING, mp_ping);
14886   S (mp_ping);
14887
14888   /* Wait for a reply... */
14889   W (ret);
14890   return ret;
14891 }
14892
14893 #define api_lisp_locator_dump api_one_locator_dump
14894
14895 static int
14896 api_one_locator_set_dump (vat_main_t * vam)
14897 {
14898   vl_api_one_locator_set_dump_t *mp;
14899   vl_api_control_ping_t *mp_ping;
14900   unformat_input_t *input = vam->input;
14901   u8 filter = 0;
14902   int ret;
14903
14904   /* Parse args required to build the message */
14905   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14906     {
14907       if (unformat (input, "local"))
14908         {
14909           filter = 1;
14910         }
14911       else if (unformat (input, "remote"))
14912         {
14913           filter = 2;
14914         }
14915       else
14916         {
14917           errmsg ("parse error '%U'", format_unformat_error, input);
14918           return -99;
14919         }
14920     }
14921
14922   if (!vam->json_output)
14923     {
14924       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
14925     }
14926
14927   M (ONE_LOCATOR_SET_DUMP, mp);
14928
14929   mp->filter = filter;
14930
14931   /* send it... */
14932   S (mp);
14933
14934   /* Use a control ping for synchronization */
14935   M (CONTROL_PING, mp_ping);
14936   S (mp_ping);
14937
14938   /* Wait for a reply... */
14939   W (ret);
14940   return ret;
14941 }
14942
14943 #define api_lisp_locator_set_dump api_one_locator_set_dump
14944
14945 static int
14946 api_one_eid_table_map_dump (vat_main_t * vam)
14947 {
14948   u8 is_l2 = 0;
14949   u8 mode_set = 0;
14950   unformat_input_t *input = vam->input;
14951   vl_api_one_eid_table_map_dump_t *mp;
14952   vl_api_control_ping_t *mp_ping;
14953   int ret;
14954
14955   /* Parse args required to build the message */
14956   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14957     {
14958       if (unformat (input, "l2"))
14959         {
14960           is_l2 = 1;
14961           mode_set = 1;
14962         }
14963       else if (unformat (input, "l3"))
14964         {
14965           is_l2 = 0;
14966           mode_set = 1;
14967         }
14968       else
14969         {
14970           errmsg ("parse error '%U'", format_unformat_error, input);
14971           return -99;
14972         }
14973     }
14974
14975   if (!mode_set)
14976     {
14977       errmsg ("expected one of 'l2' or 'l3' parameter!");
14978       return -99;
14979     }
14980
14981   if (!vam->json_output)
14982     {
14983       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
14984     }
14985
14986   M (ONE_EID_TABLE_MAP_DUMP, mp);
14987   mp->is_l2 = is_l2;
14988
14989   /* send it... */
14990   S (mp);
14991
14992   /* Use a control ping for synchronization */
14993   M (CONTROL_PING, mp_ping);
14994   S (mp_ping);
14995
14996   /* Wait for a reply... */
14997   W (ret);
14998   return ret;
14999 }
15000
15001 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
15002
15003 static int
15004 api_one_eid_table_vni_dump (vat_main_t * vam)
15005 {
15006   vl_api_one_eid_table_vni_dump_t *mp;
15007   vl_api_control_ping_t *mp_ping;
15008   int ret;
15009
15010   if (!vam->json_output)
15011     {
15012       print (vam->ofp, "VNI");
15013     }
15014
15015   M (ONE_EID_TABLE_VNI_DUMP, mp);
15016
15017   /* send it... */
15018   S (mp);
15019
15020   /* Use a control ping for synchronization */
15021   M (CONTROL_PING, mp_ping);
15022   S (mp_ping);
15023
15024   /* Wait for a reply... */
15025   W (ret);
15026   return ret;
15027 }
15028
15029 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
15030
15031 static int
15032 api_one_eid_table_dump (vat_main_t * vam)
15033 {
15034   unformat_input_t *i = vam->input;
15035   vl_api_one_eid_table_dump_t *mp;
15036   vl_api_control_ping_t *mp_ping;
15037   struct in_addr ip4;
15038   struct in6_addr ip6;
15039   u8 mac[6];
15040   u8 eid_type = ~0, eid_set = 0;
15041   u32 prefix_length = ~0, t, vni = 0;
15042   u8 filter = 0;
15043   int ret;
15044
15045   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15046     {
15047       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
15048         {
15049           eid_set = 1;
15050           eid_type = 0;
15051           prefix_length = t;
15052         }
15053       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
15054         {
15055           eid_set = 1;
15056           eid_type = 1;
15057           prefix_length = t;
15058         }
15059       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
15060         {
15061           eid_set = 1;
15062           eid_type = 2;
15063         }
15064       else if (unformat (i, "vni %d", &t))
15065         {
15066           vni = t;
15067         }
15068       else if (unformat (i, "local"))
15069         {
15070           filter = 1;
15071         }
15072       else if (unformat (i, "remote"))
15073         {
15074           filter = 2;
15075         }
15076       else
15077         {
15078           errmsg ("parse error '%U'", format_unformat_error, i);
15079           return -99;
15080         }
15081     }
15082
15083   if (!vam->json_output)
15084     {
15085       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
15086              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
15087     }
15088
15089   M (ONE_EID_TABLE_DUMP, mp);
15090
15091   mp->filter = filter;
15092   if (eid_set)
15093     {
15094       mp->eid_set = 1;
15095       mp->vni = htonl (vni);
15096       mp->eid_type = eid_type;
15097       switch (eid_type)
15098         {
15099         case 0:
15100           mp->prefix_length = prefix_length;
15101           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
15102           break;
15103         case 1:
15104           mp->prefix_length = prefix_length;
15105           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
15106           break;
15107         case 2:
15108           clib_memcpy (mp->eid, mac, sizeof (mac));
15109           break;
15110         default:
15111           errmsg ("unknown EID type %d!", eid_type);
15112           return -99;
15113         }
15114     }
15115
15116   /* send it... */
15117   S (mp);
15118
15119   /* Use a control ping for synchronization */
15120   M (CONTROL_PING, mp_ping);
15121   S (mp_ping);
15122
15123   /* Wait for a reply... */
15124   W (ret);
15125   return ret;
15126 }
15127
15128 #define api_lisp_eid_table_dump api_one_eid_table_dump
15129
15130 static int
15131 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
15132 {
15133   unformat_input_t *i = vam->input;
15134   vl_api_gpe_fwd_entries_get_t *mp;
15135   u8 vni_set = 0;
15136   u32 vni = ~0;
15137   int ret;
15138
15139   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15140     {
15141       if (unformat (i, "vni %d", &vni))
15142         {
15143           vni_set = 1;
15144         }
15145       else
15146         {
15147           errmsg ("parse error '%U'", format_unformat_error, i);
15148           return -99;
15149         }
15150     }
15151
15152   if (!vni_set)
15153     {
15154       errmsg ("vni not set!");
15155       return -99;
15156     }
15157
15158   if (!vam->json_output)
15159     {
15160       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
15161              "leid", "reid");
15162     }
15163
15164   M (GPE_FWD_ENTRIES_GET, mp);
15165   mp->vni = clib_host_to_net_u32 (vni);
15166
15167   /* send it... */
15168   S (mp);
15169
15170   /* Wait for a reply... */
15171   W (ret);
15172   return ret;
15173 }
15174
15175 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
15176 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
15177 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
15178 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
15179
15180 static int
15181 api_one_adjacencies_get (vat_main_t * vam)
15182 {
15183   unformat_input_t *i = vam->input;
15184   vl_api_one_adjacencies_get_t *mp;
15185   u8 vni_set = 0;
15186   u32 vni = ~0;
15187   int ret;
15188
15189   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15190     {
15191       if (unformat (i, "vni %d", &vni))
15192         {
15193           vni_set = 1;
15194         }
15195       else
15196         {
15197           errmsg ("parse error '%U'", format_unformat_error, i);
15198           return -99;
15199         }
15200     }
15201
15202   if (!vni_set)
15203     {
15204       errmsg ("vni not set!");
15205       return -99;
15206     }
15207
15208   if (!vam->json_output)
15209     {
15210       print (vam->ofp, "%s %40s", "leid", "reid");
15211     }
15212
15213   M (ONE_ADJACENCIES_GET, mp);
15214   mp->vni = clib_host_to_net_u32 (vni);
15215
15216   /* send it... */
15217   S (mp);
15218
15219   /* Wait for a reply... */
15220   W (ret);
15221   return ret;
15222 }
15223
15224 #define api_lisp_adjacencies_get api_one_adjacencies_get
15225
15226 static int
15227 api_one_map_server_dump (vat_main_t * vam)
15228 {
15229   vl_api_one_map_server_dump_t *mp;
15230   vl_api_control_ping_t *mp_ping;
15231   int ret;
15232
15233   if (!vam->json_output)
15234     {
15235       print (vam->ofp, "%=20s", "Map server");
15236     }
15237
15238   M (ONE_MAP_SERVER_DUMP, mp);
15239   /* send it... */
15240   S (mp);
15241
15242   /* Use a control ping for synchronization */
15243   M (CONTROL_PING, mp_ping);
15244   S (mp_ping);
15245
15246   /* Wait for a reply... */
15247   W (ret);
15248   return ret;
15249 }
15250
15251 #define api_lisp_map_server_dump api_one_map_server_dump
15252
15253 static int
15254 api_one_map_resolver_dump (vat_main_t * vam)
15255 {
15256   vl_api_one_map_resolver_dump_t *mp;
15257   vl_api_control_ping_t *mp_ping;
15258   int ret;
15259
15260   if (!vam->json_output)
15261     {
15262       print (vam->ofp, "%=20s", "Map resolver");
15263     }
15264
15265   M (ONE_MAP_RESOLVER_DUMP, mp);
15266   /* send it... */
15267   S (mp);
15268
15269   /* Use a control ping for synchronization */
15270   M (CONTROL_PING, mp_ping);
15271   S (mp_ping);
15272
15273   /* Wait for a reply... */
15274   W (ret);
15275   return ret;
15276 }
15277
15278 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
15279
15280 static int
15281 api_show_one_status (vat_main_t * vam)
15282 {
15283   vl_api_show_one_status_t *mp;
15284   int ret;
15285
15286   if (!vam->json_output)
15287     {
15288       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
15289     }
15290
15291   M (SHOW_ONE_STATUS, mp);
15292   /* send it... */
15293   S (mp);
15294   /* Wait for a reply... */
15295   W (ret);
15296   return ret;
15297 }
15298
15299 #define api_show_lisp_status api_show_one_status
15300
15301 static int
15302 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
15303 {
15304   vl_api_gpe_fwd_entry_path_dump_t *mp;
15305   vl_api_control_ping_t *mp_ping;
15306   unformat_input_t *i = vam->input;
15307   u32 fwd_entry_index = ~0;
15308   int ret;
15309
15310   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15311     {
15312       if (unformat (i, "index %d", &fwd_entry_index))
15313         ;
15314       else
15315         break;
15316     }
15317
15318   if (~0 == fwd_entry_index)
15319     {
15320       errmsg ("no index specified!");
15321       return -99;
15322     }
15323
15324   if (!vam->json_output)
15325     {
15326       print (vam->ofp, "first line");
15327     }
15328
15329   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
15330
15331   /* send it... */
15332   S (mp);
15333   /* Use a control ping for synchronization */
15334   M (CONTROL_PING, mp_ping);
15335   S (mp_ping);
15336
15337   /* Wait for a reply... */
15338   W (ret);
15339   return ret;
15340 }
15341
15342 static int
15343 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
15344 {
15345   vl_api_one_get_map_request_itr_rlocs_t *mp;
15346   int ret;
15347
15348   if (!vam->json_output)
15349     {
15350       print (vam->ofp, "%=20s", "itr-rlocs:");
15351     }
15352
15353   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
15354   /* send it... */
15355   S (mp);
15356   /* Wait for a reply... */
15357   W (ret);
15358   return ret;
15359 }
15360
15361 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
15362
15363 static int
15364 api_af_packet_create (vat_main_t * vam)
15365 {
15366   unformat_input_t *i = vam->input;
15367   vl_api_af_packet_create_t *mp;
15368   u8 *host_if_name = 0;
15369   u8 hw_addr[6];
15370   u8 random_hw_addr = 1;
15371   int ret;
15372
15373   memset (hw_addr, 0, sizeof (hw_addr));
15374
15375   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15376     {
15377       if (unformat (i, "name %s", &host_if_name))
15378         vec_add1 (host_if_name, 0);
15379       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15380         random_hw_addr = 0;
15381       else
15382         break;
15383     }
15384
15385   if (!vec_len (host_if_name))
15386     {
15387       errmsg ("host-interface name must be specified");
15388       return -99;
15389     }
15390
15391   if (vec_len (host_if_name) > 64)
15392     {
15393       errmsg ("host-interface name too long");
15394       return -99;
15395     }
15396
15397   M (AF_PACKET_CREATE, mp);
15398
15399   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15400   clib_memcpy (mp->hw_addr, hw_addr, 6);
15401   mp->use_random_hw_addr = random_hw_addr;
15402   vec_free (host_if_name);
15403
15404   S (mp);
15405
15406   /* *INDENT-OFF* */
15407   W2 (ret,
15408       ({
15409         if (ret == 0)
15410           fprintf (vam->ofp ? vam->ofp : stderr,
15411                    " new sw_if_index = %d\n", vam->sw_if_index);
15412       }));
15413   /* *INDENT-ON* */
15414   return ret;
15415 }
15416
15417 static int
15418 api_af_packet_delete (vat_main_t * vam)
15419 {
15420   unformat_input_t *i = vam->input;
15421   vl_api_af_packet_delete_t *mp;
15422   u8 *host_if_name = 0;
15423   int ret;
15424
15425   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15426     {
15427       if (unformat (i, "name %s", &host_if_name))
15428         vec_add1 (host_if_name, 0);
15429       else
15430         break;
15431     }
15432
15433   if (!vec_len (host_if_name))
15434     {
15435       errmsg ("host-interface name must be specified");
15436       return -99;
15437     }
15438
15439   if (vec_len (host_if_name) > 64)
15440     {
15441       errmsg ("host-interface name too long");
15442       return -99;
15443     }
15444
15445   M (AF_PACKET_DELETE, mp);
15446
15447   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15448   vec_free (host_if_name);
15449
15450   S (mp);
15451   W (ret);
15452   return ret;
15453 }
15454
15455 static int
15456 api_policer_add_del (vat_main_t * vam)
15457 {
15458   unformat_input_t *i = vam->input;
15459   vl_api_policer_add_del_t *mp;
15460   u8 is_add = 1;
15461   u8 *name = 0;
15462   u32 cir = 0;
15463   u32 eir = 0;
15464   u64 cb = 0;
15465   u64 eb = 0;
15466   u8 rate_type = 0;
15467   u8 round_type = 0;
15468   u8 type = 0;
15469   u8 color_aware = 0;
15470   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
15471   int ret;
15472
15473   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
15474   conform_action.dscp = 0;
15475   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
15476   exceed_action.dscp = 0;
15477   violate_action.action_type = SSE2_QOS_ACTION_DROP;
15478   violate_action.dscp = 0;
15479
15480   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15481     {
15482       if (unformat (i, "del"))
15483         is_add = 0;
15484       else if (unformat (i, "name %s", &name))
15485         vec_add1 (name, 0);
15486       else if (unformat (i, "cir %u", &cir))
15487         ;
15488       else if (unformat (i, "eir %u", &eir))
15489         ;
15490       else if (unformat (i, "cb %u", &cb))
15491         ;
15492       else if (unformat (i, "eb %u", &eb))
15493         ;
15494       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
15495                          &rate_type))
15496         ;
15497       else if (unformat (i, "round_type %U", unformat_policer_round_type,
15498                          &round_type))
15499         ;
15500       else if (unformat (i, "type %U", unformat_policer_type, &type))
15501         ;
15502       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
15503                          &conform_action))
15504         ;
15505       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
15506                          &exceed_action))
15507         ;
15508       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
15509                          &violate_action))
15510         ;
15511       else if (unformat (i, "color-aware"))
15512         color_aware = 1;
15513       else
15514         break;
15515     }
15516
15517   if (!vec_len (name))
15518     {
15519       errmsg ("policer name must be specified");
15520       return -99;
15521     }
15522
15523   if (vec_len (name) > 64)
15524     {
15525       errmsg ("policer name too long");
15526       return -99;
15527     }
15528
15529   M (POLICER_ADD_DEL, mp);
15530
15531   clib_memcpy (mp->name, name, vec_len (name));
15532   vec_free (name);
15533   mp->is_add = is_add;
15534   mp->cir = cir;
15535   mp->eir = eir;
15536   mp->cb = cb;
15537   mp->eb = eb;
15538   mp->rate_type = rate_type;
15539   mp->round_type = round_type;
15540   mp->type = type;
15541   mp->conform_action_type = conform_action.action_type;
15542   mp->conform_dscp = conform_action.dscp;
15543   mp->exceed_action_type = exceed_action.action_type;
15544   mp->exceed_dscp = exceed_action.dscp;
15545   mp->violate_action_type = violate_action.action_type;
15546   mp->violate_dscp = violate_action.dscp;
15547   mp->color_aware = color_aware;
15548
15549   S (mp);
15550   W (ret);
15551   return ret;
15552 }
15553
15554 static int
15555 api_policer_dump (vat_main_t * vam)
15556 {
15557   unformat_input_t *i = vam->input;
15558   vl_api_policer_dump_t *mp;
15559   vl_api_control_ping_t *mp_ping;
15560   u8 *match_name = 0;
15561   u8 match_name_valid = 0;
15562   int ret;
15563
15564   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15565     {
15566       if (unformat (i, "name %s", &match_name))
15567         {
15568           vec_add1 (match_name, 0);
15569           match_name_valid = 1;
15570         }
15571       else
15572         break;
15573     }
15574
15575   M (POLICER_DUMP, mp);
15576   mp->match_name_valid = match_name_valid;
15577   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
15578   vec_free (match_name);
15579   /* send it... */
15580   S (mp);
15581
15582   /* Use a control ping for synchronization */
15583   M (CONTROL_PING, mp_ping);
15584   S (mp_ping);
15585
15586   /* Wait for a reply... */
15587   W (ret);
15588   return ret;
15589 }
15590
15591 static int
15592 api_policer_classify_set_interface (vat_main_t * vam)
15593 {
15594   unformat_input_t *i = vam->input;
15595   vl_api_policer_classify_set_interface_t *mp;
15596   u32 sw_if_index;
15597   int sw_if_index_set;
15598   u32 ip4_table_index = ~0;
15599   u32 ip6_table_index = ~0;
15600   u32 l2_table_index = ~0;
15601   u8 is_add = 1;
15602   int ret;
15603
15604   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15605     {
15606       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15607         sw_if_index_set = 1;
15608       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15609         sw_if_index_set = 1;
15610       else if (unformat (i, "del"))
15611         is_add = 0;
15612       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15613         ;
15614       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15615         ;
15616       else if (unformat (i, "l2-table %d", &l2_table_index))
15617         ;
15618       else
15619         {
15620           clib_warning ("parse error '%U'", format_unformat_error, i);
15621           return -99;
15622         }
15623     }
15624
15625   if (sw_if_index_set == 0)
15626     {
15627       errmsg ("missing interface name or sw_if_index");
15628       return -99;
15629     }
15630
15631   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
15632
15633   mp->sw_if_index = ntohl (sw_if_index);
15634   mp->ip4_table_index = ntohl (ip4_table_index);
15635   mp->ip6_table_index = ntohl (ip6_table_index);
15636   mp->l2_table_index = ntohl (l2_table_index);
15637   mp->is_add = is_add;
15638
15639   S (mp);
15640   W (ret);
15641   return ret;
15642 }
15643
15644 static int
15645 api_policer_classify_dump (vat_main_t * vam)
15646 {
15647   unformat_input_t *i = vam->input;
15648   vl_api_policer_classify_dump_t *mp;
15649   vl_api_control_ping_t *mp_ping;
15650   u8 type = POLICER_CLASSIFY_N_TABLES;
15651   int ret;
15652
15653   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
15654     ;
15655   else
15656     {
15657       errmsg ("classify table type must be specified");
15658       return -99;
15659     }
15660
15661   if (!vam->json_output)
15662     {
15663       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
15664     }
15665
15666   M (POLICER_CLASSIFY_DUMP, mp);
15667   mp->type = type;
15668   /* send it... */
15669   S (mp);
15670
15671   /* Use a control ping for synchronization */
15672   M (CONTROL_PING, mp_ping);
15673   S (mp_ping);
15674
15675   /* Wait for a reply... */
15676   W (ret);
15677   return ret;
15678 }
15679
15680 static int
15681 api_netmap_create (vat_main_t * vam)
15682 {
15683   unformat_input_t *i = vam->input;
15684   vl_api_netmap_create_t *mp;
15685   u8 *if_name = 0;
15686   u8 hw_addr[6];
15687   u8 random_hw_addr = 1;
15688   u8 is_pipe = 0;
15689   u8 is_master = 0;
15690   int ret;
15691
15692   memset (hw_addr, 0, sizeof (hw_addr));
15693
15694   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15695     {
15696       if (unformat (i, "name %s", &if_name))
15697         vec_add1 (if_name, 0);
15698       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15699         random_hw_addr = 0;
15700       else if (unformat (i, "pipe"))
15701         is_pipe = 1;
15702       else if (unformat (i, "master"))
15703         is_master = 1;
15704       else if (unformat (i, "slave"))
15705         is_master = 0;
15706       else
15707         break;
15708     }
15709
15710   if (!vec_len (if_name))
15711     {
15712       errmsg ("interface name must be specified");
15713       return -99;
15714     }
15715
15716   if (vec_len (if_name) > 64)
15717     {
15718       errmsg ("interface name too long");
15719       return -99;
15720     }
15721
15722   M (NETMAP_CREATE, mp);
15723
15724   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15725   clib_memcpy (mp->hw_addr, hw_addr, 6);
15726   mp->use_random_hw_addr = random_hw_addr;
15727   mp->is_pipe = is_pipe;
15728   mp->is_master = is_master;
15729   vec_free (if_name);
15730
15731   S (mp);
15732   W (ret);
15733   return ret;
15734 }
15735
15736 static int
15737 api_netmap_delete (vat_main_t * vam)
15738 {
15739   unformat_input_t *i = vam->input;
15740   vl_api_netmap_delete_t *mp;
15741   u8 *if_name = 0;
15742   int ret;
15743
15744   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15745     {
15746       if (unformat (i, "name %s", &if_name))
15747         vec_add1 (if_name, 0);
15748       else
15749         break;
15750     }
15751
15752   if (!vec_len (if_name))
15753     {
15754       errmsg ("interface name must be specified");
15755       return -99;
15756     }
15757
15758   if (vec_len (if_name) > 64)
15759     {
15760       errmsg ("interface name too long");
15761       return -99;
15762     }
15763
15764   M (NETMAP_DELETE, mp);
15765
15766   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15767   vec_free (if_name);
15768
15769   S (mp);
15770   W (ret);
15771   return ret;
15772 }
15773
15774 static void vl_api_mpls_tunnel_details_t_handler
15775   (vl_api_mpls_tunnel_details_t * mp)
15776 {
15777   vat_main_t *vam = &vat_main;
15778   i32 len = mp->mt_next_hop_n_labels;
15779   i32 i;
15780
15781   print (vam->ofp, "[%d]: via %U %d labels ",
15782          mp->tunnel_index,
15783          format_ip4_address, mp->mt_next_hop,
15784          ntohl (mp->mt_next_hop_sw_if_index));
15785   for (i = 0; i < len; i++)
15786     {
15787       print (vam->ofp, "%u ", ntohl (mp->mt_next_hop_out_labels[i]));
15788     }
15789   print (vam->ofp, "");
15790 }
15791
15792 static void vl_api_mpls_tunnel_details_t_handler_json
15793   (vl_api_mpls_tunnel_details_t * mp)
15794 {
15795   vat_main_t *vam = &vat_main;
15796   vat_json_node_t *node = NULL;
15797   struct in_addr ip4;
15798   i32 i;
15799   i32 len = mp->mt_next_hop_n_labels;
15800
15801   if (VAT_JSON_ARRAY != vam->json_tree.type)
15802     {
15803       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15804       vat_json_init_array (&vam->json_tree);
15805     }
15806   node = vat_json_array_add (&vam->json_tree);
15807
15808   vat_json_init_object (node);
15809   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
15810   clib_memcpy (&ip4, &(mp->mt_next_hop), sizeof (ip4));
15811   vat_json_object_add_ip4 (node, "next_hop", ip4);
15812   vat_json_object_add_uint (node, "next_hop_sw_if_index",
15813                             ntohl (mp->mt_next_hop_sw_if_index));
15814   vat_json_object_add_uint (node, "l2_only", ntohl (mp->mt_l2_only));
15815   vat_json_object_add_uint (node, "label_count", len);
15816   for (i = 0; i < len; i++)
15817     {
15818       vat_json_object_add_uint (node, "label",
15819                                 ntohl (mp->mt_next_hop_out_labels[i]));
15820     }
15821 }
15822
15823 static int
15824 api_mpls_tunnel_dump (vat_main_t * vam)
15825 {
15826   vl_api_mpls_tunnel_dump_t *mp;
15827   vl_api_control_ping_t *mp_ping;
15828   i32 index = -1;
15829   int ret;
15830
15831   /* Parse args required to build the message */
15832   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
15833     {
15834       if (!unformat (vam->input, "tunnel_index %d", &index))
15835         {
15836           index = -1;
15837           break;
15838         }
15839     }
15840
15841   print (vam->ofp, "  tunnel_index %d", index);
15842
15843   M (MPLS_TUNNEL_DUMP, mp);
15844   mp->tunnel_index = htonl (index);
15845   S (mp);
15846
15847   /* Use a control ping for synchronization */
15848   M (CONTROL_PING, mp_ping);
15849   S (mp_ping);
15850
15851   W (ret);
15852   return ret;
15853 }
15854
15855 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
15856 #define vl_api_mpls_fib_details_t_print vl_noop_handler
15857
15858 static void
15859 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
15860 {
15861   vat_main_t *vam = &vat_main;
15862   int count = ntohl (mp->count);
15863   vl_api_fib_path2_t *fp;
15864   int i;
15865
15866   print (vam->ofp,
15867          "table-id %d, label %u, ess_bit %u",
15868          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
15869   fp = mp->path;
15870   for (i = 0; i < count; i++)
15871     {
15872       if (fp->afi == IP46_TYPE_IP6)
15873         print (vam->ofp,
15874                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15875                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15876                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15877                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15878                format_ip6_address, fp->next_hop);
15879       else if (fp->afi == IP46_TYPE_IP4)
15880         print (vam->ofp,
15881                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15882                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15883                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15884                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15885                format_ip4_address, fp->next_hop);
15886       fp++;
15887     }
15888 }
15889
15890 static void vl_api_mpls_fib_details_t_handler_json
15891   (vl_api_mpls_fib_details_t * mp)
15892 {
15893   vat_main_t *vam = &vat_main;
15894   int count = ntohl (mp->count);
15895   vat_json_node_t *node = NULL;
15896   struct in_addr ip4;
15897   struct in6_addr ip6;
15898   vl_api_fib_path2_t *fp;
15899   int i;
15900
15901   if (VAT_JSON_ARRAY != vam->json_tree.type)
15902     {
15903       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15904       vat_json_init_array (&vam->json_tree);
15905     }
15906   node = vat_json_array_add (&vam->json_tree);
15907
15908   vat_json_init_object (node);
15909   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15910   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
15911   vat_json_object_add_uint (node, "label", ntohl (mp->label));
15912   vat_json_object_add_uint (node, "path_count", count);
15913   fp = mp->path;
15914   for (i = 0; i < count; i++)
15915     {
15916       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15917       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15918       vat_json_object_add_uint (node, "is_local", fp->is_local);
15919       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15920       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15921       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15922       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15923       if (fp->afi == IP46_TYPE_IP4)
15924         {
15925           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15926           vat_json_object_add_ip4 (node, "next_hop", ip4);
15927         }
15928       else if (fp->afi == IP46_TYPE_IP6)
15929         {
15930           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15931           vat_json_object_add_ip6 (node, "next_hop", ip6);
15932         }
15933     }
15934 }
15935
15936 static int
15937 api_mpls_fib_dump (vat_main_t * vam)
15938 {
15939   vl_api_mpls_fib_dump_t *mp;
15940   vl_api_control_ping_t *mp_ping;
15941   int ret;
15942
15943   M (MPLS_FIB_DUMP, mp);
15944   S (mp);
15945
15946   /* Use a control ping for synchronization */
15947   M (CONTROL_PING, mp_ping);
15948   S (mp_ping);
15949
15950   W (ret);
15951   return ret;
15952 }
15953
15954 #define vl_api_ip_fib_details_t_endian vl_noop_handler
15955 #define vl_api_ip_fib_details_t_print vl_noop_handler
15956
15957 static void
15958 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
15959 {
15960   vat_main_t *vam = &vat_main;
15961   int count = ntohl (mp->count);
15962   vl_api_fib_path_t *fp;
15963   int i;
15964
15965   print (vam->ofp,
15966          "table-id %d, prefix %U/%d",
15967          ntohl (mp->table_id), format_ip4_address, mp->address,
15968          mp->address_length);
15969   fp = mp->path;
15970   for (i = 0; i < count; i++)
15971     {
15972       if (fp->afi == IP46_TYPE_IP6)
15973         print (vam->ofp,
15974                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15975                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15976                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15977                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15978                format_ip6_address, fp->next_hop);
15979       else if (fp->afi == IP46_TYPE_IP4)
15980         print (vam->ofp,
15981                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15982                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15983                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15984                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15985                format_ip4_address, fp->next_hop);
15986       fp++;
15987     }
15988 }
15989
15990 static void vl_api_ip_fib_details_t_handler_json
15991   (vl_api_ip_fib_details_t * mp)
15992 {
15993   vat_main_t *vam = &vat_main;
15994   int count = ntohl (mp->count);
15995   vat_json_node_t *node = NULL;
15996   struct in_addr ip4;
15997   struct in6_addr ip6;
15998   vl_api_fib_path_t *fp;
15999   int i;
16000
16001   if (VAT_JSON_ARRAY != vam->json_tree.type)
16002     {
16003       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16004       vat_json_init_array (&vam->json_tree);
16005     }
16006   node = vat_json_array_add (&vam->json_tree);
16007
16008   vat_json_init_object (node);
16009   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16010   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
16011   vat_json_object_add_ip4 (node, "prefix", ip4);
16012   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16013   vat_json_object_add_uint (node, "path_count", count);
16014   fp = mp->path;
16015   for (i = 0; i < count; i++)
16016     {
16017       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16018       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16019       vat_json_object_add_uint (node, "is_local", fp->is_local);
16020       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16021       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16022       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16023       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16024       if (fp->afi == IP46_TYPE_IP4)
16025         {
16026           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16027           vat_json_object_add_ip4 (node, "next_hop", ip4);
16028         }
16029       else if (fp->afi == IP46_TYPE_IP6)
16030         {
16031           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16032           vat_json_object_add_ip6 (node, "next_hop", ip6);
16033         }
16034     }
16035 }
16036
16037 static int
16038 api_ip_fib_dump (vat_main_t * vam)
16039 {
16040   vl_api_ip_fib_dump_t *mp;
16041   vl_api_control_ping_t *mp_ping;
16042   int ret;
16043
16044   M (IP_FIB_DUMP, mp);
16045   S (mp);
16046
16047   /* Use a control ping for synchronization */
16048   M (CONTROL_PING, mp_ping);
16049   S (mp_ping);
16050
16051   W (ret);
16052   return ret;
16053 }
16054
16055 static int
16056 api_ip_mfib_dump (vat_main_t * vam)
16057 {
16058   vl_api_ip_mfib_dump_t *mp;
16059   vl_api_control_ping_t *mp_ping;
16060   int ret;
16061
16062   M (IP_MFIB_DUMP, mp);
16063   S (mp);
16064
16065   /* Use a control ping for synchronization */
16066   M (CONTROL_PING, mp_ping);
16067   S (mp_ping);
16068
16069   W (ret);
16070   return ret;
16071 }
16072
16073 static void vl_api_ip_neighbor_details_t_handler
16074   (vl_api_ip_neighbor_details_t * mp)
16075 {
16076   vat_main_t *vam = &vat_main;
16077
16078   print (vam->ofp, "%c %U %U",
16079          (mp->is_static) ? 'S' : 'D',
16080          format_ethernet_address, &mp->mac_address,
16081          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
16082          &mp->ip_address);
16083 }
16084
16085 static void vl_api_ip_neighbor_details_t_handler_json
16086   (vl_api_ip_neighbor_details_t * mp)
16087 {
16088
16089   vat_main_t *vam = &vat_main;
16090   vat_json_node_t *node;
16091   struct in_addr ip4;
16092   struct in6_addr ip6;
16093
16094   if (VAT_JSON_ARRAY != vam->json_tree.type)
16095     {
16096       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16097       vat_json_init_array (&vam->json_tree);
16098     }
16099   node = vat_json_array_add (&vam->json_tree);
16100
16101   vat_json_init_object (node);
16102   vat_json_object_add_string_copy (node, "flag",
16103                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
16104                                    "dynamic");
16105
16106   vat_json_object_add_string_copy (node, "link_layer",
16107                                    format (0, "%U", format_ethernet_address,
16108                                            &mp->mac_address));
16109
16110   if (mp->is_ipv6)
16111     {
16112       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
16113       vat_json_object_add_ip6 (node, "ip_address", ip6);
16114     }
16115   else
16116     {
16117       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
16118       vat_json_object_add_ip4 (node, "ip_address", ip4);
16119     }
16120 }
16121
16122 static int
16123 api_ip_neighbor_dump (vat_main_t * vam)
16124 {
16125   unformat_input_t *i = vam->input;
16126   vl_api_ip_neighbor_dump_t *mp;
16127   vl_api_control_ping_t *mp_ping;
16128   u8 is_ipv6 = 0;
16129   u32 sw_if_index = ~0;
16130   int ret;
16131
16132   /* Parse args required to build the message */
16133   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16134     {
16135       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16136         ;
16137       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16138         ;
16139       else if (unformat (i, "ip6"))
16140         is_ipv6 = 1;
16141       else
16142         break;
16143     }
16144
16145   if (sw_if_index == ~0)
16146     {
16147       errmsg ("missing interface name or sw_if_index");
16148       return -99;
16149     }
16150
16151   M (IP_NEIGHBOR_DUMP, mp);
16152   mp->is_ipv6 = (u8) is_ipv6;
16153   mp->sw_if_index = ntohl (sw_if_index);
16154   S (mp);
16155
16156   /* Use a control ping for synchronization */
16157   M (CONTROL_PING, mp_ping);
16158   S (mp_ping);
16159
16160   W (ret);
16161   return ret;
16162 }
16163
16164 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
16165 #define vl_api_ip6_fib_details_t_print vl_noop_handler
16166
16167 static void
16168 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
16169 {
16170   vat_main_t *vam = &vat_main;
16171   int count = ntohl (mp->count);
16172   vl_api_fib_path_t *fp;
16173   int i;
16174
16175   print (vam->ofp,
16176          "table-id %d, prefix %U/%d",
16177          ntohl (mp->table_id), format_ip6_address, mp->address,
16178          mp->address_length);
16179   fp = mp->path;
16180   for (i = 0; i < count; i++)
16181     {
16182       if (fp->afi == IP46_TYPE_IP6)
16183         print (vam->ofp,
16184                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16185                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16186                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16187                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16188                format_ip6_address, fp->next_hop);
16189       else if (fp->afi == IP46_TYPE_IP4)
16190         print (vam->ofp,
16191                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16192                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16193                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16194                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16195                format_ip4_address, fp->next_hop);
16196       fp++;
16197     }
16198 }
16199
16200 static void vl_api_ip6_fib_details_t_handler_json
16201   (vl_api_ip6_fib_details_t * mp)
16202 {
16203   vat_main_t *vam = &vat_main;
16204   int count = ntohl (mp->count);
16205   vat_json_node_t *node = NULL;
16206   struct in_addr ip4;
16207   struct in6_addr ip6;
16208   vl_api_fib_path_t *fp;
16209   int i;
16210
16211   if (VAT_JSON_ARRAY != vam->json_tree.type)
16212     {
16213       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16214       vat_json_init_array (&vam->json_tree);
16215     }
16216   node = vat_json_array_add (&vam->json_tree);
16217
16218   vat_json_init_object (node);
16219   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16220   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
16221   vat_json_object_add_ip6 (node, "prefix", ip6);
16222   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16223   vat_json_object_add_uint (node, "path_count", count);
16224   fp = mp->path;
16225   for (i = 0; i < count; i++)
16226     {
16227       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16228       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16229       vat_json_object_add_uint (node, "is_local", fp->is_local);
16230       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16231       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16232       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16233       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16234       if (fp->afi == IP46_TYPE_IP4)
16235         {
16236           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16237           vat_json_object_add_ip4 (node, "next_hop", ip4);
16238         }
16239       else if (fp->afi == IP46_TYPE_IP6)
16240         {
16241           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16242           vat_json_object_add_ip6 (node, "next_hop", ip6);
16243         }
16244     }
16245 }
16246
16247 static int
16248 api_ip6_fib_dump (vat_main_t * vam)
16249 {
16250   vl_api_ip6_fib_dump_t *mp;
16251   vl_api_control_ping_t *mp_ping;
16252   int ret;
16253
16254   M (IP6_FIB_DUMP, mp);
16255   S (mp);
16256
16257   /* Use a control ping for synchronization */
16258   M (CONTROL_PING, mp_ping);
16259   S (mp_ping);
16260
16261   W (ret);
16262   return ret;
16263 }
16264
16265 static int
16266 api_ip6_mfib_dump (vat_main_t * vam)
16267 {
16268   vl_api_ip6_mfib_dump_t *mp;
16269   vl_api_control_ping_t *mp_ping;
16270   int ret;
16271
16272   M (IP6_MFIB_DUMP, mp);
16273   S (mp);
16274
16275   /* Use a control ping for synchronization */
16276   M (CONTROL_PING, mp_ping);
16277   S (mp_ping);
16278
16279   W (ret);
16280   return ret;
16281 }
16282
16283 int
16284 api_classify_table_ids (vat_main_t * vam)
16285 {
16286   vl_api_classify_table_ids_t *mp;
16287   int ret;
16288
16289   /* Construct the API message */
16290   M (CLASSIFY_TABLE_IDS, mp);
16291   mp->context = 0;
16292
16293   S (mp);
16294   W (ret);
16295   return ret;
16296 }
16297
16298 int
16299 api_classify_table_by_interface (vat_main_t * vam)
16300 {
16301   unformat_input_t *input = vam->input;
16302   vl_api_classify_table_by_interface_t *mp;
16303
16304   u32 sw_if_index = ~0;
16305   int ret;
16306   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16307     {
16308       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16309         ;
16310       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16311         ;
16312       else
16313         break;
16314     }
16315   if (sw_if_index == ~0)
16316     {
16317       errmsg ("missing interface name or sw_if_index");
16318       return -99;
16319     }
16320
16321   /* Construct the API message */
16322   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
16323   mp->context = 0;
16324   mp->sw_if_index = ntohl (sw_if_index);
16325
16326   S (mp);
16327   W (ret);
16328   return ret;
16329 }
16330
16331 int
16332 api_classify_table_info (vat_main_t * vam)
16333 {
16334   unformat_input_t *input = vam->input;
16335   vl_api_classify_table_info_t *mp;
16336
16337   u32 table_id = ~0;
16338   int ret;
16339   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16340     {
16341       if (unformat (input, "table_id %d", &table_id))
16342         ;
16343       else
16344         break;
16345     }
16346   if (table_id == ~0)
16347     {
16348       errmsg ("missing table id");
16349       return -99;
16350     }
16351
16352   /* Construct the API message */
16353   M (CLASSIFY_TABLE_INFO, mp);
16354   mp->context = 0;
16355   mp->table_id = ntohl (table_id);
16356
16357   S (mp);
16358   W (ret);
16359   return ret;
16360 }
16361
16362 int
16363 api_classify_session_dump (vat_main_t * vam)
16364 {
16365   unformat_input_t *input = vam->input;
16366   vl_api_classify_session_dump_t *mp;
16367   vl_api_control_ping_t *mp_ping;
16368
16369   u32 table_id = ~0;
16370   int ret;
16371   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16372     {
16373       if (unformat (input, "table_id %d", &table_id))
16374         ;
16375       else
16376         break;
16377     }
16378   if (table_id == ~0)
16379     {
16380       errmsg ("missing table id");
16381       return -99;
16382     }
16383
16384   /* Construct the API message */
16385   M (CLASSIFY_SESSION_DUMP, mp);
16386   mp->context = 0;
16387   mp->table_id = ntohl (table_id);
16388   S (mp);
16389
16390   /* Use a control ping for synchronization */
16391   M (CONTROL_PING, mp_ping);
16392   S (mp_ping);
16393
16394   W (ret);
16395   return ret;
16396 }
16397
16398 static void
16399 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
16400 {
16401   vat_main_t *vam = &vat_main;
16402
16403   print (vam->ofp, "collector_address %U, collector_port %d, "
16404          "src_address %U, vrf_id %d, path_mtu %u, "
16405          "template_interval %u, udp_checksum %d",
16406          format_ip4_address, mp->collector_address,
16407          ntohs (mp->collector_port),
16408          format_ip4_address, mp->src_address,
16409          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
16410          ntohl (mp->template_interval), mp->udp_checksum);
16411
16412   vam->retval = 0;
16413   vam->result_ready = 1;
16414 }
16415
16416 static void
16417   vl_api_ipfix_exporter_details_t_handler_json
16418   (vl_api_ipfix_exporter_details_t * mp)
16419 {
16420   vat_main_t *vam = &vat_main;
16421   vat_json_node_t node;
16422   struct in_addr collector_address;
16423   struct in_addr src_address;
16424
16425   vat_json_init_object (&node);
16426   clib_memcpy (&collector_address, &mp->collector_address,
16427                sizeof (collector_address));
16428   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
16429   vat_json_object_add_uint (&node, "collector_port",
16430                             ntohs (mp->collector_port));
16431   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
16432   vat_json_object_add_ip4 (&node, "src_address", src_address);
16433   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
16434   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
16435   vat_json_object_add_uint (&node, "template_interval",
16436                             ntohl (mp->template_interval));
16437   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
16438
16439   vat_json_print (vam->ofp, &node);
16440   vat_json_free (&node);
16441   vam->retval = 0;
16442   vam->result_ready = 1;
16443 }
16444
16445 int
16446 api_ipfix_exporter_dump (vat_main_t * vam)
16447 {
16448   vl_api_ipfix_exporter_dump_t *mp;
16449   int ret;
16450
16451   /* Construct the API message */
16452   M (IPFIX_EXPORTER_DUMP, mp);
16453   mp->context = 0;
16454
16455   S (mp);
16456   W (ret);
16457   return ret;
16458 }
16459
16460 static int
16461 api_ipfix_classify_stream_dump (vat_main_t * vam)
16462 {
16463   vl_api_ipfix_classify_stream_dump_t *mp;
16464   int ret;
16465
16466   /* Construct the API message */
16467   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
16468   mp->context = 0;
16469
16470   S (mp);
16471   W (ret);
16472   return ret;
16473   /* NOTREACHED */
16474   return 0;
16475 }
16476
16477 static void
16478   vl_api_ipfix_classify_stream_details_t_handler
16479   (vl_api_ipfix_classify_stream_details_t * mp)
16480 {
16481   vat_main_t *vam = &vat_main;
16482   print (vam->ofp, "domain_id %d, src_port %d",
16483          ntohl (mp->domain_id), ntohs (mp->src_port));
16484   vam->retval = 0;
16485   vam->result_ready = 1;
16486 }
16487
16488 static void
16489   vl_api_ipfix_classify_stream_details_t_handler_json
16490   (vl_api_ipfix_classify_stream_details_t * mp)
16491 {
16492   vat_main_t *vam = &vat_main;
16493   vat_json_node_t node;
16494
16495   vat_json_init_object (&node);
16496   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
16497   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
16498
16499   vat_json_print (vam->ofp, &node);
16500   vat_json_free (&node);
16501   vam->retval = 0;
16502   vam->result_ready = 1;
16503 }
16504
16505 static int
16506 api_ipfix_classify_table_dump (vat_main_t * vam)
16507 {
16508   vl_api_ipfix_classify_table_dump_t *mp;
16509   vl_api_control_ping_t *mp_ping;
16510   int ret;
16511
16512   if (!vam->json_output)
16513     {
16514       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
16515              "transport_protocol");
16516     }
16517
16518   /* Construct the API message */
16519   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
16520
16521   /* send it... */
16522   S (mp);
16523
16524   /* Use a control ping for synchronization */
16525   M (CONTROL_PING, mp_ping);
16526   S (mp_ping);
16527
16528   W (ret);
16529   return ret;
16530 }
16531
16532 static void
16533   vl_api_ipfix_classify_table_details_t_handler
16534   (vl_api_ipfix_classify_table_details_t * mp)
16535 {
16536   vat_main_t *vam = &vat_main;
16537   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
16538          mp->transport_protocol);
16539 }
16540
16541 static void
16542   vl_api_ipfix_classify_table_details_t_handler_json
16543   (vl_api_ipfix_classify_table_details_t * mp)
16544 {
16545   vat_json_node_t *node = NULL;
16546   vat_main_t *vam = &vat_main;
16547
16548   if (VAT_JSON_ARRAY != vam->json_tree.type)
16549     {
16550       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16551       vat_json_init_array (&vam->json_tree);
16552     }
16553
16554   node = vat_json_array_add (&vam->json_tree);
16555   vat_json_init_object (node);
16556
16557   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
16558   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
16559   vat_json_object_add_uint (node, "transport_protocol",
16560                             mp->transport_protocol);
16561 }
16562
16563 static int
16564 api_sw_interface_span_enable_disable (vat_main_t * vam)
16565 {
16566   unformat_input_t *i = vam->input;
16567   vl_api_sw_interface_span_enable_disable_t *mp;
16568   u32 src_sw_if_index = ~0;
16569   u32 dst_sw_if_index = ~0;
16570   u8 state = 3;
16571   int ret;
16572
16573   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16574     {
16575       if (unformat
16576           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
16577         ;
16578       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
16579         ;
16580       else
16581         if (unformat
16582             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
16583         ;
16584       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
16585         ;
16586       else if (unformat (i, "disable"))
16587         state = 0;
16588       else if (unformat (i, "rx"))
16589         state = 1;
16590       else if (unformat (i, "tx"))
16591         state = 2;
16592       else if (unformat (i, "both"))
16593         state = 3;
16594       else
16595         break;
16596     }
16597
16598   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
16599
16600   mp->sw_if_index_from = htonl (src_sw_if_index);
16601   mp->sw_if_index_to = htonl (dst_sw_if_index);
16602   mp->state = state;
16603
16604   S (mp);
16605   W (ret);
16606   return ret;
16607 }
16608
16609 static void
16610 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
16611                                             * mp)
16612 {
16613   vat_main_t *vam = &vat_main;
16614   u8 *sw_if_from_name = 0;
16615   u8 *sw_if_to_name = 0;
16616   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16617   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16618   char *states[] = { "none", "rx", "tx", "both" };
16619   hash_pair_t *p;
16620
16621   /* *INDENT-OFF* */
16622   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16623   ({
16624     if ((u32) p->value[0] == sw_if_index_from)
16625       {
16626         sw_if_from_name = (u8 *)(p->key);
16627         if (sw_if_to_name)
16628           break;
16629       }
16630     if ((u32) p->value[0] == sw_if_index_to)
16631       {
16632         sw_if_to_name = (u8 *)(p->key);
16633         if (sw_if_from_name)
16634           break;
16635       }
16636   }));
16637   /* *INDENT-ON* */
16638   print (vam->ofp, "%20s => %20s (%s)",
16639          sw_if_from_name, sw_if_to_name, states[mp->state]);
16640 }
16641
16642 static void
16643   vl_api_sw_interface_span_details_t_handler_json
16644   (vl_api_sw_interface_span_details_t * mp)
16645 {
16646   vat_main_t *vam = &vat_main;
16647   vat_json_node_t *node = NULL;
16648   u8 *sw_if_from_name = 0;
16649   u8 *sw_if_to_name = 0;
16650   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16651   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16652   hash_pair_t *p;
16653
16654   /* *INDENT-OFF* */
16655   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16656   ({
16657     if ((u32) p->value[0] == sw_if_index_from)
16658       {
16659         sw_if_from_name = (u8 *)(p->key);
16660         if (sw_if_to_name)
16661           break;
16662       }
16663     if ((u32) p->value[0] == sw_if_index_to)
16664       {
16665         sw_if_to_name = (u8 *)(p->key);
16666         if (sw_if_from_name)
16667           break;
16668       }
16669   }));
16670   /* *INDENT-ON* */
16671
16672   if (VAT_JSON_ARRAY != vam->json_tree.type)
16673     {
16674       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16675       vat_json_init_array (&vam->json_tree);
16676     }
16677   node = vat_json_array_add (&vam->json_tree);
16678
16679   vat_json_init_object (node);
16680   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
16681   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
16682   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
16683   if (0 != sw_if_to_name)
16684     {
16685       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
16686     }
16687   vat_json_object_add_uint (node, "state", mp->state);
16688 }
16689
16690 static int
16691 api_sw_interface_span_dump (vat_main_t * vam)
16692 {
16693   vl_api_sw_interface_span_dump_t *mp;
16694   vl_api_control_ping_t *mp_ping;
16695   int ret;
16696
16697   M (SW_INTERFACE_SPAN_DUMP, mp);
16698   S (mp);
16699
16700   /* Use a control ping for synchronization */
16701   M (CONTROL_PING, mp_ping);
16702   S (mp_ping);
16703
16704   W (ret);
16705   return ret;
16706 }
16707
16708 int
16709 api_pg_create_interface (vat_main_t * vam)
16710 {
16711   unformat_input_t *input = vam->input;
16712   vl_api_pg_create_interface_t *mp;
16713
16714   u32 if_id = ~0;
16715   int ret;
16716   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16717     {
16718       if (unformat (input, "if_id %d", &if_id))
16719         ;
16720       else
16721         break;
16722     }
16723   if (if_id == ~0)
16724     {
16725       errmsg ("missing pg interface index");
16726       return -99;
16727     }
16728
16729   /* Construct the API message */
16730   M (PG_CREATE_INTERFACE, mp);
16731   mp->context = 0;
16732   mp->interface_id = ntohl (if_id);
16733
16734   S (mp);
16735   W (ret);
16736   return ret;
16737 }
16738
16739 int
16740 api_pg_capture (vat_main_t * vam)
16741 {
16742   unformat_input_t *input = vam->input;
16743   vl_api_pg_capture_t *mp;
16744
16745   u32 if_id = ~0;
16746   u8 enable = 1;
16747   u32 count = 1;
16748   u8 pcap_file_set = 0;
16749   u8 *pcap_file = 0;
16750   int ret;
16751   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16752     {
16753       if (unformat (input, "if_id %d", &if_id))
16754         ;
16755       else if (unformat (input, "pcap %s", &pcap_file))
16756         pcap_file_set = 1;
16757       else if (unformat (input, "count %d", &count))
16758         ;
16759       else if (unformat (input, "disable"))
16760         enable = 0;
16761       else
16762         break;
16763     }
16764   if (if_id == ~0)
16765     {
16766       errmsg ("missing pg interface index");
16767       return -99;
16768     }
16769   if (pcap_file_set > 0)
16770     {
16771       if (vec_len (pcap_file) > 255)
16772         {
16773           errmsg ("pcap file name is too long");
16774           return -99;
16775         }
16776     }
16777
16778   u32 name_len = vec_len (pcap_file);
16779   /* Construct the API message */
16780   M (PG_CAPTURE, mp);
16781   mp->context = 0;
16782   mp->interface_id = ntohl (if_id);
16783   mp->is_enabled = enable;
16784   mp->count = ntohl (count);
16785   mp->pcap_name_length = ntohl (name_len);
16786   if (pcap_file_set != 0)
16787     {
16788       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
16789     }
16790   vec_free (pcap_file);
16791
16792   S (mp);
16793   W (ret);
16794   return ret;
16795 }
16796
16797 int
16798 api_pg_enable_disable (vat_main_t * vam)
16799 {
16800   unformat_input_t *input = vam->input;
16801   vl_api_pg_enable_disable_t *mp;
16802
16803   u8 enable = 1;
16804   u8 stream_name_set = 0;
16805   u8 *stream_name = 0;
16806   int ret;
16807   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16808     {
16809       if (unformat (input, "stream %s", &stream_name))
16810         stream_name_set = 1;
16811       else if (unformat (input, "disable"))
16812         enable = 0;
16813       else
16814         break;
16815     }
16816
16817   if (stream_name_set > 0)
16818     {
16819       if (vec_len (stream_name) > 255)
16820         {
16821           errmsg ("stream name too long");
16822           return -99;
16823         }
16824     }
16825
16826   u32 name_len = vec_len (stream_name);
16827   /* Construct the API message */
16828   M (PG_ENABLE_DISABLE, mp);
16829   mp->context = 0;
16830   mp->is_enabled = enable;
16831   if (stream_name_set != 0)
16832     {
16833       mp->stream_name_length = ntohl (name_len);
16834       clib_memcpy (mp->stream_name, stream_name, name_len);
16835     }
16836   vec_free (stream_name);
16837
16838   S (mp);
16839   W (ret);
16840   return ret;
16841 }
16842
16843 int
16844 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
16845 {
16846   unformat_input_t *input = vam->input;
16847   vl_api_ip_source_and_port_range_check_add_del_t *mp;
16848
16849   u16 *low_ports = 0;
16850   u16 *high_ports = 0;
16851   u16 this_low;
16852   u16 this_hi;
16853   ip4_address_t ip4_addr;
16854   ip6_address_t ip6_addr;
16855   u32 length;
16856   u32 tmp, tmp2;
16857   u8 prefix_set = 0;
16858   u32 vrf_id = ~0;
16859   u8 is_add = 1;
16860   u8 is_ipv6 = 0;
16861   int ret;
16862
16863   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16864     {
16865       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
16866         {
16867           prefix_set = 1;
16868         }
16869       else
16870         if (unformat
16871             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
16872         {
16873           prefix_set = 1;
16874           is_ipv6 = 1;
16875         }
16876       else if (unformat (input, "vrf %d", &vrf_id))
16877         ;
16878       else if (unformat (input, "del"))
16879         is_add = 0;
16880       else if (unformat (input, "port %d", &tmp))
16881         {
16882           if (tmp == 0 || tmp > 65535)
16883             {
16884               errmsg ("port %d out of range", tmp);
16885               return -99;
16886             }
16887           this_low = tmp;
16888           this_hi = this_low + 1;
16889           vec_add1 (low_ports, this_low);
16890           vec_add1 (high_ports, this_hi);
16891         }
16892       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
16893         {
16894           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
16895             {
16896               errmsg ("incorrect range parameters");
16897               return -99;
16898             }
16899           this_low = tmp;
16900           /* Note: in debug CLI +1 is added to high before
16901              passing to real fn that does "the work"
16902              (ip_source_and_port_range_check_add_del).
16903              This fn is a wrapper around the binary API fn a
16904              control plane will call, which expects this increment
16905              to have occurred. Hence letting the binary API control
16906              plane fn do the increment for consistency between VAT
16907              and other control planes.
16908            */
16909           this_hi = tmp2;
16910           vec_add1 (low_ports, this_low);
16911           vec_add1 (high_ports, this_hi);
16912         }
16913       else
16914         break;
16915     }
16916
16917   if (prefix_set == 0)
16918     {
16919       errmsg ("<address>/<mask> not specified");
16920       return -99;
16921     }
16922
16923   if (vrf_id == ~0)
16924     {
16925       errmsg ("VRF ID required, not specified");
16926       return -99;
16927     }
16928
16929   if (vrf_id == 0)
16930     {
16931       errmsg
16932         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
16933       return -99;
16934     }
16935
16936   if (vec_len (low_ports) == 0)
16937     {
16938       errmsg ("At least one port or port range required");
16939       return -99;
16940     }
16941
16942   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
16943
16944   mp->is_add = is_add;
16945
16946   if (is_ipv6)
16947     {
16948       mp->is_ipv6 = 1;
16949       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
16950     }
16951   else
16952     {
16953       mp->is_ipv6 = 0;
16954       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
16955     }
16956
16957   mp->mask_length = length;
16958   mp->number_of_ranges = vec_len (low_ports);
16959
16960   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
16961   vec_free (low_ports);
16962
16963   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
16964   vec_free (high_ports);
16965
16966   mp->vrf_id = ntohl (vrf_id);
16967
16968   S (mp);
16969   W (ret);
16970   return ret;
16971 }
16972
16973 int
16974 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
16975 {
16976   unformat_input_t *input = vam->input;
16977   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
16978   u32 sw_if_index = ~0;
16979   int vrf_set = 0;
16980   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
16981   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
16982   u8 is_add = 1;
16983   int ret;
16984
16985   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16986     {
16987       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16988         ;
16989       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16990         ;
16991       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
16992         vrf_set = 1;
16993       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
16994         vrf_set = 1;
16995       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
16996         vrf_set = 1;
16997       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
16998         vrf_set = 1;
16999       else if (unformat (input, "del"))
17000         is_add = 0;
17001       else
17002         break;
17003     }
17004
17005   if (sw_if_index == ~0)
17006     {
17007       errmsg ("Interface required but not specified");
17008       return -99;
17009     }
17010
17011   if (vrf_set == 0)
17012     {
17013       errmsg ("VRF ID required but not specified");
17014       return -99;
17015     }
17016
17017   if (tcp_out_vrf_id == 0
17018       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
17019     {
17020       errmsg
17021         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17022       return -99;
17023     }
17024
17025   /* Construct the API message */
17026   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
17027
17028   mp->sw_if_index = ntohl (sw_if_index);
17029   mp->is_add = is_add;
17030   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
17031   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
17032   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
17033   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
17034
17035   /* send it... */
17036   S (mp);
17037
17038   /* Wait for a reply... */
17039   W (ret);
17040   return ret;
17041 }
17042
17043 static int
17044 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
17045 {
17046   unformat_input_t *i = vam->input;
17047   vl_api_ipsec_gre_add_del_tunnel_t *mp;
17048   u32 local_sa_id = 0;
17049   u32 remote_sa_id = 0;
17050   ip4_address_t src_address;
17051   ip4_address_t dst_address;
17052   u8 is_add = 1;
17053   int ret;
17054
17055   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17056     {
17057       if (unformat (i, "local_sa %d", &local_sa_id))
17058         ;
17059       else if (unformat (i, "remote_sa %d", &remote_sa_id))
17060         ;
17061       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
17062         ;
17063       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
17064         ;
17065       else if (unformat (i, "del"))
17066         is_add = 0;
17067       else
17068         {
17069           clib_warning ("parse error '%U'", format_unformat_error, i);
17070           return -99;
17071         }
17072     }
17073
17074   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
17075
17076   mp->local_sa_id = ntohl (local_sa_id);
17077   mp->remote_sa_id = ntohl (remote_sa_id);
17078   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
17079   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
17080   mp->is_add = is_add;
17081
17082   S (mp);
17083   W (ret);
17084   return ret;
17085 }
17086
17087 static int
17088 api_punt (vat_main_t * vam)
17089 {
17090   unformat_input_t *i = vam->input;
17091   vl_api_punt_t *mp;
17092   u32 ipv = ~0;
17093   u32 protocol = ~0;
17094   u32 port = ~0;
17095   int is_add = 1;
17096   int ret;
17097
17098   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17099     {
17100       if (unformat (i, "ip %d", &ipv))
17101         ;
17102       else if (unformat (i, "protocol %d", &protocol))
17103         ;
17104       else if (unformat (i, "port %d", &port))
17105         ;
17106       else if (unformat (i, "del"))
17107         is_add = 0;
17108       else
17109         {
17110           clib_warning ("parse error '%U'", format_unformat_error, i);
17111           return -99;
17112         }
17113     }
17114
17115   M (PUNT, mp);
17116
17117   mp->is_add = (u8) is_add;
17118   mp->ipv = (u8) ipv;
17119   mp->l4_protocol = (u8) protocol;
17120   mp->l4_port = htons ((u16) port);
17121
17122   S (mp);
17123   W (ret);
17124   return ret;
17125 }
17126
17127 static void vl_api_ipsec_gre_tunnel_details_t_handler
17128   (vl_api_ipsec_gre_tunnel_details_t * mp)
17129 {
17130   vat_main_t *vam = &vat_main;
17131
17132   print (vam->ofp, "%11d%15U%15U%14d%14d",
17133          ntohl (mp->sw_if_index),
17134          format_ip4_address, &mp->src_address,
17135          format_ip4_address, &mp->dst_address,
17136          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
17137 }
17138
17139 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
17140   (vl_api_ipsec_gre_tunnel_details_t * mp)
17141 {
17142   vat_main_t *vam = &vat_main;
17143   vat_json_node_t *node = NULL;
17144   struct in_addr ip4;
17145
17146   if (VAT_JSON_ARRAY != vam->json_tree.type)
17147     {
17148       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17149       vat_json_init_array (&vam->json_tree);
17150     }
17151   node = vat_json_array_add (&vam->json_tree);
17152
17153   vat_json_init_object (node);
17154   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17155   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
17156   vat_json_object_add_ip4 (node, "src_address", ip4);
17157   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
17158   vat_json_object_add_ip4 (node, "dst_address", ip4);
17159   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
17160   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
17161 }
17162
17163 static int
17164 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
17165 {
17166   unformat_input_t *i = vam->input;
17167   vl_api_ipsec_gre_tunnel_dump_t *mp;
17168   vl_api_control_ping_t *mp_ping;
17169   u32 sw_if_index;
17170   u8 sw_if_index_set = 0;
17171   int ret;
17172
17173   /* Parse args required to build the message */
17174   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17175     {
17176       if (unformat (i, "sw_if_index %d", &sw_if_index))
17177         sw_if_index_set = 1;
17178       else
17179         break;
17180     }
17181
17182   if (sw_if_index_set == 0)
17183     {
17184       sw_if_index = ~0;
17185     }
17186
17187   if (!vam->json_output)
17188     {
17189       print (vam->ofp, "%11s%15s%15s%14s%14s",
17190              "sw_if_index", "src_address", "dst_address",
17191              "local_sa_id", "remote_sa_id");
17192     }
17193
17194   /* Get list of gre-tunnel interfaces */
17195   M (IPSEC_GRE_TUNNEL_DUMP, mp);
17196
17197   mp->sw_if_index = htonl (sw_if_index);
17198
17199   S (mp);
17200
17201   /* Use a control ping for synchronization */
17202   M (CONTROL_PING, mp_ping);
17203   S (mp_ping);
17204
17205   W (ret);
17206   return ret;
17207 }
17208
17209 static int
17210 api_delete_subif (vat_main_t * vam)
17211 {
17212   unformat_input_t *i = vam->input;
17213   vl_api_delete_subif_t *mp;
17214   u32 sw_if_index = ~0;
17215   int ret;
17216
17217   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17218     {
17219       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17220         ;
17221       if (unformat (i, "sw_if_index %d", &sw_if_index))
17222         ;
17223       else
17224         break;
17225     }
17226
17227   if (sw_if_index == ~0)
17228     {
17229       errmsg ("missing sw_if_index");
17230       return -99;
17231     }
17232
17233   /* Construct the API message */
17234   M (DELETE_SUBIF, mp);
17235   mp->sw_if_index = ntohl (sw_if_index);
17236
17237   S (mp);
17238   W (ret);
17239   return ret;
17240 }
17241
17242 #define foreach_pbb_vtr_op      \
17243 _("disable",  L2_VTR_DISABLED)  \
17244 _("pop",  L2_VTR_POP_2)         \
17245 _("push",  L2_VTR_PUSH_2)
17246
17247 static int
17248 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
17249 {
17250   unformat_input_t *i = vam->input;
17251   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
17252   u32 sw_if_index = ~0, vtr_op = ~0;
17253   u16 outer_tag = ~0;
17254   u8 dmac[6], smac[6];
17255   u8 dmac_set = 0, smac_set = 0;
17256   u16 vlanid = 0;
17257   u32 sid = ~0;
17258   u32 tmp;
17259   int ret;
17260
17261   /* Shut up coverity */
17262   memset (dmac, 0, sizeof (dmac));
17263   memset (smac, 0, sizeof (smac));
17264
17265   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17266     {
17267       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17268         ;
17269       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17270         ;
17271       else if (unformat (i, "vtr_op %d", &vtr_op))
17272         ;
17273 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
17274       foreach_pbb_vtr_op
17275 #undef _
17276         else if (unformat (i, "translate_pbb_stag"))
17277         {
17278           if (unformat (i, "%d", &tmp))
17279             {
17280               vtr_op = L2_VTR_TRANSLATE_2_1;
17281               outer_tag = tmp;
17282             }
17283           else
17284             {
17285               errmsg
17286                 ("translate_pbb_stag operation requires outer tag definition");
17287               return -99;
17288             }
17289         }
17290       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
17291         dmac_set++;
17292       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
17293         smac_set++;
17294       else if (unformat (i, "sid %d", &sid))
17295         ;
17296       else if (unformat (i, "vlanid %d", &tmp))
17297         vlanid = tmp;
17298       else
17299         {
17300           clib_warning ("parse error '%U'", format_unformat_error, i);
17301           return -99;
17302         }
17303     }
17304
17305   if ((sw_if_index == ~0) || (vtr_op == ~0))
17306     {
17307       errmsg ("missing sw_if_index or vtr operation");
17308       return -99;
17309     }
17310   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
17311       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
17312     {
17313       errmsg
17314         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
17315       return -99;
17316     }
17317
17318   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
17319   mp->sw_if_index = ntohl (sw_if_index);
17320   mp->vtr_op = ntohl (vtr_op);
17321   mp->outer_tag = ntohs (outer_tag);
17322   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
17323   clib_memcpy (mp->b_smac, smac, sizeof (smac));
17324   mp->b_vlanid = ntohs (vlanid);
17325   mp->i_sid = ntohl (sid);
17326
17327   S (mp);
17328   W (ret);
17329   return ret;
17330 }
17331
17332 static int
17333 api_flow_classify_set_interface (vat_main_t * vam)
17334 {
17335   unformat_input_t *i = vam->input;
17336   vl_api_flow_classify_set_interface_t *mp;
17337   u32 sw_if_index;
17338   int sw_if_index_set;
17339   u32 ip4_table_index = ~0;
17340   u32 ip6_table_index = ~0;
17341   u8 is_add = 1;
17342   int ret;
17343
17344   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17345     {
17346       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17347         sw_if_index_set = 1;
17348       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17349         sw_if_index_set = 1;
17350       else if (unformat (i, "del"))
17351         is_add = 0;
17352       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17353         ;
17354       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17355         ;
17356       else
17357         {
17358           clib_warning ("parse error '%U'", format_unformat_error, i);
17359           return -99;
17360         }
17361     }
17362
17363   if (sw_if_index_set == 0)
17364     {
17365       errmsg ("missing interface name or sw_if_index");
17366       return -99;
17367     }
17368
17369   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
17370
17371   mp->sw_if_index = ntohl (sw_if_index);
17372   mp->ip4_table_index = ntohl (ip4_table_index);
17373   mp->ip6_table_index = ntohl (ip6_table_index);
17374   mp->is_add = is_add;
17375
17376   S (mp);
17377   W (ret);
17378   return ret;
17379 }
17380
17381 static int
17382 api_flow_classify_dump (vat_main_t * vam)
17383 {
17384   unformat_input_t *i = vam->input;
17385   vl_api_flow_classify_dump_t *mp;
17386   vl_api_control_ping_t *mp_ping;
17387   u8 type = FLOW_CLASSIFY_N_TABLES;
17388   int ret;
17389
17390   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
17391     ;
17392   else
17393     {
17394       errmsg ("classify table type must be specified");
17395       return -99;
17396     }
17397
17398   if (!vam->json_output)
17399     {
17400       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17401     }
17402
17403   M (FLOW_CLASSIFY_DUMP, mp);
17404   mp->type = type;
17405   /* send it... */
17406   S (mp);
17407
17408   /* Use a control ping for synchronization */
17409   M (CONTROL_PING, mp_ping);
17410   S (mp_ping);
17411
17412   /* Wait for a reply... */
17413   W (ret);
17414   return ret;
17415 }
17416
17417 static int
17418 api_feature_enable_disable (vat_main_t * vam)
17419 {
17420   unformat_input_t *i = vam->input;
17421   vl_api_feature_enable_disable_t *mp;
17422   u8 *arc_name = 0;
17423   u8 *feature_name = 0;
17424   u32 sw_if_index = ~0;
17425   u8 enable = 1;
17426   int ret;
17427
17428   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17429     {
17430       if (unformat (i, "arc_name %s", &arc_name))
17431         ;
17432       else if (unformat (i, "feature_name %s", &feature_name))
17433         ;
17434       else
17435         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17436         ;
17437       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17438         ;
17439       else if (unformat (i, "disable"))
17440         enable = 0;
17441       else
17442         break;
17443     }
17444
17445   if (arc_name == 0)
17446     {
17447       errmsg ("missing arc name");
17448       return -99;
17449     }
17450   if (vec_len (arc_name) > 63)
17451     {
17452       errmsg ("arc name too long");
17453     }
17454
17455   if (feature_name == 0)
17456     {
17457       errmsg ("missing feature name");
17458       return -99;
17459     }
17460   if (vec_len (feature_name) > 63)
17461     {
17462       errmsg ("feature name too long");
17463     }
17464
17465   if (sw_if_index == ~0)
17466     {
17467       errmsg ("missing interface name or sw_if_index");
17468       return -99;
17469     }
17470
17471   /* Construct the API message */
17472   M (FEATURE_ENABLE_DISABLE, mp);
17473   mp->sw_if_index = ntohl (sw_if_index);
17474   mp->enable = enable;
17475   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
17476   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
17477   vec_free (arc_name);
17478   vec_free (feature_name);
17479
17480   S (mp);
17481   W (ret);
17482   return ret;
17483 }
17484
17485 static int
17486 api_sw_interface_tag_add_del (vat_main_t * vam)
17487 {
17488   unformat_input_t *i = vam->input;
17489   vl_api_sw_interface_tag_add_del_t *mp;
17490   u32 sw_if_index = ~0;
17491   u8 *tag = 0;
17492   u8 enable = 1;
17493   int ret;
17494
17495   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17496     {
17497       if (unformat (i, "tag %s", &tag))
17498         ;
17499       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17500         ;
17501       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17502         ;
17503       else if (unformat (i, "del"))
17504         enable = 0;
17505       else
17506         break;
17507     }
17508
17509   if (sw_if_index == ~0)
17510     {
17511       errmsg ("missing interface name or sw_if_index");
17512       return -99;
17513     }
17514
17515   if (enable && (tag == 0))
17516     {
17517       errmsg ("no tag specified");
17518       return -99;
17519     }
17520
17521   /* Construct the API message */
17522   M (SW_INTERFACE_TAG_ADD_DEL, mp);
17523   mp->sw_if_index = ntohl (sw_if_index);
17524   mp->is_add = enable;
17525   if (enable)
17526     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
17527   vec_free (tag);
17528
17529   S (mp);
17530   W (ret);
17531   return ret;
17532 }
17533
17534 static void vl_api_l2_xconnect_details_t_handler
17535   (vl_api_l2_xconnect_details_t * mp)
17536 {
17537   vat_main_t *vam = &vat_main;
17538
17539   print (vam->ofp, "%15d%15d",
17540          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
17541 }
17542
17543 static void vl_api_l2_xconnect_details_t_handler_json
17544   (vl_api_l2_xconnect_details_t * mp)
17545 {
17546   vat_main_t *vam = &vat_main;
17547   vat_json_node_t *node = NULL;
17548
17549   if (VAT_JSON_ARRAY != vam->json_tree.type)
17550     {
17551       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17552       vat_json_init_array (&vam->json_tree);
17553     }
17554   node = vat_json_array_add (&vam->json_tree);
17555
17556   vat_json_init_object (node);
17557   vat_json_object_add_uint (node, "rx_sw_if_index",
17558                             ntohl (mp->rx_sw_if_index));
17559   vat_json_object_add_uint (node, "tx_sw_if_index",
17560                             ntohl (mp->tx_sw_if_index));
17561 }
17562
17563 static int
17564 api_l2_xconnect_dump (vat_main_t * vam)
17565 {
17566   vl_api_l2_xconnect_dump_t *mp;
17567   vl_api_control_ping_t *mp_ping;
17568   int ret;
17569
17570   if (!vam->json_output)
17571     {
17572       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
17573     }
17574
17575   M (L2_XCONNECT_DUMP, mp);
17576
17577   S (mp);
17578
17579   /* Use a control ping for synchronization */
17580   M (CONTROL_PING, mp_ping);
17581   S (mp_ping);
17582
17583   W (ret);
17584   return ret;
17585 }
17586
17587 static int
17588 api_sw_interface_set_mtu (vat_main_t * vam)
17589 {
17590   unformat_input_t *i = vam->input;
17591   vl_api_sw_interface_set_mtu_t *mp;
17592   u32 sw_if_index = ~0;
17593   u32 mtu = 0;
17594   int ret;
17595
17596   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17597     {
17598       if (unformat (i, "mtu %d", &mtu))
17599         ;
17600       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17601         ;
17602       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17603         ;
17604       else
17605         break;
17606     }
17607
17608   if (sw_if_index == ~0)
17609     {
17610       errmsg ("missing interface name or sw_if_index");
17611       return -99;
17612     }
17613
17614   if (mtu == 0)
17615     {
17616       errmsg ("no mtu specified");
17617       return -99;
17618     }
17619
17620   /* Construct the API message */
17621   M (SW_INTERFACE_SET_MTU, mp);
17622   mp->sw_if_index = ntohl (sw_if_index);
17623   mp->mtu = ntohs ((u16) mtu);
17624
17625   S (mp);
17626   W (ret);
17627   return ret;
17628 }
17629
17630
17631 static int
17632 q_or_quit (vat_main_t * vam)
17633 {
17634 #if VPP_API_TEST_BUILTIN == 0
17635   longjmp (vam->jump_buf, 1);
17636 #endif
17637   return 0;                     /* not so much */
17638 }
17639
17640 static int
17641 q (vat_main_t * vam)
17642 {
17643   return q_or_quit (vam);
17644 }
17645
17646 static int
17647 quit (vat_main_t * vam)
17648 {
17649   return q_or_quit (vam);
17650 }
17651
17652 static int
17653 comment (vat_main_t * vam)
17654 {
17655   return 0;
17656 }
17657
17658 static int
17659 cmd_cmp (void *a1, void *a2)
17660 {
17661   u8 **c1 = a1;
17662   u8 **c2 = a2;
17663
17664   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
17665 }
17666
17667 static int
17668 help (vat_main_t * vam)
17669 {
17670   u8 **cmds = 0;
17671   u8 *name = 0;
17672   hash_pair_t *p;
17673   unformat_input_t *i = vam->input;
17674   int j;
17675
17676   if (unformat (i, "%s", &name))
17677     {
17678       uword *hs;
17679
17680       vec_add1 (name, 0);
17681
17682       hs = hash_get_mem (vam->help_by_name, name);
17683       if (hs)
17684         print (vam->ofp, "usage: %s %s", name, hs[0]);
17685       else
17686         print (vam->ofp, "No such msg / command '%s'", name);
17687       vec_free (name);
17688       return 0;
17689     }
17690
17691   print (vam->ofp, "Help is available for the following:");
17692
17693     /* *INDENT-OFF* */
17694     hash_foreach_pair (p, vam->function_by_name,
17695     ({
17696       vec_add1 (cmds, (u8 *)(p->key));
17697     }));
17698     /* *INDENT-ON* */
17699
17700   vec_sort_with_function (cmds, cmd_cmp);
17701
17702   for (j = 0; j < vec_len (cmds); j++)
17703     print (vam->ofp, "%s", cmds[j]);
17704
17705   vec_free (cmds);
17706   return 0;
17707 }
17708
17709 static int
17710 set (vat_main_t * vam)
17711 {
17712   u8 *name = 0, *value = 0;
17713   unformat_input_t *i = vam->input;
17714
17715   if (unformat (i, "%s", &name))
17716     {
17717       /* The input buffer is a vector, not a string. */
17718       value = vec_dup (i->buffer);
17719       vec_delete (value, i->index, 0);
17720       /* Almost certainly has a trailing newline */
17721       if (value[vec_len (value) - 1] == '\n')
17722         value[vec_len (value) - 1] = 0;
17723       /* Make sure it's a proper string, one way or the other */
17724       vec_add1 (value, 0);
17725       (void) clib_macro_set_value (&vam->macro_main,
17726                                    (char *) name, (char *) value);
17727     }
17728   else
17729     errmsg ("usage: set <name> <value>");
17730
17731   vec_free (name);
17732   vec_free (value);
17733   return 0;
17734 }
17735
17736 static int
17737 unset (vat_main_t * vam)
17738 {
17739   u8 *name = 0;
17740
17741   if (unformat (vam->input, "%s", &name))
17742     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
17743       errmsg ("unset: %s wasn't set", name);
17744   vec_free (name);
17745   return 0;
17746 }
17747
17748 typedef struct
17749 {
17750   u8 *name;
17751   u8 *value;
17752 } macro_sort_t;
17753
17754
17755 static int
17756 macro_sort_cmp (void *a1, void *a2)
17757 {
17758   macro_sort_t *s1 = a1;
17759   macro_sort_t *s2 = a2;
17760
17761   return strcmp ((char *) (s1->name), (char *) (s2->name));
17762 }
17763
17764 static int
17765 dump_macro_table (vat_main_t * vam)
17766 {
17767   macro_sort_t *sort_me = 0, *sm;
17768   int i;
17769   hash_pair_t *p;
17770
17771     /* *INDENT-OFF* */
17772     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
17773     ({
17774       vec_add2 (sort_me, sm, 1);
17775       sm->name = (u8 *)(p->key);
17776       sm->value = (u8 *) (p->value[0]);
17777     }));
17778     /* *INDENT-ON* */
17779
17780   vec_sort_with_function (sort_me, macro_sort_cmp);
17781
17782   if (vec_len (sort_me))
17783     print (vam->ofp, "%-15s%s", "Name", "Value");
17784   else
17785     print (vam->ofp, "The macro table is empty...");
17786
17787   for (i = 0; i < vec_len (sort_me); i++)
17788     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
17789   return 0;
17790 }
17791
17792 static int
17793 dump_node_table (vat_main_t * vam)
17794 {
17795   int i, j;
17796   vlib_node_t *node, *next_node;
17797
17798   if (vec_len (vam->graph_nodes) == 0)
17799     {
17800       print (vam->ofp, "Node table empty, issue get_node_graph...");
17801       return 0;
17802     }
17803
17804   for (i = 0; i < vec_len (vam->graph_nodes); i++)
17805     {
17806       node = vam->graph_nodes[i];
17807       print (vam->ofp, "[%d] %s", i, node->name);
17808       for (j = 0; j < vec_len (node->next_nodes); j++)
17809         {
17810           if (node->next_nodes[j] != ~0)
17811             {
17812               next_node = vam->graph_nodes[node->next_nodes[j]];
17813               print (vam->ofp, "  [%d] %s", j, next_node->name);
17814             }
17815         }
17816     }
17817   return 0;
17818 }
17819
17820 static int
17821 value_sort_cmp (void *a1, void *a2)
17822 {
17823   name_sort_t *n1 = a1;
17824   name_sort_t *n2 = a2;
17825
17826   if (n1->value < n2->value)
17827     return -1;
17828   if (n1->value > n2->value)
17829     return 1;
17830   return 0;
17831 }
17832
17833
17834 static int
17835 dump_msg_api_table (vat_main_t * vam)
17836 {
17837   api_main_t *am = &api_main;
17838   name_sort_t *nses = 0, *ns;
17839   hash_pair_t *hp;
17840   int i;
17841
17842   /* *INDENT-OFF* */
17843   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
17844   ({
17845     vec_add2 (nses, ns, 1);
17846     ns->name = (u8 *)(hp->key);
17847     ns->value = (u32) hp->value[0];
17848   }));
17849   /* *INDENT-ON* */
17850
17851   vec_sort_with_function (nses, value_sort_cmp);
17852
17853   for (i = 0; i < vec_len (nses); i++)
17854     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
17855   vec_free (nses);
17856   return 0;
17857 }
17858
17859 static int
17860 get_msg_id (vat_main_t * vam)
17861 {
17862   u8 *name_and_crc;
17863   u32 message_index;
17864
17865   if (unformat (vam->input, "%s", &name_and_crc))
17866     {
17867       message_index = vl_api_get_msg_index (name_and_crc);
17868       if (message_index == ~0)
17869         {
17870           print (vam->ofp, " '%s' not found", name_and_crc);
17871           return 0;
17872         }
17873       print (vam->ofp, " '%s' has message index %d",
17874              name_and_crc, message_index);
17875       return 0;
17876     }
17877   errmsg ("name_and_crc required...");
17878   return 0;
17879 }
17880
17881 static int
17882 search_node_table (vat_main_t * vam)
17883 {
17884   unformat_input_t *line_input = vam->input;
17885   u8 *node_to_find;
17886   int j;
17887   vlib_node_t *node, *next_node;
17888   uword *p;
17889
17890   if (vam->graph_node_index_by_name == 0)
17891     {
17892       print (vam->ofp, "Node table empty, issue get_node_graph...");
17893       return 0;
17894     }
17895
17896   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
17897     {
17898       if (unformat (line_input, "%s", &node_to_find))
17899         {
17900           vec_add1 (node_to_find, 0);
17901           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
17902           if (p == 0)
17903             {
17904               print (vam->ofp, "%s not found...", node_to_find);
17905               goto out;
17906             }
17907           node = vam->graph_nodes[p[0]];
17908           print (vam->ofp, "[%d] %s", p[0], node->name);
17909           for (j = 0; j < vec_len (node->next_nodes); j++)
17910             {
17911               if (node->next_nodes[j] != ~0)
17912                 {
17913                   next_node = vam->graph_nodes[node->next_nodes[j]];
17914                   print (vam->ofp, "  [%d] %s", j, next_node->name);
17915                 }
17916             }
17917         }
17918
17919       else
17920         {
17921           clib_warning ("parse error '%U'", format_unformat_error,
17922                         line_input);
17923           return -99;
17924         }
17925
17926     out:
17927       vec_free (node_to_find);
17928
17929     }
17930
17931   return 0;
17932 }
17933
17934
17935 static int
17936 script (vat_main_t * vam)
17937 {
17938 #if (VPP_API_TEST_BUILTIN==0)
17939   u8 *s = 0;
17940   char *save_current_file;
17941   unformat_input_t save_input;
17942   jmp_buf save_jump_buf;
17943   u32 save_line_number;
17944
17945   FILE *new_fp, *save_ifp;
17946
17947   if (unformat (vam->input, "%s", &s))
17948     {
17949       new_fp = fopen ((char *) s, "r");
17950       if (new_fp == 0)
17951         {
17952           errmsg ("Couldn't open script file %s", s);
17953           vec_free (s);
17954           return -99;
17955         }
17956     }
17957   else
17958     {
17959       errmsg ("Missing script name");
17960       return -99;
17961     }
17962
17963   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
17964   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
17965   save_ifp = vam->ifp;
17966   save_line_number = vam->input_line_number;
17967   save_current_file = (char *) vam->current_file;
17968
17969   vam->input_line_number = 0;
17970   vam->ifp = new_fp;
17971   vam->current_file = s;
17972   do_one_file (vam);
17973
17974   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
17975   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
17976   vam->ifp = save_ifp;
17977   vam->input_line_number = save_line_number;
17978   vam->current_file = (u8 *) save_current_file;
17979   vec_free (s);
17980
17981   return 0;
17982 #else
17983   clib_warning ("use the exec command...");
17984   return -99;
17985 #endif
17986 }
17987
17988 static int
17989 echo (vat_main_t * vam)
17990 {
17991   print (vam->ofp, "%v", vam->input->buffer);
17992   return 0;
17993 }
17994
17995 /* List of API message constructors, CLI names map to api_xxx */
17996 #define foreach_vpe_api_msg                                             \
17997 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
17998 _(sw_interface_dump,"")                                                 \
17999 _(sw_interface_set_flags,                                               \
18000   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
18001 _(sw_interface_add_del_address,                                         \
18002   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
18003 _(sw_interface_set_table,                                               \
18004   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
18005 _(sw_interface_set_mpls_enable,                                         \
18006   "<intfc> | sw_if_index [disable | dis]")                              \
18007 _(sw_interface_set_vpath,                                               \
18008   "<intfc> | sw_if_index <id> enable | disable")                        \
18009 _(sw_interface_set_vxlan_bypass,                                        \
18010   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
18011 _(sw_interface_set_l2_xconnect,                                         \
18012   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18013   "enable | disable")                                                   \
18014 _(sw_interface_set_l2_bridge,                                           \
18015   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"               \
18016   "[shg <split-horizon-group>] [bvi]\n"                                 \
18017   "enable | disable")                                                   \
18018 _(bridge_domain_add_del,                                                \
18019   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n") \
18020 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
18021 _(l2fib_add_del,                                                        \
18022   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
18023 _(l2_flags,                                                             \
18024   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
18025 _(bridge_flags,                                                         \
18026   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
18027 _(tap_connect,                                                          \
18028   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
18029 _(tap_modify,                                                           \
18030   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
18031 _(tap_delete,                                                           \
18032   "<vpp-if-name> | sw_if_index <id>")                                   \
18033 _(sw_interface_tap_dump, "")                                            \
18034 _(ip_add_del_route,                                                     \
18035   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
18036   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
18037   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
18038   "[multipath] [count <n>]")                                            \
18039 _(ip_mroute_add_del,                                                    \
18040   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
18041   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
18042 _(mpls_route_add_del,                                                   \
18043   "<label> <eos> via <addr> [table-id <n>]\n"                           \
18044   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
18045   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
18046   "[multipath] [count <n>]")                                            \
18047 _(mpls_ip_bind_unbind,                                                  \
18048   "<label> <addr/len>")                                                 \
18049 _(mpls_tunnel_add_del,                                                  \
18050   " via <addr> [table-id <n>]\n"                                        \
18051   "sw_if_index <id>] [l2]  [del]")                                      \
18052 _(proxy_arp_add_del,                                                    \
18053   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
18054 _(proxy_arp_intfc_enable_disable,                                       \
18055   "<intfc> | sw_if_index <id> enable | disable")                        \
18056 _(sw_interface_set_unnumbered,                                          \
18057   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
18058 _(ip_neighbor_add_del,                                                  \
18059   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
18060   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
18061 _(reset_vrf, "vrf <id> [ipv6]")                                         \
18062 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
18063 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
18064   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
18065   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
18066   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
18067 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
18068 _(reset_fib, "vrf <n> [ipv6]")                                          \
18069 _(dhcp_proxy_config,                                                    \
18070   "svr <v46-address> src <v46-address>\n"                               \
18071    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
18072 _(dhcp_proxy_set_vss,                                                   \
18073   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
18074 _(dhcp_proxy_dump, "ip6")                                               \
18075 _(dhcp_client_config,                                                   \
18076   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
18077 _(set_ip_flow_hash,                                                     \
18078   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
18079 _(sw_interface_ip6_enable_disable,                                      \
18080   "<intfc> | sw_if_index <id> enable | disable")                        \
18081 _(sw_interface_ip6_set_link_local_address,                              \
18082   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
18083 _(ip6nd_proxy_add_del,                                                  \
18084   "<intfc> | sw_if_index <id> <ip6-address>")                           \
18085 _(ip6nd_proxy_dump, "")                                                 \
18086 _(sw_interface_ip6nd_ra_prefix,                                         \
18087   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
18088   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
18089   "[nolink] [isno]")                                                    \
18090 _(sw_interface_ip6nd_ra_config,                                         \
18091   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
18092   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
18093   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
18094 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
18095 _(l2_patch_add_del,                                                     \
18096   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18097   "enable | disable")                                                   \
18098 _(sr_localsid_add_del,                                                  \
18099   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
18100   "fib-table <num> (end.psp) sw_if_index <num>")                        \
18101 _(classify_add_del_table,                                               \
18102   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
18103   " [del] [del-chain] mask <mask-value>\n"                              \
18104   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
18105   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
18106 _(classify_add_del_session,                                             \
18107   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
18108   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
18109   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
18110   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
18111 _(classify_set_interface_ip_table,                                      \
18112   "<intfc> | sw_if_index <nn> table <nn>")                              \
18113 _(classify_set_interface_l2_tables,                                     \
18114   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18115   "  [other-table <nn>]")                                               \
18116 _(get_node_index, "node <node-name")                                    \
18117 _(add_node_next, "node <node-name> next <next-node-name>")              \
18118 _(l2tpv3_create_tunnel,                                                 \
18119   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
18120   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
18121   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
18122 _(l2tpv3_set_tunnel_cookies,                                            \
18123   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
18124   "[new_remote_cookie <nn>]\n")                                         \
18125 _(l2tpv3_interface_enable_disable,                                      \
18126   "<intfc> | sw_if_index <nn> enable | disable")                        \
18127 _(l2tpv3_set_lookup_key,                                                \
18128   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
18129 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
18130 _(vxlan_add_del_tunnel,                                                 \
18131   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
18132   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
18133   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
18134 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
18135 _(gre_add_del_tunnel,                                                   \
18136   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
18137 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
18138 _(l2_fib_clear_table, "")                                               \
18139 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
18140 _(l2_interface_vlan_tag_rewrite,                                        \
18141   "<intfc> | sw_if_index <nn> \n"                                       \
18142   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
18143   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
18144 _(create_vhost_user_if,                                                 \
18145         "socket <filename> [server] [renumber <dev_instance>] "         \
18146         "[mac <mac_address>]")                                          \
18147 _(modify_vhost_user_if,                                                 \
18148         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
18149         "[server] [renumber <dev_instance>]")                           \
18150 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
18151 _(sw_interface_vhost_user_dump, "")                                     \
18152 _(show_version, "")                                                     \
18153 _(vxlan_gpe_add_del_tunnel,                                             \
18154   "local <addr> remote <addr> vni <nn>\n"                               \
18155     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
18156   "[next-ethernet] [next-nsh]\n")                                       \
18157 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
18158 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
18159 _(interface_name_renumber,                                              \
18160   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
18161 _(input_acl_set_interface,                                              \
18162   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18163   "  [l2-table <nn>] [del]")                                            \
18164 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
18165 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
18166 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
18167 _(ip_dump, "ipv4 | ipv6")                                               \
18168 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
18169 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
18170   "  spid_id <n> ")                                                     \
18171 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
18172   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
18173   "  integ_alg <alg> integ_key <hex>")                                  \
18174 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
18175   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
18176   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
18177   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
18178 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
18179 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
18180 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
18181   "(auth_data 0x<data> | auth_data <data>)")                            \
18182 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
18183   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
18184 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
18185   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
18186   "(local|remote)")                                                     \
18187 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
18188 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
18189 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18190 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18191 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
18192 _(ikev2_initiate_sa_init, "<profile_name>")                             \
18193 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
18194 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
18195 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
18196 _(delete_loopback,"sw_if_index <nn>")                                   \
18197 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
18198 _(map_add_domain,                                                       \
18199   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
18200   "ip6-src <ip6addr> "                                                  \
18201   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
18202 _(map_del_domain, "index <n>")                                          \
18203 _(map_add_del_rule,                                                     \
18204   "index <n> psid <n> dst <ip6addr> [del]")                             \
18205 _(map_domain_dump, "")                                                  \
18206 _(map_rule_dump, "index <map-domain>")                                  \
18207 _(want_interface_events,  "enable|disable")                             \
18208 _(want_stats,"enable|disable")                                          \
18209 _(get_first_msg_id, "client <name>")                                    \
18210 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
18211 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
18212   "fib-id <nn> [ip4][ip6][default]")                                    \
18213 _(get_node_graph, " ")                                                  \
18214 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
18215 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
18216 _(ioam_disable, "")                                                     \
18217 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
18218                             " sw_if_index <sw_if_index> p <priority> "  \
18219                             "w <weight>] [del]")                        \
18220 _(one_add_del_locator, "locator-set <locator_name> "                    \
18221                         "iface <intf> | sw_if_index <sw_if_index> "     \
18222                         "p <priority> w <weight> [del]")                \
18223 _(one_add_del_local_eid,"vni <vni> eid "                                \
18224                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
18225                          "locator-set <locator_name> [del]"             \
18226                          "[key-id sha1|sha256 secret-key <secret-key>]")\
18227 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
18228 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
18229 _(one_enable_disable, "enable|disable")                                 \
18230 _(one_map_register_enable_disable, "enable|disable")                    \
18231 _(one_rloc_probe_enable_disable, "enable|disable")                      \
18232 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
18233                                "[seid <seid>] "                         \
18234                                "rloc <locator> p <prio> "               \
18235                                "w <weight> [rloc <loc> ... ] "          \
18236                                "action <action> [del-all]")             \
18237 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
18238                           "<local-eid>")                                \
18239 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
18240 _(one_map_request_mode, "src-dst|dst-only")                             \
18241 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
18242 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
18243 _(one_locator_set_dump, "[local | remote]")                             \
18244 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
18245 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
18246                        "[local] | [remote]")                            \
18247 _(one_eid_table_vni_dump, "")                                           \
18248 _(one_eid_table_map_dump, "l2|l3")                                      \
18249 _(one_map_resolver_dump, "")                                            \
18250 _(one_map_server_dump, "")                                              \
18251 _(one_adjacencies_get, "vni <vni>")                                     \
18252 _(show_one_rloc_probe_state, "")                                        \
18253 _(show_one_map_register_state, "")                                      \
18254 _(show_one_status, "")                                                  \
18255 _(one_get_map_request_itr_rlocs, "")                                    \
18256 _(show_one_pitr, "")                                                    \
18257 _(show_one_map_request_mode, "")                                        \
18258 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
18259                             " sw_if_index <sw_if_index> p <priority> "  \
18260                             "w <weight>] [del]")                        \
18261 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
18262                         "iface <intf> | sw_if_index <sw_if_index> "     \
18263                         "p <priority> w <weight> [del]")                \
18264 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
18265                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
18266                          "locator-set <locator_name> [del]"             \
18267                          "[key-id sha1|sha256 secret-key <secret-key>]") \
18268 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
18269 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
18270 _(lisp_enable_disable, "enable|disable")                                \
18271 _(lisp_map_register_enable_disable, "enable|disable")                   \
18272 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
18273 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
18274                                "[seid <seid>] "                         \
18275                                "rloc <locator> p <prio> "               \
18276                                "w <weight> [rloc <loc> ... ] "          \
18277                                "action <action> [del-all]")             \
18278 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
18279                           "<local-eid>")                                \
18280 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
18281 _(lisp_map_request_mode, "src-dst|dst-only")                            \
18282 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
18283 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
18284 _(lisp_locator_set_dump, "[local | remote]")                            \
18285 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
18286 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
18287                        "[local] | [remote]")                            \
18288 _(lisp_eid_table_vni_dump, "")                                          \
18289 _(lisp_eid_table_map_dump, "l2|l3")                                     \
18290 _(lisp_map_resolver_dump, "")                                           \
18291 _(lisp_map_server_dump, "")                                             \
18292 _(lisp_adjacencies_get, "vni <vni>")                                    \
18293 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
18294 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
18295 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
18296 _(gpe_get_encap_mode, "")                                               \
18297 _(lisp_gpe_add_del_iface, "up|down")                                    \
18298 _(lisp_gpe_enable_disable, "enable|disable")                            \
18299 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
18300   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
18301 _(show_lisp_rloc_probe_state, "")                                       \
18302 _(show_lisp_map_register_state, "")                                     \
18303 _(show_lisp_status, "")                                                 \
18304 _(lisp_get_map_request_itr_rlocs, "")                                   \
18305 _(show_lisp_pitr, "")                                                   \
18306 _(show_lisp_map_request_mode, "")                                       \
18307 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
18308 _(af_packet_delete, "name <host interface name>")                       \
18309 _(policer_add_del, "name <policer name> <params> [del]")                \
18310 _(policer_dump, "[name <policer name>]")                                \
18311 _(policer_classify_set_interface,                                       \
18312   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18313   "  [l2-table <nn>] [del]")                                            \
18314 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
18315 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
18316     "[master|slave]")                                                   \
18317 _(netmap_delete, "name <interface name>")                               \
18318 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
18319 _(mpls_fib_dump, "")                                                    \
18320 _(classify_table_ids, "")                                               \
18321 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
18322 _(classify_table_info, "table_id <nn>")                                 \
18323 _(classify_session_dump, "table_id <nn>")                               \
18324 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
18325     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
18326     "[template_interval <nn>] [udp_checksum]")                          \
18327 _(ipfix_exporter_dump, "")                                              \
18328 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
18329 _(ipfix_classify_stream_dump, "")                                       \
18330 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
18331 _(ipfix_classify_table_dump, "")                                        \
18332 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
18333 _(sw_interface_span_dump, "")                                           \
18334 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
18335 _(pg_create_interface, "if_id <nn>")                                    \
18336 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
18337 _(pg_enable_disable, "[stream <id>] disable")                           \
18338 _(ip_source_and_port_range_check_add_del,                               \
18339   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
18340 _(ip_source_and_port_range_check_interface_add_del,                     \
18341   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
18342   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
18343 _(ipsec_gre_add_del_tunnel,                                             \
18344   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
18345 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
18346 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
18347 _(l2_interface_pbb_tag_rewrite,                                         \
18348   "<intfc> | sw_if_index <nn> \n"                                       \
18349   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
18350   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
18351 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
18352 _(flow_classify_set_interface,                                          \
18353   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
18354 _(flow_classify_dump, "type [ip4|ip6]")                                 \
18355 _(ip_fib_dump, "")                                                      \
18356 _(ip_mfib_dump, "")                                                     \
18357 _(ip6_fib_dump, "")                                                     \
18358 _(ip6_mfib_dump, "")                                                    \
18359 _(feature_enable_disable, "arc_name <arc_name> "                        \
18360   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
18361 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
18362 "[disable]")                                                            \
18363 _(l2_xconnect_dump, "")                                                 \
18364 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
18365 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
18366 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
18367
18368 /* List of command functions, CLI names map directly to functions */
18369 #define foreach_cli_function                                    \
18370 _(comment, "usage: comment <ignore-rest-of-line>")              \
18371 _(dump_interface_table, "usage: dump_interface_table")          \
18372 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
18373 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
18374 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
18375 _(dump_stats_table, "usage: dump_stats_table")                  \
18376 _(dump_macro_table, "usage: dump_macro_table ")                 \
18377 _(dump_node_table, "usage: dump_node_table")                    \
18378 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
18379 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
18380 _(echo, "usage: echo <message>")                                \
18381 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
18382 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
18383 _(help, "usage: help")                                          \
18384 _(q, "usage: quit")                                             \
18385 _(quit, "usage: quit")                                          \
18386 _(search_node_table, "usage: search_node_table <name>...")      \
18387 _(set, "usage: set <variable-name> <value>")                    \
18388 _(script, "usage: script <file-name>")                          \
18389 _(unset, "usage: unset <variable-name>")
18390
18391 #define _(N,n)                                  \
18392     static void vl_api_##n##_t_handler_uni      \
18393     (vl_api_##n##_t * mp)                       \
18394     {                                           \
18395         vat_main_t * vam = &vat_main;           \
18396         if (vam->json_output) {                 \
18397             vl_api_##n##_t_handler_json(mp);    \
18398         } else {                                \
18399             vl_api_##n##_t_handler(mp);         \
18400         }                                       \
18401     }
18402 foreach_vpe_api_reply_msg;
18403 #if VPP_API_TEST_BUILTIN == 0
18404 foreach_standalone_reply_msg;
18405 #endif
18406 #undef _
18407
18408 void
18409 vat_api_hookup (vat_main_t * vam)
18410 {
18411 #define _(N,n)                                                  \
18412     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
18413                            vl_api_##n##_t_handler_uni,          \
18414                            vl_noop_handler,                     \
18415                            vl_api_##n##_t_endian,               \
18416                            vl_api_##n##_t_print,                \
18417                            sizeof(vl_api_##n##_t), 1);
18418   foreach_vpe_api_reply_msg;
18419 #if VPP_API_TEST_BUILTIN == 0
18420   foreach_standalone_reply_msg;
18421 #endif
18422 #undef _
18423
18424 #if (VPP_API_TEST_BUILTIN==0)
18425   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
18426
18427   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
18428
18429   vam->function_by_name = hash_create_string (0, sizeof (uword));
18430
18431   vam->help_by_name = hash_create_string (0, sizeof (uword));
18432 #endif
18433
18434   /* API messages we can send */
18435 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
18436   foreach_vpe_api_msg;
18437 #undef _
18438
18439   /* Help strings */
18440 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18441   foreach_vpe_api_msg;
18442 #undef _
18443
18444   /* CLI functions */
18445 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
18446   foreach_cli_function;
18447 #undef _
18448
18449   /* Help strings */
18450 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18451   foreach_cli_function;
18452 #undef _
18453 }
18454
18455 #if VPP_API_TEST_BUILTIN
18456 static clib_error_t *
18457 vat_api_hookup_shim (vlib_main_t * vm)
18458 {
18459   vat_api_hookup (&vat_main);
18460   return 0;
18461 }
18462
18463 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
18464 #endif
18465
18466 /*
18467  * fd.io coding-style-patch-verification: ON
18468  *
18469  * Local Variables:
18470  * eval: (c-set-style "gnu")
18471  * End:
18472  */