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