VXLAN:add hidden multicast interface check
[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_use_petr_reply_t_handler
3239   (vl_api_show_one_use_petr_reply_t * mp)
3240 {
3241   vat_main_t *vam = &vat_main;
3242   i32 retval = ntohl (mp->retval);
3243
3244   if (0 <= retval)
3245     {
3246       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
3247       if (mp->status)
3248         {
3249           print (vam->ofp, "Proxy-ETR address; %U",
3250                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
3251                  mp->address);
3252         }
3253     }
3254
3255   vam->retval = retval;
3256   vam->result_ready = 1;
3257 }
3258
3259 static void
3260   vl_api_show_one_use_petr_reply_t_handler_json
3261   (vl_api_show_one_use_petr_reply_t * mp)
3262 {
3263   vat_main_t *vam = &vat_main;
3264   vat_json_node_t node;
3265   u8 *status = 0;
3266   struct in_addr ip4;
3267   struct in6_addr ip6;
3268
3269   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3270   vec_add1 (status, 0);
3271
3272   vat_json_init_object (&node);
3273   vat_json_object_add_string_copy (&node, "status", status);
3274   if (mp->status)
3275     {
3276       if (mp->is_ip4)
3277         {
3278           clib_memcpy (&ip6, mp->address, sizeof (ip6));
3279           vat_json_object_add_ip6 (&node, "address", ip6);
3280         }
3281       else
3282         {
3283           clib_memcpy (&ip4, mp->address, sizeof (ip4));
3284           vat_json_object_add_ip4 (&node, "address", ip4);
3285         }
3286     }
3287
3288   vec_free (status);
3289
3290   vat_json_print (vam->ofp, &node);
3291   vat_json_free (&node);
3292
3293   vam->retval = ntohl (mp->retval);
3294   vam->result_ready = 1;
3295 }
3296
3297 static void
3298 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
3299 {
3300   vat_main_t *vam = &vat_main;
3301   i32 retval = ntohl (mp->retval);
3302
3303   if (0 <= retval)
3304     {
3305       print (vam->ofp, "%-20s%-16s",
3306              mp->status ? "enabled" : "disabled",
3307              mp->status ? (char *) mp->locator_set_name : "");
3308     }
3309
3310   vam->retval = retval;
3311   vam->result_ready = 1;
3312 }
3313
3314 static void
3315 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
3316 {
3317   vat_main_t *vam = &vat_main;
3318   vat_json_node_t node;
3319   u8 *status = 0;
3320
3321   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3322   vec_add1 (status, 0);
3323
3324   vat_json_init_object (&node);
3325   vat_json_object_add_string_copy (&node, "status", status);
3326   if (mp->status)
3327     {
3328       vat_json_object_add_string_copy (&node, "locator_set",
3329                                        mp->locator_set_name);
3330     }
3331
3332   vec_free (status);
3333
3334   vat_json_print (vam->ofp, &node);
3335   vat_json_free (&node);
3336
3337   vam->retval = ntohl (mp->retval);
3338   vam->result_ready = 1;
3339 }
3340
3341 static u8 *
3342 format_policer_type (u8 * s, va_list * va)
3343 {
3344   u32 i = va_arg (*va, u32);
3345
3346   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
3347     s = format (s, "1r2c");
3348   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
3349     s = format (s, "1r3c");
3350   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
3351     s = format (s, "2r3c-2698");
3352   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
3353     s = format (s, "2r3c-4115");
3354   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
3355     s = format (s, "2r3c-mef5cf1");
3356   else
3357     s = format (s, "ILLEGAL");
3358   return s;
3359 }
3360
3361 static u8 *
3362 format_policer_rate_type (u8 * s, va_list * va)
3363 {
3364   u32 i = va_arg (*va, u32);
3365
3366   if (i == SSE2_QOS_RATE_KBPS)
3367     s = format (s, "kbps");
3368   else if (i == SSE2_QOS_RATE_PPS)
3369     s = format (s, "pps");
3370   else
3371     s = format (s, "ILLEGAL");
3372   return s;
3373 }
3374
3375 static u8 *
3376 format_policer_round_type (u8 * s, va_list * va)
3377 {
3378   u32 i = va_arg (*va, u32);
3379
3380   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3381     s = format (s, "closest");
3382   else if (i == SSE2_QOS_ROUND_TO_UP)
3383     s = format (s, "up");
3384   else if (i == SSE2_QOS_ROUND_TO_DOWN)
3385     s = format (s, "down");
3386   else
3387     s = format (s, "ILLEGAL");
3388   return s;
3389 }
3390
3391 static u8 *
3392 format_policer_action_type (u8 * s, va_list * va)
3393 {
3394   u32 i = va_arg (*va, u32);
3395
3396   if (i == SSE2_QOS_ACTION_DROP)
3397     s = format (s, "drop");
3398   else if (i == SSE2_QOS_ACTION_TRANSMIT)
3399     s = format (s, "transmit");
3400   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3401     s = format (s, "mark-and-transmit");
3402   else
3403     s = format (s, "ILLEGAL");
3404   return s;
3405 }
3406
3407 static u8 *
3408 format_dscp (u8 * s, va_list * va)
3409 {
3410   u32 i = va_arg (*va, u32);
3411   char *t = 0;
3412
3413   switch (i)
3414     {
3415 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3416       foreach_vnet_dscp
3417 #undef _
3418     default:
3419       return format (s, "ILLEGAL");
3420     }
3421   s = format (s, "%s", t);
3422   return s;
3423 }
3424
3425 static void
3426 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3427 {
3428   vat_main_t *vam = &vat_main;
3429   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3430
3431   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3432     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3433   else
3434     conform_dscp_str = format (0, "");
3435
3436   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3437     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3438   else
3439     exceed_dscp_str = format (0, "");
3440
3441   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3442     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3443   else
3444     violate_dscp_str = format (0, "");
3445
3446   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3447          "rate type %U, round type %U, %s rate, %s color-aware, "
3448          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3449          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3450          "conform action %U%s, exceed action %U%s, violate action %U%s",
3451          mp->name,
3452          format_policer_type, mp->type,
3453          ntohl (mp->cir),
3454          ntohl (mp->eir),
3455          clib_net_to_host_u64 (mp->cb),
3456          clib_net_to_host_u64 (mp->eb),
3457          format_policer_rate_type, mp->rate_type,
3458          format_policer_round_type, mp->round_type,
3459          mp->single_rate ? "single" : "dual",
3460          mp->color_aware ? "is" : "not",
3461          ntohl (mp->cir_tokens_per_period),
3462          ntohl (mp->pir_tokens_per_period),
3463          ntohl (mp->scale),
3464          ntohl (mp->current_limit),
3465          ntohl (mp->current_bucket),
3466          ntohl (mp->extended_limit),
3467          ntohl (mp->extended_bucket),
3468          clib_net_to_host_u64 (mp->last_update_time),
3469          format_policer_action_type, mp->conform_action_type,
3470          conform_dscp_str,
3471          format_policer_action_type, mp->exceed_action_type,
3472          exceed_dscp_str,
3473          format_policer_action_type, mp->violate_action_type,
3474          violate_dscp_str);
3475
3476   vec_free (conform_dscp_str);
3477   vec_free (exceed_dscp_str);
3478   vec_free (violate_dscp_str);
3479 }
3480
3481 static void vl_api_policer_details_t_handler_json
3482   (vl_api_policer_details_t * mp)
3483 {
3484   vat_main_t *vam = &vat_main;
3485   vat_json_node_t *node;
3486   u8 *rate_type_str, *round_type_str, *type_str;
3487   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3488
3489   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3490   round_type_str =
3491     format (0, "%U", format_policer_round_type, mp->round_type);
3492   type_str = format (0, "%U", format_policer_type, mp->type);
3493   conform_action_str = format (0, "%U", format_policer_action_type,
3494                                mp->conform_action_type);
3495   exceed_action_str = format (0, "%U", format_policer_action_type,
3496                               mp->exceed_action_type);
3497   violate_action_str = format (0, "%U", format_policer_action_type,
3498                                mp->violate_action_type);
3499
3500   if (VAT_JSON_ARRAY != vam->json_tree.type)
3501     {
3502       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3503       vat_json_init_array (&vam->json_tree);
3504     }
3505   node = vat_json_array_add (&vam->json_tree);
3506
3507   vat_json_init_object (node);
3508   vat_json_object_add_string_copy (node, "name", mp->name);
3509   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3510   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3511   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3512   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3513   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3514   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3515   vat_json_object_add_string_copy (node, "type", type_str);
3516   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3517   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3518   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3519   vat_json_object_add_uint (node, "cir_tokens_per_period",
3520                             ntohl (mp->cir_tokens_per_period));
3521   vat_json_object_add_uint (node, "eir_tokens_per_period",
3522                             ntohl (mp->pir_tokens_per_period));
3523   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3524   vat_json_object_add_uint (node, "current_bucket",
3525                             ntohl (mp->current_bucket));
3526   vat_json_object_add_uint (node, "extended_limit",
3527                             ntohl (mp->extended_limit));
3528   vat_json_object_add_uint (node, "extended_bucket",
3529                             ntohl (mp->extended_bucket));
3530   vat_json_object_add_uint (node, "last_update_time",
3531                             ntohl (mp->last_update_time));
3532   vat_json_object_add_string_copy (node, "conform_action",
3533                                    conform_action_str);
3534   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3535     {
3536       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3537       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3538       vec_free (dscp_str);
3539     }
3540   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3541   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3542     {
3543       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3544       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3545       vec_free (dscp_str);
3546     }
3547   vat_json_object_add_string_copy (node, "violate_action",
3548                                    violate_action_str);
3549   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3550     {
3551       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3552       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3553       vec_free (dscp_str);
3554     }
3555
3556   vec_free (rate_type_str);
3557   vec_free (round_type_str);
3558   vec_free (type_str);
3559   vec_free (conform_action_str);
3560   vec_free (exceed_action_str);
3561   vec_free (violate_action_str);
3562 }
3563
3564 static void
3565 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3566                                            mp)
3567 {
3568   vat_main_t *vam = &vat_main;
3569   int i, count = ntohl (mp->count);
3570
3571   if (count > 0)
3572     print (vam->ofp, "classify table ids (%d) : ", count);
3573   for (i = 0; i < count; i++)
3574     {
3575       print (vam->ofp, "%d", ntohl (mp->ids[i]));
3576       print (vam->ofp, (i < count - 1) ? "," : "");
3577     }
3578   vam->retval = ntohl (mp->retval);
3579   vam->result_ready = 1;
3580 }
3581
3582 static void
3583   vl_api_classify_table_ids_reply_t_handler_json
3584   (vl_api_classify_table_ids_reply_t * mp)
3585 {
3586   vat_main_t *vam = &vat_main;
3587   int i, count = ntohl (mp->count);
3588
3589   if (count > 0)
3590     {
3591       vat_json_node_t node;
3592
3593       vat_json_init_object (&node);
3594       for (i = 0; i < count; i++)
3595         {
3596           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3597         }
3598       vat_json_print (vam->ofp, &node);
3599       vat_json_free (&node);
3600     }
3601   vam->retval = ntohl (mp->retval);
3602   vam->result_ready = 1;
3603 }
3604
3605 static void
3606   vl_api_classify_table_by_interface_reply_t_handler
3607   (vl_api_classify_table_by_interface_reply_t * mp)
3608 {
3609   vat_main_t *vam = &vat_main;
3610   u32 table_id;
3611
3612   table_id = ntohl (mp->l2_table_id);
3613   if (table_id != ~0)
3614     print (vam->ofp, "l2 table id : %d", table_id);
3615   else
3616     print (vam->ofp, "l2 table id : No input ACL tables configured");
3617   table_id = ntohl (mp->ip4_table_id);
3618   if (table_id != ~0)
3619     print (vam->ofp, "ip4 table id : %d", table_id);
3620   else
3621     print (vam->ofp, "ip4 table id : No input ACL tables configured");
3622   table_id = ntohl (mp->ip6_table_id);
3623   if (table_id != ~0)
3624     print (vam->ofp, "ip6 table id : %d", table_id);
3625   else
3626     print (vam->ofp, "ip6 table id : No input ACL tables configured");
3627   vam->retval = ntohl (mp->retval);
3628   vam->result_ready = 1;
3629 }
3630
3631 static void
3632   vl_api_classify_table_by_interface_reply_t_handler_json
3633   (vl_api_classify_table_by_interface_reply_t * mp)
3634 {
3635   vat_main_t *vam = &vat_main;
3636   vat_json_node_t node;
3637
3638   vat_json_init_object (&node);
3639
3640   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3641   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3642   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3643
3644   vat_json_print (vam->ofp, &node);
3645   vat_json_free (&node);
3646
3647   vam->retval = ntohl (mp->retval);
3648   vam->result_ready = 1;
3649 }
3650
3651 static void vl_api_policer_add_del_reply_t_handler
3652   (vl_api_policer_add_del_reply_t * mp)
3653 {
3654   vat_main_t *vam = &vat_main;
3655   i32 retval = ntohl (mp->retval);
3656   if (vam->async_mode)
3657     {
3658       vam->async_errors += (retval < 0);
3659     }
3660   else
3661     {
3662       vam->retval = retval;
3663       vam->result_ready = 1;
3664       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3665         /*
3666          * Note: this is just barely thread-safe, depends on
3667          * the main thread spinning waiting for an answer...
3668          */
3669         errmsg ("policer index %d", ntohl (mp->policer_index));
3670     }
3671 }
3672
3673 static void vl_api_policer_add_del_reply_t_handler_json
3674   (vl_api_policer_add_del_reply_t * mp)
3675 {
3676   vat_main_t *vam = &vat_main;
3677   vat_json_node_t node;
3678
3679   vat_json_init_object (&node);
3680   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3681   vat_json_object_add_uint (&node, "policer_index",
3682                             ntohl (mp->policer_index));
3683
3684   vat_json_print (vam->ofp, &node);
3685   vat_json_free (&node);
3686
3687   vam->retval = ntohl (mp->retval);
3688   vam->result_ready = 1;
3689 }
3690
3691 /* Format hex dump. */
3692 u8 *
3693 format_hex_bytes (u8 * s, va_list * va)
3694 {
3695   u8 *bytes = va_arg (*va, u8 *);
3696   int n_bytes = va_arg (*va, int);
3697   uword i;
3698
3699   /* Print short or long form depending on byte count. */
3700   uword short_form = n_bytes <= 32;
3701   uword indent = format_get_indent (s);
3702
3703   if (n_bytes == 0)
3704     return s;
3705
3706   for (i = 0; i < n_bytes; i++)
3707     {
3708       if (!short_form && (i % 32) == 0)
3709         s = format (s, "%08x: ", i);
3710       s = format (s, "%02x", bytes[i]);
3711       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3712         s = format (s, "\n%U", format_white_space, indent);
3713     }
3714
3715   return s;
3716 }
3717
3718 static void
3719 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3720                                             * mp)
3721 {
3722   vat_main_t *vam = &vat_main;
3723   i32 retval = ntohl (mp->retval);
3724   if (retval == 0)
3725     {
3726       print (vam->ofp, "classify table info :");
3727       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3728              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3729              ntohl (mp->miss_next_index));
3730       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3731              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3732              ntohl (mp->match_n_vectors));
3733       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3734              ntohl (mp->mask_length));
3735     }
3736   vam->retval = retval;
3737   vam->result_ready = 1;
3738 }
3739
3740 static void
3741   vl_api_classify_table_info_reply_t_handler_json
3742   (vl_api_classify_table_info_reply_t * mp)
3743 {
3744   vat_main_t *vam = &vat_main;
3745   vat_json_node_t node;
3746
3747   i32 retval = ntohl (mp->retval);
3748   if (retval == 0)
3749     {
3750       vat_json_init_object (&node);
3751
3752       vat_json_object_add_int (&node, "sessions",
3753                                ntohl (mp->active_sessions));
3754       vat_json_object_add_int (&node, "nexttbl",
3755                                ntohl (mp->next_table_index));
3756       vat_json_object_add_int (&node, "nextnode",
3757                                ntohl (mp->miss_next_index));
3758       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3759       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3760       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3761       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3762                       ntohl (mp->mask_length), 0);
3763       vat_json_object_add_string_copy (&node, "mask", s);
3764
3765       vat_json_print (vam->ofp, &node);
3766       vat_json_free (&node);
3767     }
3768   vam->retval = ntohl (mp->retval);
3769   vam->result_ready = 1;
3770 }
3771
3772 static void
3773 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3774                                            mp)
3775 {
3776   vat_main_t *vam = &vat_main;
3777
3778   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3779          ntohl (mp->hit_next_index), ntohl (mp->advance),
3780          ntohl (mp->opaque_index));
3781   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3782          ntohl (mp->match_length));
3783 }
3784
3785 static void
3786   vl_api_classify_session_details_t_handler_json
3787   (vl_api_classify_session_details_t * mp)
3788 {
3789   vat_main_t *vam = &vat_main;
3790   vat_json_node_t *node = NULL;
3791
3792   if (VAT_JSON_ARRAY != vam->json_tree.type)
3793     {
3794       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3795       vat_json_init_array (&vam->json_tree);
3796     }
3797   node = vat_json_array_add (&vam->json_tree);
3798
3799   vat_json_init_object (node);
3800   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3801   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3802   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3803   u8 *s =
3804     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3805             0);
3806   vat_json_object_add_string_copy (node, "match", s);
3807 }
3808
3809 static void vl_api_pg_create_interface_reply_t_handler
3810   (vl_api_pg_create_interface_reply_t * mp)
3811 {
3812   vat_main_t *vam = &vat_main;
3813
3814   vam->retval = ntohl (mp->retval);
3815   vam->result_ready = 1;
3816 }
3817
3818 static void vl_api_pg_create_interface_reply_t_handler_json
3819   (vl_api_pg_create_interface_reply_t * mp)
3820 {
3821   vat_main_t *vam = &vat_main;
3822   vat_json_node_t node;
3823
3824   i32 retval = ntohl (mp->retval);
3825   if (retval == 0)
3826     {
3827       vat_json_init_object (&node);
3828
3829       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3830
3831       vat_json_print (vam->ofp, &node);
3832       vat_json_free (&node);
3833     }
3834   vam->retval = ntohl (mp->retval);
3835   vam->result_ready = 1;
3836 }
3837
3838 static void vl_api_policer_classify_details_t_handler
3839   (vl_api_policer_classify_details_t * mp)
3840 {
3841   vat_main_t *vam = &vat_main;
3842
3843   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3844          ntohl (mp->table_index));
3845 }
3846
3847 static void vl_api_policer_classify_details_t_handler_json
3848   (vl_api_policer_classify_details_t * mp)
3849 {
3850   vat_main_t *vam = &vat_main;
3851   vat_json_node_t *node;
3852
3853   if (VAT_JSON_ARRAY != vam->json_tree.type)
3854     {
3855       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3856       vat_json_init_array (&vam->json_tree);
3857     }
3858   node = vat_json_array_add (&vam->json_tree);
3859
3860   vat_json_init_object (node);
3861   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3862   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3863 }
3864
3865 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3866   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3867 {
3868   vat_main_t *vam = &vat_main;
3869   i32 retval = ntohl (mp->retval);
3870   if (vam->async_mode)
3871     {
3872       vam->async_errors += (retval < 0);
3873     }
3874   else
3875     {
3876       vam->retval = retval;
3877       vam->sw_if_index = ntohl (mp->sw_if_index);
3878       vam->result_ready = 1;
3879     }
3880 }
3881
3882 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3883   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3884 {
3885   vat_main_t *vam = &vat_main;
3886   vat_json_node_t node;
3887
3888   vat_json_init_object (&node);
3889   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3890   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3891
3892   vat_json_print (vam->ofp, &node);
3893   vat_json_free (&node);
3894
3895   vam->retval = ntohl (mp->retval);
3896   vam->result_ready = 1;
3897 }
3898
3899 static void vl_api_flow_classify_details_t_handler
3900   (vl_api_flow_classify_details_t * mp)
3901 {
3902   vat_main_t *vam = &vat_main;
3903
3904   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3905          ntohl (mp->table_index));
3906 }
3907
3908 static void vl_api_flow_classify_details_t_handler_json
3909   (vl_api_flow_classify_details_t * mp)
3910 {
3911   vat_main_t *vam = &vat_main;
3912   vat_json_node_t *node;
3913
3914   if (VAT_JSON_ARRAY != vam->json_tree.type)
3915     {
3916       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3917       vat_json_init_array (&vam->json_tree);
3918     }
3919   node = vat_json_array_add (&vam->json_tree);
3920
3921   vat_json_init_object (node);
3922   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3923   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3924 }
3925
3926
3927
3928 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3929 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3930 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3931 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3932 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
3933 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
3934 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
3935 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
3936 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
3937 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
3938
3939 /*
3940  * Generate boilerplate reply handlers, which
3941  * dig the return value out of the xxx_reply_t API message,
3942  * stick it into vam->retval, and set vam->result_ready
3943  *
3944  * Could also do this by pointing N message decode slots at
3945  * a single function, but that could break in subtle ways.
3946  */
3947
3948 #define foreach_standard_reply_retval_handler           \
3949 _(sw_interface_set_flags_reply)                         \
3950 _(sw_interface_add_del_address_reply)                   \
3951 _(sw_interface_set_table_reply)                         \
3952 _(sw_interface_set_mpls_enable_reply)                   \
3953 _(sw_interface_set_vpath_reply)                         \
3954 _(sw_interface_set_vxlan_bypass_reply)                  \
3955 _(sw_interface_set_l2_bridge_reply)                     \
3956 _(bridge_domain_add_del_reply)                          \
3957 _(sw_interface_set_l2_xconnect_reply)                   \
3958 _(l2fib_add_del_reply)                                  \
3959 _(ip_add_del_route_reply)                               \
3960 _(ip_mroute_add_del_reply)                              \
3961 _(mpls_route_add_del_reply)                             \
3962 _(mpls_ip_bind_unbind_reply)                            \
3963 _(proxy_arp_add_del_reply)                              \
3964 _(proxy_arp_intfc_enable_disable_reply)                 \
3965 _(sw_interface_set_unnumbered_reply)                    \
3966 _(ip_neighbor_add_del_reply)                            \
3967 _(reset_vrf_reply)                                      \
3968 _(oam_add_del_reply)                                    \
3969 _(reset_fib_reply)                                      \
3970 _(dhcp_proxy_config_reply)                              \
3971 _(dhcp_proxy_set_vss_reply)                             \
3972 _(dhcp_client_config_reply)                             \
3973 _(set_ip_flow_hash_reply)                               \
3974 _(sw_interface_ip6_enable_disable_reply)                \
3975 _(sw_interface_ip6_set_link_local_address_reply)        \
3976 _(ip6nd_proxy_add_del_reply)                            \
3977 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3978 _(sw_interface_ip6nd_ra_config_reply)                   \
3979 _(set_arp_neighbor_limit_reply)                         \
3980 _(l2_patch_add_del_reply)                               \
3981 _(sr_policy_add_reply)                                  \
3982 _(sr_policy_mod_reply)                                  \
3983 _(sr_policy_del_reply)                                  \
3984 _(sr_localsid_add_del_reply)                            \
3985 _(sr_steering_add_del_reply)                            \
3986 _(classify_add_del_session_reply)                       \
3987 _(classify_set_interface_ip_table_reply)                \
3988 _(classify_set_interface_l2_tables_reply)               \
3989 _(l2tpv3_set_tunnel_cookies_reply)                      \
3990 _(l2tpv3_interface_enable_disable_reply)                \
3991 _(l2tpv3_set_lookup_key_reply)                          \
3992 _(l2_fib_clear_table_reply)                             \
3993 _(l2_interface_efp_filter_reply)                        \
3994 _(l2_interface_vlan_tag_rewrite_reply)                  \
3995 _(modify_vhost_user_if_reply)                           \
3996 _(delete_vhost_user_if_reply)                           \
3997 _(want_ip4_arp_events_reply)                            \
3998 _(want_ip6_nd_events_reply)                             \
3999 _(input_acl_set_interface_reply)                        \
4000 _(ipsec_spd_add_del_reply)                              \
4001 _(ipsec_interface_add_del_spd_reply)                    \
4002 _(ipsec_spd_add_del_entry_reply)                        \
4003 _(ipsec_sad_add_del_entry_reply)                        \
4004 _(ipsec_sa_set_key_reply)                               \
4005 _(ikev2_profile_add_del_reply)                          \
4006 _(ikev2_profile_set_auth_reply)                         \
4007 _(ikev2_profile_set_id_reply)                           \
4008 _(ikev2_profile_set_ts_reply)                           \
4009 _(ikev2_set_local_key_reply)                            \
4010 _(ikev2_set_responder_reply)                            \
4011 _(ikev2_set_ike_transforms_reply)                       \
4012 _(ikev2_set_esp_transforms_reply)                       \
4013 _(ikev2_set_sa_lifetime_reply)                          \
4014 _(ikev2_initiate_sa_init_reply)                         \
4015 _(ikev2_initiate_del_ike_sa_reply)                      \
4016 _(ikev2_initiate_del_child_sa_reply)                    \
4017 _(ikev2_initiate_rekey_child_sa_reply)                  \
4018 _(delete_loopback_reply)                                \
4019 _(bd_ip_mac_add_del_reply)                              \
4020 _(map_del_domain_reply)                                 \
4021 _(map_add_del_rule_reply)                               \
4022 _(want_interface_events_reply)                          \
4023 _(want_stats_reply)                                     \
4024 _(cop_interface_enable_disable_reply)                   \
4025 _(cop_whitelist_enable_disable_reply)                   \
4026 _(sw_interface_clear_stats_reply)                       \
4027 _(ioam_enable_reply)                              \
4028 _(ioam_disable_reply)                              \
4029 _(one_add_del_locator_reply)                            \
4030 _(one_add_del_local_eid_reply)                          \
4031 _(one_add_del_remote_mapping_reply)                     \
4032 _(one_add_del_adjacency_reply)                          \
4033 _(one_add_del_map_resolver_reply)                       \
4034 _(one_add_del_map_server_reply)                         \
4035 _(one_enable_disable_reply)                             \
4036 _(one_rloc_probe_enable_disable_reply)                  \
4037 _(one_map_register_enable_disable_reply)                \
4038 _(one_pitr_set_locator_set_reply)                       \
4039 _(one_map_request_mode_reply)                           \
4040 _(one_add_del_map_request_itr_rlocs_reply)              \
4041 _(one_eid_table_add_del_map_reply)                      \
4042 _(one_use_petr_reply)                                   \
4043 _(gpe_add_del_fwd_entry_reply)                          \
4044 _(gpe_enable_disable_reply)                             \
4045 _(gpe_set_encap_mode_reply)                             \
4046 _(gpe_add_del_iface_reply)                              \
4047 _(vxlan_gpe_add_del_tunnel_reply)                       \
4048 _(af_packet_delete_reply)                               \
4049 _(policer_classify_set_interface_reply)                 \
4050 _(netmap_create_reply)                                  \
4051 _(netmap_delete_reply)                                  \
4052 _(set_ipfix_exporter_reply)                             \
4053 _(set_ipfix_classify_stream_reply)                      \
4054 _(ipfix_classify_table_add_del_reply)                   \
4055 _(flow_classify_set_interface_reply)                    \
4056 _(sw_interface_span_enable_disable_reply)               \
4057 _(pg_capture_reply)                                     \
4058 _(pg_enable_disable_reply)                              \
4059 _(ip_source_and_port_range_check_add_del_reply)         \
4060 _(ip_source_and_port_range_check_interface_add_del_reply)\
4061 _(delete_subif_reply)                                   \
4062 _(l2_interface_pbb_tag_rewrite_reply)                   \
4063 _(punt_reply)                                           \
4064 _(feature_enable_disable_reply)                         \
4065 _(sw_interface_tag_add_del_reply)                       \
4066 _(sw_interface_set_mtu_reply)
4067
4068 #define _(n)                                    \
4069     static void vl_api_##n##_t_handler          \
4070     (vl_api_##n##_t * mp)                       \
4071     {                                           \
4072         vat_main_t * vam = &vat_main;           \
4073         i32 retval = ntohl(mp->retval);         \
4074         if (vam->async_mode) {                  \
4075             vam->async_errors += (retval < 0);  \
4076         } else {                                \
4077             vam->retval = retval;               \
4078             vam->result_ready = 1;              \
4079         }                                       \
4080     }
4081 foreach_standard_reply_retval_handler;
4082 #undef _
4083
4084 #define _(n)                                    \
4085     static void vl_api_##n##_t_handler_json     \
4086     (vl_api_##n##_t * mp)                       \
4087     {                                           \
4088         vat_main_t * vam = &vat_main;           \
4089         vat_json_node_t node;                   \
4090         vat_json_init_object(&node);            \
4091         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
4092         vat_json_print(vam->ofp, &node);        \
4093         vam->retval = ntohl(mp->retval);        \
4094         vam->result_ready = 1;                  \
4095     }
4096 foreach_standard_reply_retval_handler;
4097 #undef _
4098
4099 /*
4100  * Table of message reply handlers, must include boilerplate handlers
4101  * we just generated
4102  */
4103
4104 #define foreach_vpe_api_reply_msg                                       \
4105 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
4106 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
4107 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
4108 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
4109 _(CONTROL_PING_REPLY, control_ping_reply)                               \
4110 _(CLI_REPLY, cli_reply)                                                 \
4111 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
4112 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
4113   sw_interface_add_del_address_reply)                                   \
4114 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
4115 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
4116 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
4117 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
4118 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
4119   sw_interface_set_l2_xconnect_reply)                                   \
4120 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
4121   sw_interface_set_l2_bridge_reply)                                     \
4122 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
4123 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
4124 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
4125 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
4126 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
4127 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
4128 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
4129 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
4130 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
4131 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
4132 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
4133 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
4134 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
4135 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
4136 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
4137 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
4138   proxy_arp_intfc_enable_disable_reply)                                 \
4139 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
4140 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
4141   sw_interface_set_unnumbered_reply)                                    \
4142 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
4143 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
4144 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
4145 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
4146 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
4147 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
4148 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
4149 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
4150 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
4151 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
4152 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
4153 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
4154   sw_interface_ip6_enable_disable_reply)                                \
4155 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
4156   sw_interface_ip6_set_link_local_address_reply)                        \
4157 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
4158 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
4159 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
4160   sw_interface_ip6nd_ra_prefix_reply)                                   \
4161 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
4162   sw_interface_ip6nd_ra_config_reply)                                   \
4163 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
4164 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
4165 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
4166 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
4167 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
4168 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
4169 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
4170 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
4171 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
4172 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
4173 classify_set_interface_ip_table_reply)                                  \
4174 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
4175   classify_set_interface_l2_tables_reply)                               \
4176 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
4177 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
4178 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
4179 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
4180 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
4181   l2tpv3_interface_enable_disable_reply)                                \
4182 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
4183 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
4184 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
4185 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
4186 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
4187 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
4188 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
4189 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
4190 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4191 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
4192 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
4193 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
4194 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
4195 _(SHOW_VERSION_REPLY, show_version_reply)                               \
4196 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
4197 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
4198 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
4199 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
4200 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
4201 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
4202 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
4203 _(IP6_ND_EVENT, ip6_nd_event)                                           \
4204 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
4205 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
4206 _(IP_DETAILS, ip_details)                                               \
4207 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
4208 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4209 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
4210 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
4211 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
4212 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
4213 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
4214 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
4215 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
4216 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
4217 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
4218 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
4219 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
4220 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
4221 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
4222 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
4223 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
4224 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
4225 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
4226 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
4227 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
4228 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
4229 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
4230 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
4231 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
4232 _(MAP_RULE_DETAILS, map_rule_details)                                   \
4233 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
4234 _(WANT_STATS_REPLY, want_stats_reply)                                   \
4235 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
4236 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4237 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4238 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
4239 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
4240 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
4241 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
4242 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
4243 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
4244 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
4245 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
4246 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
4247 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
4248 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
4249 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
4250 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
4251   one_map_register_enable_disable_reply)                                \
4252 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
4253   one_rloc_probe_enable_disable_reply)                                  \
4254 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
4255 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
4256 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
4257 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
4258 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
4259 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
4260 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
4261 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
4262 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
4263 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
4264 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
4265 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
4266 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
4267 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
4268 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
4269 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
4270 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
4271 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
4272 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
4273   gpe_fwd_entry_path_details)                                           \
4274 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
4275 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
4276   one_add_del_map_request_itr_rlocs_reply)                              \
4277 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
4278   one_get_map_request_itr_rlocs_reply)                                  \
4279 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
4280 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
4281 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
4282 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
4283 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
4284   show_one_map_register_state_reply)                                    \
4285 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
4286 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
4287 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
4288 _(POLICER_DETAILS, policer_details)                                     \
4289 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4290 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
4291 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
4292 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
4293 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
4294 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
4295 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
4296 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4297 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
4298 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
4299 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
4300 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
4301 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
4302 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
4303 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4304 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
4305 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4306 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
4307 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
4308 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
4309 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
4310 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
4311 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
4312 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
4313 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
4314  ip_source_and_port_range_check_add_del_reply)                          \
4315 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
4316  ip_source_and_port_range_check_interface_add_del_reply)                \
4317 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
4318 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
4319 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
4320 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
4321 _(PUNT_REPLY, punt_reply)                                               \
4322 _(IP_FIB_DETAILS, ip_fib_details)                                       \
4323 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
4324 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
4325 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
4326 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
4327 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
4328 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
4329 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
4330
4331 #define foreach_standalone_reply_msg                                    \
4332 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
4333 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
4334 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
4335 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
4336 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
4337 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
4338
4339 typedef struct
4340 {
4341   u8 *name;
4342   u32 value;
4343 } name_sort_t;
4344
4345
4346 #define STR_VTR_OP_CASE(op)     \
4347     case L2_VTR_ ## op:         \
4348         return "" # op;
4349
4350 static const char *
4351 str_vtr_op (u32 vtr_op)
4352 {
4353   switch (vtr_op)
4354     {
4355       STR_VTR_OP_CASE (DISABLED);
4356       STR_VTR_OP_CASE (PUSH_1);
4357       STR_VTR_OP_CASE (PUSH_2);
4358       STR_VTR_OP_CASE (POP_1);
4359       STR_VTR_OP_CASE (POP_2);
4360       STR_VTR_OP_CASE (TRANSLATE_1_1);
4361       STR_VTR_OP_CASE (TRANSLATE_1_2);
4362       STR_VTR_OP_CASE (TRANSLATE_2_1);
4363       STR_VTR_OP_CASE (TRANSLATE_2_2);
4364     }
4365
4366   return "UNKNOWN";
4367 }
4368
4369 static int
4370 dump_sub_interface_table (vat_main_t * vam)
4371 {
4372   const sw_interface_subif_t *sub = NULL;
4373
4374   if (vam->json_output)
4375     {
4376       clib_warning
4377         ("JSON output supported only for VPE API calls and dump_stats_table");
4378       return -99;
4379     }
4380
4381   print (vam->ofp,
4382          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4383          "Interface", "sw_if_index",
4384          "sub id", "dot1ad", "tags", "outer id",
4385          "inner id", "exact", "default", "outer any", "inner any");
4386
4387   vec_foreach (sub, vam->sw_if_subif_table)
4388   {
4389     print (vam->ofp,
4390            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4391            sub->interface_name,
4392            sub->sw_if_index,
4393            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4394            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4395            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4396            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4397     if (sub->vtr_op != L2_VTR_DISABLED)
4398       {
4399         print (vam->ofp,
4400                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4401                "tag1: %d tag2: %d ]",
4402                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4403                sub->vtr_tag1, sub->vtr_tag2);
4404       }
4405   }
4406
4407   return 0;
4408 }
4409
4410 static int
4411 name_sort_cmp (void *a1, void *a2)
4412 {
4413   name_sort_t *n1 = a1;
4414   name_sort_t *n2 = a2;
4415
4416   return strcmp ((char *) n1->name, (char *) n2->name);
4417 }
4418
4419 static int
4420 dump_interface_table (vat_main_t * vam)
4421 {
4422   hash_pair_t *p;
4423   name_sort_t *nses = 0, *ns;
4424
4425   if (vam->json_output)
4426     {
4427       clib_warning
4428         ("JSON output supported only for VPE API calls and dump_stats_table");
4429       return -99;
4430     }
4431
4432   /* *INDENT-OFF* */
4433   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4434   ({
4435     vec_add2 (nses, ns, 1);
4436     ns->name = (u8 *)(p->key);
4437     ns->value = (u32) p->value[0];
4438   }));
4439   /* *INDENT-ON* */
4440
4441   vec_sort_with_function (nses, name_sort_cmp);
4442
4443   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4444   vec_foreach (ns, nses)
4445   {
4446     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4447   }
4448   vec_free (nses);
4449   return 0;
4450 }
4451
4452 static int
4453 dump_ip_table (vat_main_t * vam, int is_ipv6)
4454 {
4455   const ip_details_t *det = NULL;
4456   const ip_address_details_t *address = NULL;
4457   u32 i = ~0;
4458
4459   print (vam->ofp, "%-12s", "sw_if_index");
4460
4461   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4462   {
4463     i++;
4464     if (!det->present)
4465       {
4466         continue;
4467       }
4468     print (vam->ofp, "%-12d", i);
4469     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
4470     if (!det->addr)
4471       {
4472         continue;
4473       }
4474     vec_foreach (address, det->addr)
4475     {
4476       print (vam->ofp,
4477              "            %-30U%-13d",
4478              is_ipv6 ? format_ip6_address : format_ip4_address,
4479              address->ip, address->prefix_length);
4480     }
4481   }
4482
4483   return 0;
4484 }
4485
4486 static int
4487 dump_ipv4_table (vat_main_t * vam)
4488 {
4489   if (vam->json_output)
4490     {
4491       clib_warning
4492         ("JSON output supported only for VPE API calls and dump_stats_table");
4493       return -99;
4494     }
4495
4496   return dump_ip_table (vam, 0);
4497 }
4498
4499 static int
4500 dump_ipv6_table (vat_main_t * vam)
4501 {
4502   if (vam->json_output)
4503     {
4504       clib_warning
4505         ("JSON output supported only for VPE API calls and dump_stats_table");
4506       return -99;
4507     }
4508
4509   return dump_ip_table (vam, 1);
4510 }
4511
4512 static char *
4513 counter_type_to_str (u8 counter_type, u8 is_combined)
4514 {
4515   if (!is_combined)
4516     {
4517       switch (counter_type)
4518         {
4519         case VNET_INTERFACE_COUNTER_DROP:
4520           return "drop";
4521         case VNET_INTERFACE_COUNTER_PUNT:
4522           return "punt";
4523         case VNET_INTERFACE_COUNTER_IP4:
4524           return "ip4";
4525         case VNET_INTERFACE_COUNTER_IP6:
4526           return "ip6";
4527         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4528           return "rx-no-buf";
4529         case VNET_INTERFACE_COUNTER_RX_MISS:
4530           return "rx-miss";
4531         case VNET_INTERFACE_COUNTER_RX_ERROR:
4532           return "rx-error";
4533         case VNET_INTERFACE_COUNTER_TX_ERROR:
4534           return "tx-error";
4535         default:
4536           return "INVALID-COUNTER-TYPE";
4537         }
4538     }
4539   else
4540     {
4541       switch (counter_type)
4542         {
4543         case VNET_INTERFACE_COUNTER_RX:
4544           return "rx";
4545         case VNET_INTERFACE_COUNTER_TX:
4546           return "tx";
4547         default:
4548           return "INVALID-COUNTER-TYPE";
4549         }
4550     }
4551 }
4552
4553 static int
4554 dump_stats_table (vat_main_t * vam)
4555 {
4556   vat_json_node_t node;
4557   vat_json_node_t *msg_array;
4558   vat_json_node_t *msg;
4559   vat_json_node_t *counter_array;
4560   vat_json_node_t *counter;
4561   interface_counter_t c;
4562   u64 packets;
4563   ip4_fib_counter_t *c4;
4564   ip6_fib_counter_t *c6;
4565   ip4_nbr_counter_t *n4;
4566   ip6_nbr_counter_t *n6;
4567   int i, j;
4568
4569   if (!vam->json_output)
4570     {
4571       clib_warning ("dump_stats_table supported only in JSON format");
4572       return -99;
4573     }
4574
4575   vat_json_init_object (&node);
4576
4577   /* interface counters */
4578   msg_array = vat_json_object_add (&node, "interface_counters");
4579   vat_json_init_array (msg_array);
4580   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4581     {
4582       msg = vat_json_array_add (msg_array);
4583       vat_json_init_object (msg);
4584       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4585                                        (u8 *) counter_type_to_str (i, 0));
4586       vat_json_object_add_int (msg, "is_combined", 0);
4587       counter_array = vat_json_object_add (msg, "data");
4588       vat_json_init_array (counter_array);
4589       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4590         {
4591           packets = vam->simple_interface_counters[i][j];
4592           vat_json_array_add_uint (counter_array, packets);
4593         }
4594     }
4595   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4596     {
4597       msg = vat_json_array_add (msg_array);
4598       vat_json_init_object (msg);
4599       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4600                                        (u8 *) counter_type_to_str (i, 1));
4601       vat_json_object_add_int (msg, "is_combined", 1);
4602       counter_array = vat_json_object_add (msg, "data");
4603       vat_json_init_array (counter_array);
4604       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4605         {
4606           c = vam->combined_interface_counters[i][j];
4607           counter = vat_json_array_add (counter_array);
4608           vat_json_init_object (counter);
4609           vat_json_object_add_uint (counter, "packets", c.packets);
4610           vat_json_object_add_uint (counter, "bytes", c.bytes);
4611         }
4612     }
4613
4614   /* ip4 fib counters */
4615   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4616   vat_json_init_array (msg_array);
4617   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4618     {
4619       msg = vat_json_array_add (msg_array);
4620       vat_json_init_object (msg);
4621       vat_json_object_add_uint (msg, "vrf_id",
4622                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4623       counter_array = vat_json_object_add (msg, "c");
4624       vat_json_init_array (counter_array);
4625       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4626         {
4627           counter = vat_json_array_add (counter_array);
4628           vat_json_init_object (counter);
4629           c4 = &vam->ip4_fib_counters[i][j];
4630           vat_json_object_add_ip4 (counter, "address", c4->address);
4631           vat_json_object_add_uint (counter, "address_length",
4632                                     c4->address_length);
4633           vat_json_object_add_uint (counter, "packets", c4->packets);
4634           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4635         }
4636     }
4637
4638   /* ip6 fib counters */
4639   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4640   vat_json_init_array (msg_array);
4641   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4642     {
4643       msg = vat_json_array_add (msg_array);
4644       vat_json_init_object (msg);
4645       vat_json_object_add_uint (msg, "vrf_id",
4646                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4647       counter_array = vat_json_object_add (msg, "c");
4648       vat_json_init_array (counter_array);
4649       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4650         {
4651           counter = vat_json_array_add (counter_array);
4652           vat_json_init_object (counter);
4653           c6 = &vam->ip6_fib_counters[i][j];
4654           vat_json_object_add_ip6 (counter, "address", c6->address);
4655           vat_json_object_add_uint (counter, "address_length",
4656                                     c6->address_length);
4657           vat_json_object_add_uint (counter, "packets", c6->packets);
4658           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4659         }
4660     }
4661
4662   /* ip4 nbr counters */
4663   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
4664   vat_json_init_array (msg_array);
4665   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
4666     {
4667       msg = vat_json_array_add (msg_array);
4668       vat_json_init_object (msg);
4669       vat_json_object_add_uint (msg, "sw_if_index", i);
4670       counter_array = vat_json_object_add (msg, "c");
4671       vat_json_init_array (counter_array);
4672       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
4673         {
4674           counter = vat_json_array_add (counter_array);
4675           vat_json_init_object (counter);
4676           n4 = &vam->ip4_nbr_counters[i][j];
4677           vat_json_object_add_ip4 (counter, "address", n4->address);
4678           vat_json_object_add_uint (counter, "link-type", n4->linkt);
4679           vat_json_object_add_uint (counter, "packets", n4->packets);
4680           vat_json_object_add_uint (counter, "bytes", n4->bytes);
4681         }
4682     }
4683
4684   /* ip6 nbr counters */
4685   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
4686   vat_json_init_array (msg_array);
4687   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
4688     {
4689       msg = vat_json_array_add (msg_array);
4690       vat_json_init_object (msg);
4691       vat_json_object_add_uint (msg, "sw_if_index", i);
4692       counter_array = vat_json_object_add (msg, "c");
4693       vat_json_init_array (counter_array);
4694       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
4695         {
4696           counter = vat_json_array_add (counter_array);
4697           vat_json_init_object (counter);
4698           n6 = &vam->ip6_nbr_counters[i][j];
4699           vat_json_object_add_ip6 (counter, "address", n6->address);
4700           vat_json_object_add_uint (counter, "packets", n6->packets);
4701           vat_json_object_add_uint (counter, "bytes", n6->bytes);
4702         }
4703     }
4704
4705   vat_json_print (vam->ofp, &node);
4706   vat_json_free (&node);
4707
4708   return 0;
4709 }
4710
4711 int
4712 exec (vat_main_t * vam)
4713 {
4714   api_main_t *am = &api_main;
4715   vl_api_cli_request_t *mp;
4716   f64 timeout;
4717   void *oldheap;
4718   u8 *cmd = 0;
4719   unformat_input_t *i = vam->input;
4720
4721   if (vec_len (i->buffer) == 0)
4722     return -1;
4723
4724   if (vam->exec_mode == 0 && unformat (i, "mode"))
4725     {
4726       vam->exec_mode = 1;
4727       return 0;
4728     }
4729   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4730     {
4731       vam->exec_mode = 0;
4732       return 0;
4733     }
4734
4735
4736   M (CLI_REQUEST, mp);
4737
4738   /*
4739    * Copy cmd into shared memory.
4740    * In order for the CLI command to work, it
4741    * must be a vector ending in \n, not a C-string ending
4742    * in \n\0.
4743    */
4744   pthread_mutex_lock (&am->vlib_rp->mutex);
4745   oldheap = svm_push_data_heap (am->vlib_rp);
4746
4747   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4748   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4749
4750   svm_pop_heap (oldheap);
4751   pthread_mutex_unlock (&am->vlib_rp->mutex);
4752
4753   mp->cmd_in_shmem = (u64) cmd;
4754   S (mp);
4755   timeout = vat_time_now (vam) + 10.0;
4756
4757   while (vat_time_now (vam) < timeout)
4758     {
4759       if (vam->result_ready == 1)
4760         {
4761           u8 *free_me;
4762           if (vam->shmem_result != NULL)
4763             print (vam->ofp, "%s", vam->shmem_result);
4764           pthread_mutex_lock (&am->vlib_rp->mutex);
4765           oldheap = svm_push_data_heap (am->vlib_rp);
4766
4767           free_me = (u8 *) vam->shmem_result;
4768           vec_free (free_me);
4769
4770           svm_pop_heap (oldheap);
4771           pthread_mutex_unlock (&am->vlib_rp->mutex);
4772           return 0;
4773         }
4774     }
4775   return -99;
4776 }
4777
4778 /*
4779  * Future replacement of exec() that passes CLI buffers directly in
4780  * the API messages instead of an additional shared memory area.
4781  */
4782 static int
4783 exec_inband (vat_main_t * vam)
4784 {
4785   vl_api_cli_inband_t *mp;
4786   unformat_input_t *i = vam->input;
4787   int ret;
4788
4789   if (vec_len (i->buffer) == 0)
4790     return -1;
4791
4792   if (vam->exec_mode == 0 && unformat (i, "mode"))
4793     {
4794       vam->exec_mode = 1;
4795       return 0;
4796     }
4797   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4798     {
4799       vam->exec_mode = 0;
4800       return 0;
4801     }
4802
4803   /*
4804    * In order for the CLI command to work, it
4805    * must be a vector ending in \n, not a C-string ending
4806    * in \n\0.
4807    */
4808   u32 len = vec_len (vam->input->buffer);
4809   M2 (CLI_INBAND, mp, len);
4810   clib_memcpy (mp->cmd, vam->input->buffer, len);
4811   mp->length = htonl (len);
4812
4813   S (mp);
4814   W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
4815   return ret;
4816 }
4817
4818 static int
4819 api_create_loopback (vat_main_t * vam)
4820 {
4821   unformat_input_t *i = vam->input;
4822   vl_api_create_loopback_t *mp;
4823   vl_api_create_loopback_instance_t *mp_lbi;
4824   u8 mac_address[6];
4825   u8 mac_set = 0;
4826   u8 is_specified = 0;
4827   u32 user_instance = 0;
4828   int ret;
4829
4830   memset (mac_address, 0, sizeof (mac_address));
4831
4832   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4833     {
4834       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4835         mac_set = 1;
4836       if (unformat (i, "instance %d", &user_instance))
4837         is_specified = 1;
4838       else
4839         break;
4840     }
4841
4842   if (is_specified)
4843     {
4844       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
4845       mp_lbi->is_specified = is_specified;
4846       if (is_specified)
4847         mp_lbi->user_instance = htonl (user_instance);
4848       if (mac_set)
4849         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
4850       S (mp_lbi);
4851     }
4852   else
4853     {
4854       /* Construct the API message */
4855       M (CREATE_LOOPBACK, mp);
4856       if (mac_set)
4857         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4858       S (mp);
4859     }
4860
4861   W (ret);
4862   return ret;
4863 }
4864
4865 static int
4866 api_delete_loopback (vat_main_t * vam)
4867 {
4868   unformat_input_t *i = vam->input;
4869   vl_api_delete_loopback_t *mp;
4870   u32 sw_if_index = ~0;
4871   int ret;
4872
4873   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4874     {
4875       if (unformat (i, "sw_if_index %d", &sw_if_index))
4876         ;
4877       else
4878         break;
4879     }
4880
4881   if (sw_if_index == ~0)
4882     {
4883       errmsg ("missing sw_if_index");
4884       return -99;
4885     }
4886
4887   /* Construct the API message */
4888   M (DELETE_LOOPBACK, mp);
4889   mp->sw_if_index = ntohl (sw_if_index);
4890
4891   S (mp);
4892   W (ret);
4893   return ret;
4894 }
4895
4896 static int
4897 api_want_stats (vat_main_t * vam)
4898 {
4899   unformat_input_t *i = vam->input;
4900   vl_api_want_stats_t *mp;
4901   int enable = -1;
4902   int ret;
4903
4904   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4905     {
4906       if (unformat (i, "enable"))
4907         enable = 1;
4908       else if (unformat (i, "disable"))
4909         enable = 0;
4910       else
4911         break;
4912     }
4913
4914   if (enable == -1)
4915     {
4916       errmsg ("missing enable|disable");
4917       return -99;
4918     }
4919
4920   M (WANT_STATS, mp);
4921   mp->enable_disable = enable;
4922
4923   S (mp);
4924   W (ret);
4925   return ret;
4926 }
4927
4928 static int
4929 api_want_interface_events (vat_main_t * vam)
4930 {
4931   unformat_input_t *i = vam->input;
4932   vl_api_want_interface_events_t *mp;
4933   int enable = -1;
4934   int ret;
4935
4936   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4937     {
4938       if (unformat (i, "enable"))
4939         enable = 1;
4940       else if (unformat (i, "disable"))
4941         enable = 0;
4942       else
4943         break;
4944     }
4945
4946   if (enable == -1)
4947     {
4948       errmsg ("missing enable|disable");
4949       return -99;
4950     }
4951
4952   M (WANT_INTERFACE_EVENTS, mp);
4953   mp->enable_disable = enable;
4954
4955   vam->interface_event_display = enable;
4956
4957   S (mp);
4958   W (ret);
4959   return ret;
4960 }
4961
4962
4963 /* Note: non-static, called once to set up the initial intfc table */
4964 int
4965 api_sw_interface_dump (vat_main_t * vam)
4966 {
4967   vl_api_sw_interface_dump_t *mp;
4968   vl_api_control_ping_t *mp_ping;
4969   hash_pair_t *p;
4970   name_sort_t *nses = 0, *ns;
4971   sw_interface_subif_t *sub = NULL;
4972   int ret;
4973
4974   /* Toss the old name table */
4975   /* *INDENT-OFF* */
4976   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4977   ({
4978     vec_add2 (nses, ns, 1);
4979     ns->name = (u8 *)(p->key);
4980     ns->value = (u32) p->value[0];
4981   }));
4982   /* *INDENT-ON* */
4983
4984   hash_free (vam->sw_if_index_by_interface_name);
4985
4986   vec_foreach (ns, nses) vec_free (ns->name);
4987
4988   vec_free (nses);
4989
4990   vec_foreach (sub, vam->sw_if_subif_table)
4991   {
4992     vec_free (sub->interface_name);
4993   }
4994   vec_free (vam->sw_if_subif_table);
4995
4996   /* recreate the interface name hash table */
4997   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4998
4999   /* Get list of ethernets */
5000   M (SW_INTERFACE_DUMP, mp);
5001   mp->name_filter_valid = 1;
5002   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
5003   S (mp);
5004
5005   /* and local / loopback interfaces */
5006   M (SW_INTERFACE_DUMP, mp);
5007   mp->name_filter_valid = 1;
5008   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
5009   S (mp);
5010
5011   /* and packet-generator interfaces */
5012   M (SW_INTERFACE_DUMP, mp);
5013   mp->name_filter_valid = 1;
5014   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
5015   S (mp);
5016
5017   /* and vxlan-gpe tunnel interfaces */
5018   M (SW_INTERFACE_DUMP, mp);
5019   mp->name_filter_valid = 1;
5020   strncpy ((char *) mp->name_filter, "vxlan_gpe",
5021            sizeof (mp->name_filter) - 1);
5022   S (mp);
5023
5024   /* and vxlan tunnel interfaces */
5025   M (SW_INTERFACE_DUMP, mp);
5026   mp->name_filter_valid = 1;
5027   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
5028   S (mp);
5029
5030   /* and host (af_packet) interfaces */
5031   M (SW_INTERFACE_DUMP, mp);
5032   mp->name_filter_valid = 1;
5033   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
5034   S (mp);
5035
5036   /* and l2tpv3 tunnel interfaces */
5037   M (SW_INTERFACE_DUMP, mp);
5038   mp->name_filter_valid = 1;
5039   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
5040            sizeof (mp->name_filter) - 1);
5041   S (mp);
5042
5043   /* and GRE tunnel interfaces */
5044   M (SW_INTERFACE_DUMP, mp);
5045   mp->name_filter_valid = 1;
5046   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
5047   S (mp);
5048
5049   /* and LISP-GPE interfaces */
5050   M (SW_INTERFACE_DUMP, mp);
5051   mp->name_filter_valid = 1;
5052   strncpy ((char *) mp->name_filter, "lisp_gpe",
5053            sizeof (mp->name_filter) - 1);
5054   S (mp);
5055
5056   /* and IPSEC tunnel interfaces */
5057   M (SW_INTERFACE_DUMP, mp);
5058   mp->name_filter_valid = 1;
5059   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
5060   S (mp);
5061
5062   /* Use a control ping for synchronization */
5063   M (CONTROL_PING, mp_ping);
5064   S (mp_ping);
5065
5066   W (ret);
5067   return ret;
5068 }
5069
5070 static int
5071 api_sw_interface_set_flags (vat_main_t * vam)
5072 {
5073   unformat_input_t *i = vam->input;
5074   vl_api_sw_interface_set_flags_t *mp;
5075   u32 sw_if_index;
5076   u8 sw_if_index_set = 0;
5077   u8 admin_up = 0, link_up = 0;
5078   int ret;
5079
5080   /* Parse args required to build the message */
5081   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5082     {
5083       if (unformat (i, "admin-up"))
5084         admin_up = 1;
5085       else if (unformat (i, "admin-down"))
5086         admin_up = 0;
5087       else if (unformat (i, "link-up"))
5088         link_up = 1;
5089       else if (unformat (i, "link-down"))
5090         link_up = 0;
5091       else
5092         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5093         sw_if_index_set = 1;
5094       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5095         sw_if_index_set = 1;
5096       else
5097         break;
5098     }
5099
5100   if (sw_if_index_set == 0)
5101     {
5102       errmsg ("missing interface name or sw_if_index");
5103       return -99;
5104     }
5105
5106   /* Construct the API message */
5107   M (SW_INTERFACE_SET_FLAGS, mp);
5108   mp->sw_if_index = ntohl (sw_if_index);
5109   mp->admin_up_down = admin_up;
5110   mp->link_up_down = link_up;
5111
5112   /* send it... */
5113   S (mp);
5114
5115   /* Wait for a reply, return the good/bad news... */
5116   W (ret);
5117   return ret;
5118 }
5119
5120 static int
5121 api_sw_interface_clear_stats (vat_main_t * vam)
5122 {
5123   unformat_input_t *i = vam->input;
5124   vl_api_sw_interface_clear_stats_t *mp;
5125   u32 sw_if_index;
5126   u8 sw_if_index_set = 0;
5127   int ret;
5128
5129   /* Parse args required to build the message */
5130   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5131     {
5132       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5133         sw_if_index_set = 1;
5134       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5135         sw_if_index_set = 1;
5136       else
5137         break;
5138     }
5139
5140   /* Construct the API message */
5141   M (SW_INTERFACE_CLEAR_STATS, mp);
5142
5143   if (sw_if_index_set == 1)
5144     mp->sw_if_index = ntohl (sw_if_index);
5145   else
5146     mp->sw_if_index = ~0;
5147
5148   /* send it... */
5149   S (mp);
5150
5151   /* Wait for a reply, return the good/bad news... */
5152   W (ret);
5153   return ret;
5154 }
5155
5156 static int
5157 api_sw_interface_add_del_address (vat_main_t * vam)
5158 {
5159   unformat_input_t *i = vam->input;
5160   vl_api_sw_interface_add_del_address_t *mp;
5161   u32 sw_if_index;
5162   u8 sw_if_index_set = 0;
5163   u8 is_add = 1, del_all = 0;
5164   u32 address_length = 0;
5165   u8 v4_address_set = 0;
5166   u8 v6_address_set = 0;
5167   ip4_address_t v4address;
5168   ip6_address_t v6address;
5169   int ret;
5170
5171   /* Parse args required to build the message */
5172   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5173     {
5174       if (unformat (i, "del-all"))
5175         del_all = 1;
5176       else if (unformat (i, "del"))
5177         is_add = 0;
5178       else
5179         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5180         sw_if_index_set = 1;
5181       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5182         sw_if_index_set = 1;
5183       else if (unformat (i, "%U/%d",
5184                          unformat_ip4_address, &v4address, &address_length))
5185         v4_address_set = 1;
5186       else if (unformat (i, "%U/%d",
5187                          unformat_ip6_address, &v6address, &address_length))
5188         v6_address_set = 1;
5189       else
5190         break;
5191     }
5192
5193   if (sw_if_index_set == 0)
5194     {
5195       errmsg ("missing interface name or sw_if_index");
5196       return -99;
5197     }
5198   if (v4_address_set && v6_address_set)
5199     {
5200       errmsg ("both v4 and v6 addresses set");
5201       return -99;
5202     }
5203   if (!v4_address_set && !v6_address_set && !del_all)
5204     {
5205       errmsg ("no addresses set");
5206       return -99;
5207     }
5208
5209   /* Construct the API message */
5210   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
5211
5212   mp->sw_if_index = ntohl (sw_if_index);
5213   mp->is_add = is_add;
5214   mp->del_all = del_all;
5215   if (v6_address_set)
5216     {
5217       mp->is_ipv6 = 1;
5218       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5219     }
5220   else
5221     {
5222       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5223     }
5224   mp->address_length = address_length;
5225
5226   /* send it... */
5227   S (mp);
5228
5229   /* Wait for a reply, return good/bad news  */
5230   W (ret);
5231   return ret;
5232 }
5233
5234 static int
5235 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5236 {
5237   unformat_input_t *i = vam->input;
5238   vl_api_sw_interface_set_mpls_enable_t *mp;
5239   u32 sw_if_index;
5240   u8 sw_if_index_set = 0;
5241   u8 enable = 1;
5242   int ret;
5243
5244   /* Parse args required to build the message */
5245   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5246     {
5247       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5248         sw_if_index_set = 1;
5249       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5250         sw_if_index_set = 1;
5251       else if (unformat (i, "disable"))
5252         enable = 0;
5253       else if (unformat (i, "dis"))
5254         enable = 0;
5255       else
5256         break;
5257     }
5258
5259   if (sw_if_index_set == 0)
5260     {
5261       errmsg ("missing interface name or sw_if_index");
5262       return -99;
5263     }
5264
5265   /* Construct the API message */
5266   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
5267
5268   mp->sw_if_index = ntohl (sw_if_index);
5269   mp->enable = enable;
5270
5271   /* send it... */
5272   S (mp);
5273
5274   /* Wait for a reply... */
5275   W (ret);
5276   return ret;
5277 }
5278
5279 static int
5280 api_sw_interface_set_table (vat_main_t * vam)
5281 {
5282   unformat_input_t *i = vam->input;
5283   vl_api_sw_interface_set_table_t *mp;
5284   u32 sw_if_index, vrf_id = 0;
5285   u8 sw_if_index_set = 0;
5286   u8 is_ipv6 = 0;
5287   int ret;
5288
5289   /* Parse args required to build the message */
5290   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5291     {
5292       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5293         sw_if_index_set = 1;
5294       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5295         sw_if_index_set = 1;
5296       else if (unformat (i, "vrf %d", &vrf_id))
5297         ;
5298       else if (unformat (i, "ipv6"))
5299         is_ipv6 = 1;
5300       else
5301         break;
5302     }
5303
5304   if (sw_if_index_set == 0)
5305     {
5306       errmsg ("missing interface name or sw_if_index");
5307       return -99;
5308     }
5309
5310   /* Construct the API message */
5311   M (SW_INTERFACE_SET_TABLE, mp);
5312
5313   mp->sw_if_index = ntohl (sw_if_index);
5314   mp->is_ipv6 = is_ipv6;
5315   mp->vrf_id = ntohl (vrf_id);
5316
5317   /* send it... */
5318   S (mp);
5319
5320   /* Wait for a reply... */
5321   W (ret);
5322   return ret;
5323 }
5324
5325 static void vl_api_sw_interface_get_table_reply_t_handler
5326   (vl_api_sw_interface_get_table_reply_t * mp)
5327 {
5328   vat_main_t *vam = &vat_main;
5329
5330   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5331
5332   vam->retval = ntohl (mp->retval);
5333   vam->result_ready = 1;
5334
5335 }
5336
5337 static void vl_api_sw_interface_get_table_reply_t_handler_json
5338   (vl_api_sw_interface_get_table_reply_t * mp)
5339 {
5340   vat_main_t *vam = &vat_main;
5341   vat_json_node_t node;
5342
5343   vat_json_init_object (&node);
5344   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5345   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5346
5347   vat_json_print (vam->ofp, &node);
5348   vat_json_free (&node);
5349
5350   vam->retval = ntohl (mp->retval);
5351   vam->result_ready = 1;
5352 }
5353
5354 static int
5355 api_sw_interface_get_table (vat_main_t * vam)
5356 {
5357   unformat_input_t *i = vam->input;
5358   vl_api_sw_interface_get_table_t *mp;
5359   u32 sw_if_index;
5360   u8 sw_if_index_set = 0;
5361   u8 is_ipv6 = 0;
5362   int ret;
5363
5364   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5365     {
5366       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5367         sw_if_index_set = 1;
5368       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5369         sw_if_index_set = 1;
5370       else if (unformat (i, "ipv6"))
5371         is_ipv6 = 1;
5372       else
5373         break;
5374     }
5375
5376   if (sw_if_index_set == 0)
5377     {
5378       errmsg ("missing interface name or sw_if_index");
5379       return -99;
5380     }
5381
5382   M (SW_INTERFACE_GET_TABLE, mp);
5383   mp->sw_if_index = htonl (sw_if_index);
5384   mp->is_ipv6 = is_ipv6;
5385
5386   S (mp);
5387   W (ret);
5388   return ret;
5389 }
5390
5391 static int
5392 api_sw_interface_set_vpath (vat_main_t * vam)
5393 {
5394   unformat_input_t *i = vam->input;
5395   vl_api_sw_interface_set_vpath_t *mp;
5396   u32 sw_if_index = 0;
5397   u8 sw_if_index_set = 0;
5398   u8 is_enable = 0;
5399   int ret;
5400
5401   /* Parse args required to build the message */
5402   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5403     {
5404       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5405         sw_if_index_set = 1;
5406       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5407         sw_if_index_set = 1;
5408       else if (unformat (i, "enable"))
5409         is_enable = 1;
5410       else if (unformat (i, "disable"))
5411         is_enable = 0;
5412       else
5413         break;
5414     }
5415
5416   if (sw_if_index_set == 0)
5417     {
5418       errmsg ("missing interface name or sw_if_index");
5419       return -99;
5420     }
5421
5422   /* Construct the API message */
5423   M (SW_INTERFACE_SET_VPATH, mp);
5424
5425   mp->sw_if_index = ntohl (sw_if_index);
5426   mp->enable = is_enable;
5427
5428   /* send it... */
5429   S (mp);
5430
5431   /* Wait for a reply... */
5432   W (ret);
5433   return ret;
5434 }
5435
5436 static int
5437 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5438 {
5439   unformat_input_t *i = vam->input;
5440   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5441   u32 sw_if_index = 0;
5442   u8 sw_if_index_set = 0;
5443   u8 is_enable = 1;
5444   u8 is_ipv6 = 0;
5445   int ret;
5446
5447   /* Parse args required to build the message */
5448   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5449     {
5450       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5451         sw_if_index_set = 1;
5452       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5453         sw_if_index_set = 1;
5454       else if (unformat (i, "enable"))
5455         is_enable = 1;
5456       else if (unformat (i, "disable"))
5457         is_enable = 0;
5458       else if (unformat (i, "ip4"))
5459         is_ipv6 = 0;
5460       else if (unformat (i, "ip6"))
5461         is_ipv6 = 1;
5462       else
5463         break;
5464     }
5465
5466   if (sw_if_index_set == 0)
5467     {
5468       errmsg ("missing interface name or sw_if_index");
5469       return -99;
5470     }
5471
5472   /* Construct the API message */
5473   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
5474
5475   mp->sw_if_index = ntohl (sw_if_index);
5476   mp->enable = is_enable;
5477   mp->is_ipv6 = is_ipv6;
5478
5479   /* send it... */
5480   S (mp);
5481
5482   /* Wait for a reply... */
5483   W (ret);
5484   return ret;
5485 }
5486
5487 static int
5488 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5489 {
5490   unformat_input_t *i = vam->input;
5491   vl_api_sw_interface_set_l2_xconnect_t *mp;
5492   u32 rx_sw_if_index;
5493   u8 rx_sw_if_index_set = 0;
5494   u32 tx_sw_if_index;
5495   u8 tx_sw_if_index_set = 0;
5496   u8 enable = 1;
5497   int ret;
5498
5499   /* Parse args required to build the message */
5500   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5501     {
5502       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5503         rx_sw_if_index_set = 1;
5504       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5505         tx_sw_if_index_set = 1;
5506       else if (unformat (i, "rx"))
5507         {
5508           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5509             {
5510               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5511                             &rx_sw_if_index))
5512                 rx_sw_if_index_set = 1;
5513             }
5514           else
5515             break;
5516         }
5517       else if (unformat (i, "tx"))
5518         {
5519           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5520             {
5521               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5522                             &tx_sw_if_index))
5523                 tx_sw_if_index_set = 1;
5524             }
5525           else
5526             break;
5527         }
5528       else if (unformat (i, "enable"))
5529         enable = 1;
5530       else if (unformat (i, "disable"))
5531         enable = 0;
5532       else
5533         break;
5534     }
5535
5536   if (rx_sw_if_index_set == 0)
5537     {
5538       errmsg ("missing rx interface name or rx_sw_if_index");
5539       return -99;
5540     }
5541
5542   if (enable && (tx_sw_if_index_set == 0))
5543     {
5544       errmsg ("missing tx interface name or tx_sw_if_index");
5545       return -99;
5546     }
5547
5548   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
5549
5550   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5551   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5552   mp->enable = enable;
5553
5554   S (mp);
5555   W (ret);
5556   return ret;
5557 }
5558
5559 static int
5560 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5561 {
5562   unformat_input_t *i = vam->input;
5563   vl_api_sw_interface_set_l2_bridge_t *mp;
5564   u32 rx_sw_if_index;
5565   u8 rx_sw_if_index_set = 0;
5566   u32 bd_id;
5567   u8 bd_id_set = 0;
5568   u8 bvi = 0;
5569   u32 shg = 0;
5570   u8 enable = 1;
5571   int ret;
5572
5573   /* Parse args required to build the message */
5574   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5575     {
5576       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5577         rx_sw_if_index_set = 1;
5578       else if (unformat (i, "bd_id %d", &bd_id))
5579         bd_id_set = 1;
5580       else
5581         if (unformat
5582             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5583         rx_sw_if_index_set = 1;
5584       else if (unformat (i, "shg %d", &shg))
5585         ;
5586       else if (unformat (i, "bvi"))
5587         bvi = 1;
5588       else if (unformat (i, "enable"))
5589         enable = 1;
5590       else if (unformat (i, "disable"))
5591         enable = 0;
5592       else
5593         break;
5594     }
5595
5596   if (rx_sw_if_index_set == 0)
5597     {
5598       errmsg ("missing rx interface name or sw_if_index");
5599       return -99;
5600     }
5601
5602   if (enable && (bd_id_set == 0))
5603     {
5604       errmsg ("missing bridge domain");
5605       return -99;
5606     }
5607
5608   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
5609
5610   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5611   mp->bd_id = ntohl (bd_id);
5612   mp->shg = (u8) shg;
5613   mp->bvi = bvi;
5614   mp->enable = enable;
5615
5616   S (mp);
5617   W (ret);
5618   return ret;
5619 }
5620
5621 static int
5622 api_bridge_domain_dump (vat_main_t * vam)
5623 {
5624   unformat_input_t *i = vam->input;
5625   vl_api_bridge_domain_dump_t *mp;
5626   vl_api_control_ping_t *mp_ping;
5627   u32 bd_id = ~0;
5628   int ret;
5629
5630   /* Parse args required to build the message */
5631   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5632     {
5633       if (unformat (i, "bd_id %d", &bd_id))
5634         ;
5635       else
5636         break;
5637     }
5638
5639   M (BRIDGE_DOMAIN_DUMP, mp);
5640   mp->bd_id = ntohl (bd_id);
5641   S (mp);
5642
5643   /* Use a control ping for synchronization */
5644   M (CONTROL_PING, mp_ping);
5645   S (mp_ping);
5646
5647   W (ret);
5648   return ret;
5649 }
5650
5651 static int
5652 api_bridge_domain_add_del (vat_main_t * vam)
5653 {
5654   unformat_input_t *i = vam->input;
5655   vl_api_bridge_domain_add_del_t *mp;
5656   u32 bd_id = ~0;
5657   u8 is_add = 1;
5658   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5659   u32 mac_age = 0;
5660   int ret;
5661
5662   /* Parse args required to build the message */
5663   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5664     {
5665       if (unformat (i, "bd_id %d", &bd_id))
5666         ;
5667       else if (unformat (i, "flood %d", &flood))
5668         ;
5669       else if (unformat (i, "uu-flood %d", &uu_flood))
5670         ;
5671       else if (unformat (i, "forward %d", &forward))
5672         ;
5673       else if (unformat (i, "learn %d", &learn))
5674         ;
5675       else if (unformat (i, "arp-term %d", &arp_term))
5676         ;
5677       else if (unformat (i, "mac-age %d", &mac_age))
5678         ;
5679       else if (unformat (i, "del"))
5680         {
5681           is_add = 0;
5682           flood = uu_flood = forward = learn = 0;
5683         }
5684       else
5685         break;
5686     }
5687
5688   if (bd_id == ~0)
5689     {
5690       errmsg ("missing bridge domain");
5691       return -99;
5692     }
5693
5694   if (mac_age > 255)
5695     {
5696       errmsg ("mac age must be less than 256 ");
5697       return -99;
5698     }
5699
5700   M (BRIDGE_DOMAIN_ADD_DEL, mp);
5701
5702   mp->bd_id = ntohl (bd_id);
5703   mp->flood = flood;
5704   mp->uu_flood = uu_flood;
5705   mp->forward = forward;
5706   mp->learn = learn;
5707   mp->arp_term = arp_term;
5708   mp->is_add = is_add;
5709   mp->mac_age = (u8) mac_age;
5710
5711   S (mp);
5712   W (ret);
5713   return ret;
5714 }
5715
5716 static int
5717 api_l2fib_add_del (vat_main_t * vam)
5718 {
5719   unformat_input_t *i = vam->input;
5720   vl_api_l2fib_add_del_t *mp;
5721   f64 timeout;
5722   u64 mac = 0;
5723   u8 mac_set = 0;
5724   u32 bd_id;
5725   u8 bd_id_set = 0;
5726   u32 sw_if_index = ~0;
5727   u8 sw_if_index_set = 0;
5728   u8 is_add = 1;
5729   u8 static_mac = 0;
5730   u8 filter_mac = 0;
5731   u8 bvi_mac = 0;
5732   int count = 1;
5733   f64 before = 0;
5734   int j;
5735
5736   /* Parse args required to build the message */
5737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5738     {
5739       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5740         mac_set = 1;
5741       else if (unformat (i, "bd_id %d", &bd_id))
5742         bd_id_set = 1;
5743       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5744         sw_if_index_set = 1;
5745       else if (unformat (i, "sw_if"))
5746         {
5747           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5748             {
5749               if (unformat
5750                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5751                 sw_if_index_set = 1;
5752             }
5753           else
5754             break;
5755         }
5756       else if (unformat (i, "static"))
5757         static_mac = 1;
5758       else if (unformat (i, "filter"))
5759         {
5760           filter_mac = 1;
5761           static_mac = 1;
5762         }
5763       else if (unformat (i, "bvi"))
5764         {
5765           bvi_mac = 1;
5766           static_mac = 1;
5767         }
5768       else if (unformat (i, "del"))
5769         is_add = 0;
5770       else if (unformat (i, "count %d", &count))
5771         ;
5772       else
5773         break;
5774     }
5775
5776   if (mac_set == 0)
5777     {
5778       errmsg ("missing mac address");
5779       return -99;
5780     }
5781
5782   if (bd_id_set == 0)
5783     {
5784       errmsg ("missing bridge domain");
5785       return -99;
5786     }
5787
5788   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
5789     {
5790       errmsg ("missing interface name or sw_if_index");
5791       return -99;
5792     }
5793
5794   if (count > 1)
5795     {
5796       /* Turn on async mode */
5797       vam->async_mode = 1;
5798       vam->async_errors = 0;
5799       before = vat_time_now (vam);
5800     }
5801
5802   for (j = 0; j < count; j++)
5803     {
5804       M (L2FIB_ADD_DEL, mp);
5805
5806       mp->mac = mac;
5807       mp->bd_id = ntohl (bd_id);
5808       mp->is_add = is_add;
5809
5810       if (is_add)
5811         {
5812           mp->sw_if_index = ntohl (sw_if_index);
5813           mp->static_mac = static_mac;
5814           mp->filter_mac = filter_mac;
5815           mp->bvi_mac = bvi_mac;
5816         }
5817       increment_mac_address (&mac);
5818       /* send it... */
5819       S (mp);
5820     }
5821
5822   if (count > 1)
5823     {
5824       vl_api_control_ping_t *mp_ping;
5825       f64 after;
5826
5827       /* Shut off async mode */
5828       vam->async_mode = 0;
5829
5830       M (CONTROL_PING, mp_ping);
5831       S (mp_ping);
5832
5833       timeout = vat_time_now (vam) + 1.0;
5834       while (vat_time_now (vam) < timeout)
5835         if (vam->result_ready == 1)
5836           goto out;
5837       vam->retval = -99;
5838
5839     out:
5840       if (vam->retval == -99)
5841         errmsg ("timeout");
5842
5843       if (vam->async_errors > 0)
5844         {
5845           errmsg ("%d asynchronous errors", vam->async_errors);
5846           vam->retval = -98;
5847         }
5848       vam->async_errors = 0;
5849       after = vat_time_now (vam);
5850
5851       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
5852              count, after - before, count / (after - before));
5853     }
5854   else
5855     {
5856       int ret;
5857
5858       /* Wait for a reply... */
5859       W (ret);
5860       return ret;
5861     }
5862   /* Return the good/bad news */
5863   return (vam->retval);
5864 }
5865
5866 static int
5867 api_l2_flags (vat_main_t * vam)
5868 {
5869   unformat_input_t *i = vam->input;
5870   vl_api_l2_flags_t *mp;
5871   u32 sw_if_index;
5872   u32 feature_bitmap = 0;
5873   u8 sw_if_index_set = 0;
5874   int ret;
5875
5876   /* Parse args required to build the message */
5877   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5878     {
5879       if (unformat (i, "sw_if_index %d", &sw_if_index))
5880         sw_if_index_set = 1;
5881       else if (unformat (i, "sw_if"))
5882         {
5883           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5884             {
5885               if (unformat
5886                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5887                 sw_if_index_set = 1;
5888             }
5889           else
5890             break;
5891         }
5892       else if (unformat (i, "learn"))
5893         feature_bitmap |= L2INPUT_FEAT_LEARN;
5894       else if (unformat (i, "forward"))
5895         feature_bitmap |= L2INPUT_FEAT_FWD;
5896       else if (unformat (i, "flood"))
5897         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5898       else if (unformat (i, "uu-flood"))
5899         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5900       else
5901         break;
5902     }
5903
5904   if (sw_if_index_set == 0)
5905     {
5906       errmsg ("missing interface name or sw_if_index");
5907       return -99;
5908     }
5909
5910   M (L2_FLAGS, mp);
5911
5912   mp->sw_if_index = ntohl (sw_if_index);
5913   mp->feature_bitmap = ntohl (feature_bitmap);
5914
5915   S (mp);
5916   W (ret);
5917   return ret;
5918 }
5919
5920 static int
5921 api_bridge_flags (vat_main_t * vam)
5922 {
5923   unformat_input_t *i = vam->input;
5924   vl_api_bridge_flags_t *mp;
5925   u32 bd_id;
5926   u8 bd_id_set = 0;
5927   u8 is_set = 1;
5928   u32 flags = 0;
5929   int ret;
5930
5931   /* Parse args required to build the message */
5932   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5933     {
5934       if (unformat (i, "bd_id %d", &bd_id))
5935         bd_id_set = 1;
5936       else if (unformat (i, "learn"))
5937         flags |= L2_LEARN;
5938       else if (unformat (i, "forward"))
5939         flags |= L2_FWD;
5940       else if (unformat (i, "flood"))
5941         flags |= L2_FLOOD;
5942       else if (unformat (i, "uu-flood"))
5943         flags |= L2_UU_FLOOD;
5944       else if (unformat (i, "arp-term"))
5945         flags |= L2_ARP_TERM;
5946       else if (unformat (i, "off"))
5947         is_set = 0;
5948       else if (unformat (i, "disable"))
5949         is_set = 0;
5950       else
5951         break;
5952     }
5953
5954   if (bd_id_set == 0)
5955     {
5956       errmsg ("missing bridge domain");
5957       return -99;
5958     }
5959
5960   M (BRIDGE_FLAGS, mp);
5961
5962   mp->bd_id = ntohl (bd_id);
5963   mp->feature_bitmap = ntohl (flags);
5964   mp->is_set = is_set;
5965
5966   S (mp);
5967   W (ret);
5968   return ret;
5969 }
5970
5971 static int
5972 api_bd_ip_mac_add_del (vat_main_t * vam)
5973 {
5974   unformat_input_t *i = vam->input;
5975   vl_api_bd_ip_mac_add_del_t *mp;
5976   u32 bd_id;
5977   u8 is_ipv6 = 0;
5978   u8 is_add = 1;
5979   u8 bd_id_set = 0;
5980   u8 ip_set = 0;
5981   u8 mac_set = 0;
5982   ip4_address_t v4addr;
5983   ip6_address_t v6addr;
5984   u8 macaddr[6];
5985   int ret;
5986
5987
5988   /* Parse args required to build the message */
5989   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5990     {
5991       if (unformat (i, "bd_id %d", &bd_id))
5992         {
5993           bd_id_set++;
5994         }
5995       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5996         {
5997           ip_set++;
5998         }
5999       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
6000         {
6001           ip_set++;
6002           is_ipv6++;
6003         }
6004       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
6005         {
6006           mac_set++;
6007         }
6008       else if (unformat (i, "del"))
6009         is_add = 0;
6010       else
6011         break;
6012     }
6013
6014   if (bd_id_set == 0)
6015     {
6016       errmsg ("missing bridge domain");
6017       return -99;
6018     }
6019   else if (ip_set == 0)
6020     {
6021       errmsg ("missing IP address");
6022       return -99;
6023     }
6024   else if (mac_set == 0)
6025     {
6026       errmsg ("missing MAC address");
6027       return -99;
6028     }
6029
6030   M (BD_IP_MAC_ADD_DEL, mp);
6031
6032   mp->bd_id = ntohl (bd_id);
6033   mp->is_ipv6 = is_ipv6;
6034   mp->is_add = is_add;
6035   if (is_ipv6)
6036     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
6037   else
6038     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
6039   clib_memcpy (mp->mac_address, macaddr, 6);
6040   S (mp);
6041   W (ret);
6042   return ret;
6043 }
6044
6045 static int
6046 api_tap_connect (vat_main_t * vam)
6047 {
6048   unformat_input_t *i = vam->input;
6049   vl_api_tap_connect_t *mp;
6050   u8 mac_address[6];
6051   u8 random_mac = 1;
6052   u8 name_set = 0;
6053   u8 *tap_name;
6054   u8 *tag = 0;
6055   ip4_address_t ip4_address;
6056   u32 ip4_mask_width;
6057   int ip4_address_set = 0;
6058   ip6_address_t ip6_address;
6059   u32 ip6_mask_width;
6060   int ip6_address_set = 0;
6061   int ret;
6062
6063   memset (mac_address, 0, sizeof (mac_address));
6064
6065   /* Parse args required to build the message */
6066   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6067     {
6068       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6069         {
6070           random_mac = 0;
6071         }
6072       else if (unformat (i, "random-mac"))
6073         random_mac = 1;
6074       else if (unformat (i, "tapname %s", &tap_name))
6075         name_set = 1;
6076       else if (unformat (i, "tag %s", &tag))
6077         ;
6078       else if (unformat (i, "address %U/%d",
6079                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
6080         ip4_address_set = 1;
6081       else if (unformat (i, "address %U/%d",
6082                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
6083         ip6_address_set = 1;
6084       else
6085         break;
6086     }
6087
6088   if (name_set == 0)
6089     {
6090       errmsg ("missing tap name");
6091       return -99;
6092     }
6093   if (vec_len (tap_name) > 63)
6094     {
6095       errmsg ("tap name too long");
6096       return -99;
6097     }
6098   vec_add1 (tap_name, 0);
6099
6100   if (vec_len (tag) > 63)
6101     {
6102       errmsg ("tag too long");
6103       return -99;
6104     }
6105
6106   /* Construct the API message */
6107   M (TAP_CONNECT, mp);
6108
6109   mp->use_random_mac = random_mac;
6110   clib_memcpy (mp->mac_address, mac_address, 6);
6111   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6112   if (tag)
6113     clib_memcpy (mp->tag, tag, vec_len (tag));
6114
6115   if (ip4_address_set)
6116     {
6117       mp->ip4_address_set = 1;
6118       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6119       mp->ip4_mask_width = ip4_mask_width;
6120     }
6121   if (ip6_address_set)
6122     {
6123       mp->ip6_address_set = 1;
6124       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6125       mp->ip6_mask_width = ip6_mask_width;
6126     }
6127
6128   vec_free (tap_name);
6129   vec_free (tag);
6130
6131   /* send it... */
6132   S (mp);
6133
6134   /* Wait for a reply... */
6135   W (ret);
6136   return ret;
6137 }
6138
6139 static int
6140 api_tap_modify (vat_main_t * vam)
6141 {
6142   unformat_input_t *i = vam->input;
6143   vl_api_tap_modify_t *mp;
6144   u8 mac_address[6];
6145   u8 random_mac = 1;
6146   u8 name_set = 0;
6147   u8 *tap_name;
6148   u32 sw_if_index = ~0;
6149   u8 sw_if_index_set = 0;
6150   int ret;
6151
6152   memset (mac_address, 0, sizeof (mac_address));
6153
6154   /* Parse args required to build the message */
6155   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6156     {
6157       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6158         sw_if_index_set = 1;
6159       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6160         sw_if_index_set = 1;
6161       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6162         {
6163           random_mac = 0;
6164         }
6165       else if (unformat (i, "random-mac"))
6166         random_mac = 1;
6167       else if (unformat (i, "tapname %s", &tap_name))
6168         name_set = 1;
6169       else
6170         break;
6171     }
6172
6173   if (sw_if_index_set == 0)
6174     {
6175       errmsg ("missing vpp interface name");
6176       return -99;
6177     }
6178   if (name_set == 0)
6179     {
6180       errmsg ("missing tap name");
6181       return -99;
6182     }
6183   if (vec_len (tap_name) > 63)
6184     {
6185       errmsg ("tap name too long");
6186     }
6187   vec_add1 (tap_name, 0);
6188
6189   /* Construct the API message */
6190   M (TAP_MODIFY, mp);
6191
6192   mp->use_random_mac = random_mac;
6193   mp->sw_if_index = ntohl (sw_if_index);
6194   clib_memcpy (mp->mac_address, mac_address, 6);
6195   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6196   vec_free (tap_name);
6197
6198   /* send it... */
6199   S (mp);
6200
6201   /* Wait for a reply... */
6202   W (ret);
6203   return ret;
6204 }
6205
6206 static int
6207 api_tap_delete (vat_main_t * vam)
6208 {
6209   unformat_input_t *i = vam->input;
6210   vl_api_tap_delete_t *mp;
6211   u32 sw_if_index = ~0;
6212   u8 sw_if_index_set = 0;
6213   int ret;
6214
6215   /* Parse args required to build the message */
6216   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6217     {
6218       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6219         sw_if_index_set = 1;
6220       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6221         sw_if_index_set = 1;
6222       else
6223         break;
6224     }
6225
6226   if (sw_if_index_set == 0)
6227     {
6228       errmsg ("missing vpp interface name");
6229       return -99;
6230     }
6231
6232   /* Construct the API message */
6233   M (TAP_DELETE, mp);
6234
6235   mp->sw_if_index = ntohl (sw_if_index);
6236
6237   /* send it... */
6238   S (mp);
6239
6240   /* Wait for a reply... */
6241   W (ret);
6242   return ret;
6243 }
6244
6245 static int
6246 api_ip_add_del_route (vat_main_t * vam)
6247 {
6248   unformat_input_t *i = vam->input;
6249   vl_api_ip_add_del_route_t *mp;
6250   u32 sw_if_index = ~0, vrf_id = 0;
6251   u8 is_ipv6 = 0;
6252   u8 is_local = 0, is_drop = 0;
6253   u8 is_unreach = 0, is_prohibit = 0;
6254   u8 create_vrf_if_needed = 0;
6255   u8 is_add = 1;
6256   u32 next_hop_weight = 1;
6257   u8 not_last = 0;
6258   u8 is_multipath = 0;
6259   u8 address_set = 0;
6260   u8 address_length_set = 0;
6261   u32 next_hop_table_id = 0;
6262   u32 resolve_attempts = 0;
6263   u32 dst_address_length = 0;
6264   u8 next_hop_set = 0;
6265   ip4_address_t v4_dst_address, v4_next_hop_address;
6266   ip6_address_t v6_dst_address, v6_next_hop_address;
6267   int count = 1;
6268   int j;
6269   f64 before = 0;
6270   u32 random_add_del = 0;
6271   u32 *random_vector = 0;
6272   uword *random_hash;
6273   u32 random_seed = 0xdeaddabe;
6274   u32 classify_table_index = ~0;
6275   u8 is_classify = 0;
6276   u8 resolve_host = 0, resolve_attached = 0;
6277   mpls_label_t *next_hop_out_label_stack = NULL;
6278   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6279   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6280
6281   /* Parse args required to build the message */
6282   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6283     {
6284       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6285         ;
6286       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6287         ;
6288       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6289         {
6290           address_set = 1;
6291           is_ipv6 = 0;
6292         }
6293       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6294         {
6295           address_set = 1;
6296           is_ipv6 = 1;
6297         }
6298       else if (unformat (i, "/%d", &dst_address_length))
6299         {
6300           address_length_set = 1;
6301         }
6302
6303       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6304                                          &v4_next_hop_address))
6305         {
6306           next_hop_set = 1;
6307         }
6308       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6309                                          &v6_next_hop_address))
6310         {
6311           next_hop_set = 1;
6312         }
6313       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6314         ;
6315       else if (unformat (i, "weight %d", &next_hop_weight))
6316         ;
6317       else if (unformat (i, "drop"))
6318         {
6319           is_drop = 1;
6320         }
6321       else if (unformat (i, "null-send-unreach"))
6322         {
6323           is_unreach = 1;
6324         }
6325       else if (unformat (i, "null-send-prohibit"))
6326         {
6327           is_prohibit = 1;
6328         }
6329       else if (unformat (i, "local"))
6330         {
6331           is_local = 1;
6332         }
6333       else if (unformat (i, "classify %d", &classify_table_index))
6334         {
6335           is_classify = 1;
6336         }
6337       else if (unformat (i, "del"))
6338         is_add = 0;
6339       else if (unformat (i, "add"))
6340         is_add = 1;
6341       else if (unformat (i, "not-last"))
6342         not_last = 1;
6343       else if (unformat (i, "resolve-via-host"))
6344         resolve_host = 1;
6345       else if (unformat (i, "resolve-via-attached"))
6346         resolve_attached = 1;
6347       else if (unformat (i, "multipath"))
6348         is_multipath = 1;
6349       else if (unformat (i, "vrf %d", &vrf_id))
6350         ;
6351       else if (unformat (i, "create-vrf"))
6352         create_vrf_if_needed = 1;
6353       else if (unformat (i, "count %d", &count))
6354         ;
6355       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6356         ;
6357       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6358         ;
6359       else if (unformat (i, "out-label %d", &next_hop_out_label))
6360         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6361       else if (unformat (i, "via-label %d", &next_hop_via_label))
6362         ;
6363       else if (unformat (i, "random"))
6364         random_add_del = 1;
6365       else if (unformat (i, "seed %d", &random_seed))
6366         ;
6367       else
6368         {
6369           clib_warning ("parse error '%U'", format_unformat_error, i);
6370           return -99;
6371         }
6372     }
6373
6374   if (!next_hop_set && !is_drop && !is_local &&
6375       !is_classify && !is_unreach && !is_prohibit &&
6376       MPLS_LABEL_INVALID == next_hop_via_label)
6377     {
6378       errmsg
6379         ("next hop / local / drop / unreach / prohibit / classify not set");
6380       return -99;
6381     }
6382
6383   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6384     {
6385       errmsg ("next hop and next-hop via label set");
6386       return -99;
6387     }
6388   if (address_set == 0)
6389     {
6390       errmsg ("missing addresses");
6391       return -99;
6392     }
6393
6394   if (address_length_set == 0)
6395     {
6396       errmsg ("missing address length");
6397       return -99;
6398     }
6399
6400   /* Generate a pile of unique, random routes */
6401   if (random_add_del)
6402     {
6403       u32 this_random_address;
6404       random_hash = hash_create (count, sizeof (uword));
6405
6406       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6407       for (j = 0; j <= count; j++)
6408         {
6409           do
6410             {
6411               this_random_address = random_u32 (&random_seed);
6412               this_random_address =
6413                 clib_host_to_net_u32 (this_random_address);
6414             }
6415           while (hash_get (random_hash, this_random_address));
6416           vec_add1 (random_vector, this_random_address);
6417           hash_set (random_hash, this_random_address, 1);
6418         }
6419       hash_free (random_hash);
6420       v4_dst_address.as_u32 = random_vector[0];
6421     }
6422
6423   if (count > 1)
6424     {
6425       /* Turn on async mode */
6426       vam->async_mode = 1;
6427       vam->async_errors = 0;
6428       before = vat_time_now (vam);
6429     }
6430
6431   for (j = 0; j < count; j++)
6432     {
6433       /* Construct the API message */
6434       M2 (IP_ADD_DEL_ROUTE, mp,
6435           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6436
6437       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6438       mp->table_id = ntohl (vrf_id);
6439       mp->create_vrf_if_needed = create_vrf_if_needed;
6440
6441       mp->is_add = is_add;
6442       mp->is_drop = is_drop;
6443       mp->is_unreach = is_unreach;
6444       mp->is_prohibit = is_prohibit;
6445       mp->is_ipv6 = is_ipv6;
6446       mp->is_local = is_local;
6447       mp->is_classify = is_classify;
6448       mp->is_multipath = is_multipath;
6449       mp->is_resolve_host = resolve_host;
6450       mp->is_resolve_attached = resolve_attached;
6451       mp->not_last = not_last;
6452       mp->next_hop_weight = next_hop_weight;
6453       mp->dst_address_length = dst_address_length;
6454       mp->next_hop_table_id = ntohl (next_hop_table_id);
6455       mp->classify_table_index = ntohl (classify_table_index);
6456       mp->next_hop_via_label = ntohl (next_hop_via_label);
6457       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6458       if (0 != mp->next_hop_n_out_labels)
6459         {
6460           memcpy (mp->next_hop_out_label_stack,
6461                   next_hop_out_label_stack,
6462                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6463           vec_free (next_hop_out_label_stack);
6464         }
6465
6466       if (is_ipv6)
6467         {
6468           clib_memcpy (mp->dst_address, &v6_dst_address,
6469                        sizeof (v6_dst_address));
6470           if (next_hop_set)
6471             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6472                          sizeof (v6_next_hop_address));
6473           increment_v6_address (&v6_dst_address);
6474         }
6475       else
6476         {
6477           clib_memcpy (mp->dst_address, &v4_dst_address,
6478                        sizeof (v4_dst_address));
6479           if (next_hop_set)
6480             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6481                          sizeof (v4_next_hop_address));
6482           if (random_add_del)
6483             v4_dst_address.as_u32 = random_vector[j + 1];
6484           else
6485             increment_v4_address (&v4_dst_address);
6486         }
6487       /* send it... */
6488       S (mp);
6489       /* If we receive SIGTERM, stop now... */
6490       if (vam->do_exit)
6491         break;
6492     }
6493
6494   /* When testing multiple add/del ops, use a control-ping to sync */
6495   if (count > 1)
6496     {
6497       vl_api_control_ping_t *mp_ping;
6498       f64 after;
6499       f64 timeout;
6500
6501       /* Shut off async mode */
6502       vam->async_mode = 0;
6503
6504       M (CONTROL_PING, mp_ping);
6505       S (mp_ping);
6506
6507       timeout = vat_time_now (vam) + 1.0;
6508       while (vat_time_now (vam) < timeout)
6509         if (vam->result_ready == 1)
6510           goto out;
6511       vam->retval = -99;
6512
6513     out:
6514       if (vam->retval == -99)
6515         errmsg ("timeout");
6516
6517       if (vam->async_errors > 0)
6518         {
6519           errmsg ("%d asynchronous errors", vam->async_errors);
6520           vam->retval = -98;
6521         }
6522       vam->async_errors = 0;
6523       after = vat_time_now (vam);
6524
6525       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6526       if (j > 0)
6527         count = j;
6528
6529       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6530              count, after - before, count / (after - before));
6531     }
6532   else
6533     {
6534       int ret;
6535
6536       /* Wait for a reply... */
6537       W (ret);
6538       return ret;
6539     }
6540
6541   /* Return the good/bad news */
6542   return (vam->retval);
6543 }
6544
6545 static int
6546 api_ip_mroute_add_del (vat_main_t * vam)
6547 {
6548   unformat_input_t *i = vam->input;
6549   vl_api_ip_mroute_add_del_t *mp;
6550   u32 sw_if_index = ~0, vrf_id = 0;
6551   u8 is_ipv6 = 0;
6552   u8 is_local = 0;
6553   u8 create_vrf_if_needed = 0;
6554   u8 is_add = 1;
6555   u8 address_set = 0;
6556   u32 grp_address_length = 0;
6557   ip4_address_t v4_grp_address, v4_src_address;
6558   ip6_address_t v6_grp_address, v6_src_address;
6559   mfib_itf_flags_t iflags = 0;
6560   mfib_entry_flags_t eflags = 0;
6561   int ret;
6562
6563   /* Parse args required to build the message */
6564   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6565     {
6566       if (unformat (i, "sw_if_index %d", &sw_if_index))
6567         ;
6568       else if (unformat (i, "%U %U",
6569                          unformat_ip4_address, &v4_src_address,
6570                          unformat_ip4_address, &v4_grp_address))
6571         {
6572           grp_address_length = 64;
6573           address_set = 1;
6574           is_ipv6 = 0;
6575         }
6576       else if (unformat (i, "%U %U",
6577                          unformat_ip6_address, &v6_src_address,
6578                          unformat_ip6_address, &v6_grp_address))
6579         {
6580           grp_address_length = 256;
6581           address_set = 1;
6582           is_ipv6 = 1;
6583         }
6584       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
6585         {
6586           memset (&v4_src_address, 0, sizeof (v4_src_address));
6587           grp_address_length = 32;
6588           address_set = 1;
6589           is_ipv6 = 0;
6590         }
6591       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
6592         {
6593           memset (&v6_src_address, 0, sizeof (v6_src_address));
6594           grp_address_length = 128;
6595           address_set = 1;
6596           is_ipv6 = 1;
6597         }
6598       else if (unformat (i, "/%d", &grp_address_length))
6599         ;
6600       else if (unformat (i, "local"))
6601         {
6602           is_local = 1;
6603         }
6604       else if (unformat (i, "del"))
6605         is_add = 0;
6606       else if (unformat (i, "add"))
6607         is_add = 1;
6608       else if (unformat (i, "vrf %d", &vrf_id))
6609         ;
6610       else if (unformat (i, "create-vrf"))
6611         create_vrf_if_needed = 1;
6612       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
6613         ;
6614       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6615         ;
6616       else
6617         {
6618           clib_warning ("parse error '%U'", format_unformat_error, i);
6619           return -99;
6620         }
6621     }
6622
6623   if (address_set == 0)
6624     {
6625       errmsg ("missing addresses\n");
6626       return -99;
6627     }
6628
6629   /* Construct the API message */
6630   M (IP_MROUTE_ADD_DEL, mp);
6631
6632   mp->next_hop_sw_if_index = ntohl (sw_if_index);
6633   mp->table_id = ntohl (vrf_id);
6634   mp->create_vrf_if_needed = create_vrf_if_needed;
6635
6636   mp->is_add = is_add;
6637   mp->is_ipv6 = is_ipv6;
6638   mp->is_local = is_local;
6639   mp->itf_flags = ntohl (iflags);
6640   mp->entry_flags = ntohl (eflags);
6641   mp->grp_address_length = grp_address_length;
6642   mp->grp_address_length = ntohs (mp->grp_address_length);
6643
6644   if (is_ipv6)
6645     {
6646       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
6647       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
6648     }
6649   else
6650     {
6651       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
6652       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
6653
6654     }
6655
6656   /* send it... */
6657   S (mp);
6658   /* Wait for a reply... */
6659   W (ret);
6660   return ret;
6661 }
6662
6663 static int
6664 api_mpls_route_add_del (vat_main_t * vam)
6665 {
6666   unformat_input_t *i = vam->input;
6667   vl_api_mpls_route_add_del_t *mp;
6668   u32 sw_if_index = ~0, table_id = 0;
6669   u8 create_table_if_needed = 0;
6670   u8 is_add = 1;
6671   u32 next_hop_weight = 1;
6672   u8 is_multipath = 0;
6673   u32 next_hop_table_id = 0;
6674   u8 next_hop_set = 0;
6675   ip4_address_t v4_next_hop_address = {
6676     .as_u32 = 0,
6677   };
6678   ip6_address_t v6_next_hop_address = { {0} };
6679   int count = 1;
6680   int j;
6681   f64 before = 0;
6682   u32 classify_table_index = ~0;
6683   u8 is_classify = 0;
6684   u8 resolve_host = 0, resolve_attached = 0;
6685   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6686   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6687   mpls_label_t *next_hop_out_label_stack = NULL;
6688   mpls_label_t local_label = MPLS_LABEL_INVALID;
6689   u8 is_eos = 0;
6690   u8 next_hop_proto_is_ip4 = 1;
6691
6692   /* Parse args required to build the message */
6693   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6694     {
6695       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6696         ;
6697       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6698         ;
6699       else if (unformat (i, "%d", &local_label))
6700         ;
6701       else if (unformat (i, "eos"))
6702         is_eos = 1;
6703       else if (unformat (i, "non-eos"))
6704         is_eos = 0;
6705       else if (unformat (i, "via %U", unformat_ip4_address,
6706                          &v4_next_hop_address))
6707         {
6708           next_hop_set = 1;
6709           next_hop_proto_is_ip4 = 1;
6710         }
6711       else if (unformat (i, "via %U", unformat_ip6_address,
6712                          &v6_next_hop_address))
6713         {
6714           next_hop_set = 1;
6715           next_hop_proto_is_ip4 = 0;
6716         }
6717       else if (unformat (i, "weight %d", &next_hop_weight))
6718         ;
6719       else if (unformat (i, "create-table"))
6720         create_table_if_needed = 1;
6721       else if (unformat (i, "classify %d", &classify_table_index))
6722         {
6723           is_classify = 1;
6724         }
6725       else if (unformat (i, "del"))
6726         is_add = 0;
6727       else if (unformat (i, "add"))
6728         is_add = 1;
6729       else if (unformat (i, "resolve-via-host"))
6730         resolve_host = 1;
6731       else if (unformat (i, "resolve-via-attached"))
6732         resolve_attached = 1;
6733       else if (unformat (i, "multipath"))
6734         is_multipath = 1;
6735       else if (unformat (i, "count %d", &count))
6736         ;
6737       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6738         {
6739           next_hop_set = 1;
6740           next_hop_proto_is_ip4 = 1;
6741         }
6742       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6743         {
6744           next_hop_set = 1;
6745           next_hop_proto_is_ip4 = 0;
6746         }
6747       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6748         ;
6749       else if (unformat (i, "via-label %d", &next_hop_via_label))
6750         ;
6751       else if (unformat (i, "out-label %d", &next_hop_out_label))
6752         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6753       else
6754         {
6755           clib_warning ("parse error '%U'", format_unformat_error, i);
6756           return -99;
6757         }
6758     }
6759
6760   if (!next_hop_set && !is_classify)
6761     {
6762       errmsg ("next hop / classify not set");
6763       return -99;
6764     }
6765
6766   if (MPLS_LABEL_INVALID == local_label)
6767     {
6768       errmsg ("missing label");
6769       return -99;
6770     }
6771
6772   if (count > 1)
6773     {
6774       /* Turn on async mode */
6775       vam->async_mode = 1;
6776       vam->async_errors = 0;
6777       before = vat_time_now (vam);
6778     }
6779
6780   for (j = 0; j < count; j++)
6781     {
6782       /* Construct the API message */
6783       M2 (MPLS_ROUTE_ADD_DEL, mp,
6784           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6785
6786       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6787       mp->mr_table_id = ntohl (table_id);
6788       mp->mr_create_table_if_needed = create_table_if_needed;
6789
6790       mp->mr_is_add = is_add;
6791       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6792       mp->mr_is_classify = is_classify;
6793       mp->mr_is_multipath = is_multipath;
6794       mp->mr_is_resolve_host = resolve_host;
6795       mp->mr_is_resolve_attached = resolve_attached;
6796       mp->mr_next_hop_weight = next_hop_weight;
6797       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6798       mp->mr_classify_table_index = ntohl (classify_table_index);
6799       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
6800       mp->mr_label = ntohl (local_label);
6801       mp->mr_eos = is_eos;
6802
6803       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6804       if (0 != mp->mr_next_hop_n_out_labels)
6805         {
6806           memcpy (mp->mr_next_hop_out_label_stack,
6807                   next_hop_out_label_stack,
6808                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6809           vec_free (next_hop_out_label_stack);
6810         }
6811
6812       if (next_hop_set)
6813         {
6814           if (next_hop_proto_is_ip4)
6815             {
6816               clib_memcpy (mp->mr_next_hop,
6817                            &v4_next_hop_address,
6818                            sizeof (v4_next_hop_address));
6819             }
6820           else
6821             {
6822               clib_memcpy (mp->mr_next_hop,
6823                            &v6_next_hop_address,
6824                            sizeof (v6_next_hop_address));
6825             }
6826         }
6827       local_label++;
6828
6829       /* send it... */
6830       S (mp);
6831       /* If we receive SIGTERM, stop now... */
6832       if (vam->do_exit)
6833         break;
6834     }
6835
6836   /* When testing multiple add/del ops, use a control-ping to sync */
6837   if (count > 1)
6838     {
6839       vl_api_control_ping_t *mp_ping;
6840       f64 after;
6841       f64 timeout;
6842
6843       /* Shut off async mode */
6844       vam->async_mode = 0;
6845
6846       M (CONTROL_PING, mp_ping);
6847       S (mp_ping);
6848
6849       timeout = vat_time_now (vam) + 1.0;
6850       while (vat_time_now (vam) < timeout)
6851         if (vam->result_ready == 1)
6852           goto out;
6853       vam->retval = -99;
6854
6855     out:
6856       if (vam->retval == -99)
6857         errmsg ("timeout");
6858
6859       if (vam->async_errors > 0)
6860         {
6861           errmsg ("%d asynchronous errors", vam->async_errors);
6862           vam->retval = -98;
6863         }
6864       vam->async_errors = 0;
6865       after = vat_time_now (vam);
6866
6867       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6868       if (j > 0)
6869         count = j;
6870
6871       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6872              count, after - before, count / (after - before));
6873     }
6874   else
6875     {
6876       int ret;
6877
6878       /* Wait for a reply... */
6879       W (ret);
6880       return ret;
6881     }
6882
6883   /* Return the good/bad news */
6884   return (vam->retval);
6885 }
6886
6887 static int
6888 api_mpls_ip_bind_unbind (vat_main_t * vam)
6889 {
6890   unformat_input_t *i = vam->input;
6891   vl_api_mpls_ip_bind_unbind_t *mp;
6892   u32 ip_table_id = 0;
6893   u8 create_table_if_needed = 0;
6894   u8 is_bind = 1;
6895   u8 is_ip4 = 1;
6896   ip4_address_t v4_address;
6897   ip6_address_t v6_address;
6898   u32 address_length;
6899   u8 address_set = 0;
6900   mpls_label_t local_label = MPLS_LABEL_INVALID;
6901   int ret;
6902
6903   /* Parse args required to build the message */
6904   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6905     {
6906       if (unformat (i, "%U/%d", unformat_ip4_address,
6907                     &v4_address, &address_length))
6908         {
6909           is_ip4 = 1;
6910           address_set = 1;
6911         }
6912       else if (unformat (i, "%U/%d", unformat_ip6_address,
6913                          &v6_address, &address_length))
6914         {
6915           is_ip4 = 0;
6916           address_set = 1;
6917         }
6918       else if (unformat (i, "%d", &local_label))
6919         ;
6920       else if (unformat (i, "create-table"))
6921         create_table_if_needed = 1;
6922       else if (unformat (i, "table-id %d", &ip_table_id))
6923         ;
6924       else if (unformat (i, "unbind"))
6925         is_bind = 0;
6926       else if (unformat (i, "bind"))
6927         is_bind = 1;
6928       else
6929         {
6930           clib_warning ("parse error '%U'", format_unformat_error, i);
6931           return -99;
6932         }
6933     }
6934
6935   if (!address_set)
6936     {
6937       errmsg ("IP addres not set");
6938       return -99;
6939     }
6940
6941   if (MPLS_LABEL_INVALID == local_label)
6942     {
6943       errmsg ("missing label");
6944       return -99;
6945     }
6946
6947   /* Construct the API message */
6948   M (MPLS_IP_BIND_UNBIND, mp);
6949
6950   mp->mb_create_table_if_needed = create_table_if_needed;
6951   mp->mb_is_bind = is_bind;
6952   mp->mb_is_ip4 = is_ip4;
6953   mp->mb_ip_table_id = ntohl (ip_table_id);
6954   mp->mb_mpls_table_id = 0;
6955   mp->mb_label = ntohl (local_label);
6956   mp->mb_address_length = address_length;
6957
6958   if (is_ip4)
6959     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
6960   else
6961     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
6962
6963   /* send it... */
6964   S (mp);
6965
6966   /* Wait for a reply... */
6967   W (ret);
6968   return ret;
6969 }
6970
6971 static int
6972 api_proxy_arp_add_del (vat_main_t * vam)
6973 {
6974   unformat_input_t *i = vam->input;
6975   vl_api_proxy_arp_add_del_t *mp;
6976   u32 vrf_id = 0;
6977   u8 is_add = 1;
6978   ip4_address_t lo, hi;
6979   u8 range_set = 0;
6980   int ret;
6981
6982   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6983     {
6984       if (unformat (i, "vrf %d", &vrf_id))
6985         ;
6986       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
6987                          unformat_ip4_address, &hi))
6988         range_set = 1;
6989       else if (unformat (i, "del"))
6990         is_add = 0;
6991       else
6992         {
6993           clib_warning ("parse error '%U'", format_unformat_error, i);
6994           return -99;
6995         }
6996     }
6997
6998   if (range_set == 0)
6999     {
7000       errmsg ("address range not set");
7001       return -99;
7002     }
7003
7004   M (PROXY_ARP_ADD_DEL, mp);
7005
7006   mp->vrf_id = ntohl (vrf_id);
7007   mp->is_add = is_add;
7008   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
7009   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
7010
7011   S (mp);
7012   W (ret);
7013   return ret;
7014 }
7015
7016 static int
7017 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
7018 {
7019   unformat_input_t *i = vam->input;
7020   vl_api_proxy_arp_intfc_enable_disable_t *mp;
7021   u32 sw_if_index;
7022   u8 enable = 1;
7023   u8 sw_if_index_set = 0;
7024   int ret;
7025
7026   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7027     {
7028       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7029         sw_if_index_set = 1;
7030       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7031         sw_if_index_set = 1;
7032       else if (unformat (i, "enable"))
7033         enable = 1;
7034       else if (unformat (i, "disable"))
7035         enable = 0;
7036       else
7037         {
7038           clib_warning ("parse error '%U'", format_unformat_error, i);
7039           return -99;
7040         }
7041     }
7042
7043   if (sw_if_index_set == 0)
7044     {
7045       errmsg ("missing interface name or sw_if_index");
7046       return -99;
7047     }
7048
7049   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
7050
7051   mp->sw_if_index = ntohl (sw_if_index);
7052   mp->enable_disable = enable;
7053
7054   S (mp);
7055   W (ret);
7056   return ret;
7057 }
7058
7059 static int
7060 api_mpls_tunnel_add_del (vat_main_t * vam)
7061 {
7062   unformat_input_t *i = vam->input;
7063   vl_api_mpls_tunnel_add_del_t *mp;
7064
7065   u8 is_add = 1;
7066   u8 l2_only = 0;
7067   u32 sw_if_index = ~0;
7068   u32 next_hop_sw_if_index = ~0;
7069   u32 next_hop_proto_is_ip4 = 1;
7070
7071   u32 next_hop_table_id = 0;
7072   ip4_address_t v4_next_hop_address = {
7073     .as_u32 = 0,
7074   };
7075   ip6_address_t v6_next_hop_address = { {0} };
7076   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
7077   int ret;
7078
7079   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7080     {
7081       if (unformat (i, "add"))
7082         is_add = 1;
7083       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7084         is_add = 0;
7085       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7086         ;
7087       else if (unformat (i, "via %U",
7088                          unformat_ip4_address, &v4_next_hop_address))
7089         {
7090           next_hop_proto_is_ip4 = 1;
7091         }
7092       else if (unformat (i, "via %U",
7093                          unformat_ip6_address, &v6_next_hop_address))
7094         {
7095           next_hop_proto_is_ip4 = 0;
7096         }
7097       else if (unformat (i, "l2-only"))
7098         l2_only = 1;
7099       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7100         ;
7101       else if (unformat (i, "out-label %d", &next_hop_out_label))
7102         vec_add1 (labels, ntohl (next_hop_out_label));
7103       else
7104         {
7105           clib_warning ("parse error '%U'", format_unformat_error, i);
7106           return -99;
7107         }
7108     }
7109
7110   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
7111
7112   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
7113   mp->mt_sw_if_index = ntohl (sw_if_index);
7114   mp->mt_is_add = is_add;
7115   mp->mt_l2_only = l2_only;
7116   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
7117   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7118
7119   mp->mt_next_hop_n_out_labels = vec_len (labels);
7120
7121   if (0 != mp->mt_next_hop_n_out_labels)
7122     {
7123       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7124                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7125       vec_free (labels);
7126     }
7127
7128   if (next_hop_proto_is_ip4)
7129     {
7130       clib_memcpy (mp->mt_next_hop,
7131                    &v4_next_hop_address, sizeof (v4_next_hop_address));
7132     }
7133   else
7134     {
7135       clib_memcpy (mp->mt_next_hop,
7136                    &v6_next_hop_address, sizeof (v6_next_hop_address));
7137     }
7138
7139   S (mp);
7140   W (ret);
7141   return ret;
7142 }
7143
7144 static int
7145 api_sw_interface_set_unnumbered (vat_main_t * vam)
7146 {
7147   unformat_input_t *i = vam->input;
7148   vl_api_sw_interface_set_unnumbered_t *mp;
7149   u32 sw_if_index;
7150   u32 unnum_sw_index = ~0;
7151   u8 is_add = 1;
7152   u8 sw_if_index_set = 0;
7153   int ret;
7154
7155   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7156     {
7157       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7158         sw_if_index_set = 1;
7159       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7160         sw_if_index_set = 1;
7161       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7162         ;
7163       else if (unformat (i, "del"))
7164         is_add = 0;
7165       else
7166         {
7167           clib_warning ("parse error '%U'", format_unformat_error, i);
7168           return -99;
7169         }
7170     }
7171
7172   if (sw_if_index_set == 0)
7173     {
7174       errmsg ("missing interface name or sw_if_index");
7175       return -99;
7176     }
7177
7178   M (SW_INTERFACE_SET_UNNUMBERED, mp);
7179
7180   mp->sw_if_index = ntohl (sw_if_index);
7181   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7182   mp->is_add = is_add;
7183
7184   S (mp);
7185   W (ret);
7186   return ret;
7187 }
7188
7189 static int
7190 api_ip_neighbor_add_del (vat_main_t * vam)
7191 {
7192   unformat_input_t *i = vam->input;
7193   vl_api_ip_neighbor_add_del_t *mp;
7194   u32 sw_if_index;
7195   u8 sw_if_index_set = 0;
7196   u8 is_add = 1;
7197   u8 is_static = 0;
7198   u8 is_no_fib_entry = 0;
7199   u8 mac_address[6];
7200   u8 mac_set = 0;
7201   u8 v4_address_set = 0;
7202   u8 v6_address_set = 0;
7203   ip4_address_t v4address;
7204   ip6_address_t v6address;
7205   int ret;
7206
7207   memset (mac_address, 0, sizeof (mac_address));
7208
7209   /* Parse args required to build the message */
7210   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7211     {
7212       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7213         {
7214           mac_set = 1;
7215         }
7216       else if (unformat (i, "del"))
7217         is_add = 0;
7218       else
7219         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7220         sw_if_index_set = 1;
7221       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7222         sw_if_index_set = 1;
7223       else if (unformat (i, "is_static"))
7224         is_static = 1;
7225       else if (unformat (i, "no-fib-entry"))
7226         is_no_fib_entry = 1;
7227       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
7228         v4_address_set = 1;
7229       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
7230         v6_address_set = 1;
7231       else
7232         {
7233           clib_warning ("parse error '%U'", format_unformat_error, i);
7234           return -99;
7235         }
7236     }
7237
7238   if (sw_if_index_set == 0)
7239     {
7240       errmsg ("missing interface name or sw_if_index");
7241       return -99;
7242     }
7243   if (v4_address_set && v6_address_set)
7244     {
7245       errmsg ("both v4 and v6 addresses set");
7246       return -99;
7247     }
7248   if (!v4_address_set && !v6_address_set)
7249     {
7250       errmsg ("no address set");
7251       return -99;
7252     }
7253
7254   /* Construct the API message */
7255   M (IP_NEIGHBOR_ADD_DEL, mp);
7256
7257   mp->sw_if_index = ntohl (sw_if_index);
7258   mp->is_add = is_add;
7259   mp->is_static = is_static;
7260   mp->is_no_adj_fib = is_no_fib_entry;
7261   if (mac_set)
7262     clib_memcpy (mp->mac_address, mac_address, 6);
7263   if (v6_address_set)
7264     {
7265       mp->is_ipv6 = 1;
7266       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
7267     }
7268   else
7269     {
7270       /* mp->is_ipv6 = 0; via memset in M macro above */
7271       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
7272     }
7273
7274   /* send it... */
7275   S (mp);
7276
7277   /* Wait for a reply, return good/bad news  */
7278   W (ret);
7279   return ret;
7280 }
7281
7282 static int
7283 api_reset_vrf (vat_main_t * vam)
7284 {
7285   unformat_input_t *i = vam->input;
7286   vl_api_reset_vrf_t *mp;
7287   u32 vrf_id = 0;
7288   u8 is_ipv6 = 0;
7289   u8 vrf_id_set = 0;
7290   int ret;
7291
7292   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7293     {
7294       if (unformat (i, "vrf %d", &vrf_id))
7295         vrf_id_set = 1;
7296       else if (unformat (i, "ipv6"))
7297         is_ipv6 = 1;
7298       else
7299         {
7300           clib_warning ("parse error '%U'", format_unformat_error, i);
7301           return -99;
7302         }
7303     }
7304
7305   if (vrf_id_set == 0)
7306     {
7307       errmsg ("missing vrf id");
7308       return -99;
7309     }
7310
7311   M (RESET_VRF, mp);
7312
7313   mp->vrf_id = ntohl (vrf_id);
7314   mp->is_ipv6 = is_ipv6;
7315
7316   S (mp);
7317   W (ret);
7318   return ret;
7319 }
7320
7321 static int
7322 api_create_vlan_subif (vat_main_t * vam)
7323 {
7324   unformat_input_t *i = vam->input;
7325   vl_api_create_vlan_subif_t *mp;
7326   u32 sw_if_index;
7327   u8 sw_if_index_set = 0;
7328   u32 vlan_id;
7329   u8 vlan_id_set = 0;
7330   int ret;
7331
7332   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7333     {
7334       if (unformat (i, "sw_if_index %d", &sw_if_index))
7335         sw_if_index_set = 1;
7336       else
7337         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7338         sw_if_index_set = 1;
7339       else if (unformat (i, "vlan %d", &vlan_id))
7340         vlan_id_set = 1;
7341       else
7342         {
7343           clib_warning ("parse error '%U'", format_unformat_error, i);
7344           return -99;
7345         }
7346     }
7347
7348   if (sw_if_index_set == 0)
7349     {
7350       errmsg ("missing interface name or sw_if_index");
7351       return -99;
7352     }
7353
7354   if (vlan_id_set == 0)
7355     {
7356       errmsg ("missing vlan_id");
7357       return -99;
7358     }
7359   M (CREATE_VLAN_SUBIF, mp);
7360
7361   mp->sw_if_index = ntohl (sw_if_index);
7362   mp->vlan_id = ntohl (vlan_id);
7363
7364   S (mp);
7365   W (ret);
7366   return ret;
7367 }
7368
7369 #define foreach_create_subif_bit                \
7370 _(no_tags)                                      \
7371 _(one_tag)                                      \
7372 _(two_tags)                                     \
7373 _(dot1ad)                                       \
7374 _(exact_match)                                  \
7375 _(default_sub)                                  \
7376 _(outer_vlan_id_any)                            \
7377 _(inner_vlan_id_any)
7378
7379 static int
7380 api_create_subif (vat_main_t * vam)
7381 {
7382   unformat_input_t *i = vam->input;
7383   vl_api_create_subif_t *mp;
7384   u32 sw_if_index;
7385   u8 sw_if_index_set = 0;
7386   u32 sub_id;
7387   u8 sub_id_set = 0;
7388   u32 no_tags = 0;
7389   u32 one_tag = 0;
7390   u32 two_tags = 0;
7391   u32 dot1ad = 0;
7392   u32 exact_match = 0;
7393   u32 default_sub = 0;
7394   u32 outer_vlan_id_any = 0;
7395   u32 inner_vlan_id_any = 0;
7396   u32 tmp;
7397   u16 outer_vlan_id = 0;
7398   u16 inner_vlan_id = 0;
7399   int ret;
7400
7401   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7402     {
7403       if (unformat (i, "sw_if_index %d", &sw_if_index))
7404         sw_if_index_set = 1;
7405       else
7406         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7407         sw_if_index_set = 1;
7408       else if (unformat (i, "sub_id %d", &sub_id))
7409         sub_id_set = 1;
7410       else if (unformat (i, "outer_vlan_id %d", &tmp))
7411         outer_vlan_id = tmp;
7412       else if (unformat (i, "inner_vlan_id %d", &tmp))
7413         inner_vlan_id = tmp;
7414
7415 #define _(a) else if (unformat (i, #a)) a = 1 ;
7416       foreach_create_subif_bit
7417 #undef _
7418         else
7419         {
7420           clib_warning ("parse error '%U'", format_unformat_error, i);
7421           return -99;
7422         }
7423     }
7424
7425   if (sw_if_index_set == 0)
7426     {
7427       errmsg ("missing interface name or sw_if_index");
7428       return -99;
7429     }
7430
7431   if (sub_id_set == 0)
7432     {
7433       errmsg ("missing sub_id");
7434       return -99;
7435     }
7436   M (CREATE_SUBIF, mp);
7437
7438   mp->sw_if_index = ntohl (sw_if_index);
7439   mp->sub_id = ntohl (sub_id);
7440
7441 #define _(a) mp->a = a;
7442   foreach_create_subif_bit;
7443 #undef _
7444
7445   mp->outer_vlan_id = ntohs (outer_vlan_id);
7446   mp->inner_vlan_id = ntohs (inner_vlan_id);
7447
7448   S (mp);
7449   W (ret);
7450   return ret;
7451 }
7452
7453 static int
7454 api_oam_add_del (vat_main_t * vam)
7455 {
7456   unformat_input_t *i = vam->input;
7457   vl_api_oam_add_del_t *mp;
7458   u32 vrf_id = 0;
7459   u8 is_add = 1;
7460   ip4_address_t src, dst;
7461   u8 src_set = 0;
7462   u8 dst_set = 0;
7463   int ret;
7464
7465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7466     {
7467       if (unformat (i, "vrf %d", &vrf_id))
7468         ;
7469       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7470         src_set = 1;
7471       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7472         dst_set = 1;
7473       else if (unformat (i, "del"))
7474         is_add = 0;
7475       else
7476         {
7477           clib_warning ("parse error '%U'", format_unformat_error, i);
7478           return -99;
7479         }
7480     }
7481
7482   if (src_set == 0)
7483     {
7484       errmsg ("missing src addr");
7485       return -99;
7486     }
7487
7488   if (dst_set == 0)
7489     {
7490       errmsg ("missing dst addr");
7491       return -99;
7492     }
7493
7494   M (OAM_ADD_DEL, mp);
7495
7496   mp->vrf_id = ntohl (vrf_id);
7497   mp->is_add = is_add;
7498   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7499   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7500
7501   S (mp);
7502   W (ret);
7503   return ret;
7504 }
7505
7506 static int
7507 api_reset_fib (vat_main_t * vam)
7508 {
7509   unformat_input_t *i = vam->input;
7510   vl_api_reset_fib_t *mp;
7511   u32 vrf_id = 0;
7512   u8 is_ipv6 = 0;
7513   u8 vrf_id_set = 0;
7514
7515   int ret;
7516   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7517     {
7518       if (unformat (i, "vrf %d", &vrf_id))
7519         vrf_id_set = 1;
7520       else if (unformat (i, "ipv6"))
7521         is_ipv6 = 1;
7522       else
7523         {
7524           clib_warning ("parse error '%U'", format_unformat_error, i);
7525           return -99;
7526         }
7527     }
7528
7529   if (vrf_id_set == 0)
7530     {
7531       errmsg ("missing vrf id");
7532       return -99;
7533     }
7534
7535   M (RESET_FIB, mp);
7536
7537   mp->vrf_id = ntohl (vrf_id);
7538   mp->is_ipv6 = is_ipv6;
7539
7540   S (mp);
7541   W (ret);
7542   return ret;
7543 }
7544
7545 static int
7546 api_dhcp_proxy_config (vat_main_t * vam)
7547 {
7548   unformat_input_t *i = vam->input;
7549   vl_api_dhcp_proxy_config_t *mp;
7550   u32 rx_vrf_id = 0;
7551   u32 server_vrf_id = 0;
7552   u8 is_add = 1;
7553   u8 v4_address_set = 0;
7554   u8 v6_address_set = 0;
7555   ip4_address_t v4address;
7556   ip6_address_t v6address;
7557   u8 v4_src_address_set = 0;
7558   u8 v6_src_address_set = 0;
7559   ip4_address_t v4srcaddress;
7560   ip6_address_t v6srcaddress;
7561   int ret;
7562
7563   /* Parse args required to build the message */
7564   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7565     {
7566       if (unformat (i, "del"))
7567         is_add = 0;
7568       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7569         ;
7570       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7571         ;
7572       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7573         v4_address_set = 1;
7574       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7575         v6_address_set = 1;
7576       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7577         v4_src_address_set = 1;
7578       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7579         v6_src_address_set = 1;
7580       else
7581         break;
7582     }
7583
7584   if (v4_address_set && v6_address_set)
7585     {
7586       errmsg ("both v4 and v6 server addresses set");
7587       return -99;
7588     }
7589   if (!v4_address_set && !v6_address_set)
7590     {
7591       errmsg ("no server addresses set");
7592       return -99;
7593     }
7594
7595   if (v4_src_address_set && v6_src_address_set)
7596     {
7597       errmsg ("both v4 and v6  src addresses set");
7598       return -99;
7599     }
7600   if (!v4_src_address_set && !v6_src_address_set)
7601     {
7602       errmsg ("no src addresses set");
7603       return -99;
7604     }
7605
7606   if (!(v4_src_address_set && v4_address_set) &&
7607       !(v6_src_address_set && v6_address_set))
7608     {
7609       errmsg ("no matching server and src addresses set");
7610       return -99;
7611     }
7612
7613   /* Construct the API message */
7614   M (DHCP_PROXY_CONFIG, mp);
7615
7616   mp->is_add = is_add;
7617   mp->rx_vrf_id = ntohl (rx_vrf_id);
7618   mp->server_vrf_id = ntohl (server_vrf_id);
7619   if (v6_address_set)
7620     {
7621       mp->is_ipv6 = 1;
7622       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7623       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7624     }
7625   else
7626     {
7627       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7628       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7629     }
7630
7631   /* send it... */
7632   S (mp);
7633
7634   /* Wait for a reply, return good/bad news  */
7635   W (ret);
7636   return ret;
7637 }
7638
7639 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
7640 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
7641
7642 static void
7643 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
7644 {
7645   vat_main_t *vam = &vat_main;
7646   u32 i, count = mp->count;
7647   vl_api_dhcp_server_t *s;
7648
7649   if (mp->is_ipv6)
7650     print (vam->ofp,
7651            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7652            ntohl (mp->rx_vrf_id),
7653            format_ip6_address, mp->dhcp_src_address,
7654            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7655   else
7656     print (vam->ofp,
7657            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7658            ntohl (mp->rx_vrf_id),
7659            format_ip4_address, mp->dhcp_src_address,
7660            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7661
7662   for (i = 0; i < count; i++)
7663     {
7664       s = &mp->servers[i];
7665
7666       if (mp->is_ipv6)
7667         print (vam->ofp,
7668                " Server Table-ID %d, Server Address %U",
7669                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
7670       else
7671         print (vam->ofp,
7672                " Server Table-ID %d, Server Address %U",
7673                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
7674     }
7675 }
7676
7677 static void vl_api_dhcp_proxy_details_t_handler_json
7678   (vl_api_dhcp_proxy_details_t * mp)
7679 {
7680   vat_main_t *vam = &vat_main;
7681   vat_json_node_t *node = NULL;
7682   u32 i, count = mp->count;
7683   struct in_addr ip4;
7684   struct in6_addr ip6;
7685   vl_api_dhcp_server_t *s;
7686
7687   if (VAT_JSON_ARRAY != vam->json_tree.type)
7688     {
7689       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7690       vat_json_init_array (&vam->json_tree);
7691     }
7692   node = vat_json_array_add (&vam->json_tree);
7693
7694   vat_json_init_object (node);
7695   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
7696   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
7697   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
7698
7699   if (mp->is_ipv6)
7700     {
7701       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
7702       vat_json_object_add_ip6 (node, "src_address", ip6);
7703     }
7704   else
7705     {
7706       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
7707       vat_json_object_add_ip4 (node, "src_address", ip4);
7708     }
7709
7710   for (i = 0; i < count; i++)
7711     {
7712       s = &mp->servers[i];
7713
7714       vat_json_object_add_uint (node, "server-table-id",
7715                                 ntohl (s->server_vrf_id));
7716
7717       if (mp->is_ipv6)
7718         {
7719           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
7720           vat_json_object_add_ip4 (node, "src_address", ip4);
7721         }
7722       else
7723         {
7724           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
7725           vat_json_object_add_ip6 (node, "server_address", ip6);
7726         }
7727     }
7728 }
7729
7730 static int
7731 api_dhcp_proxy_dump (vat_main_t * vam)
7732 {
7733   unformat_input_t *i = vam->input;
7734   vl_api_control_ping_t *mp_ping;
7735   vl_api_dhcp_proxy_dump_t *mp;
7736   u8 is_ipv6 = 0;
7737   int ret;
7738
7739   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7740     {
7741       if (unformat (i, "ipv6"))
7742         is_ipv6 = 1;
7743       else
7744         {
7745           clib_warning ("parse error '%U'", format_unformat_error, i);
7746           return -99;
7747         }
7748     }
7749
7750   M (DHCP_PROXY_DUMP, mp);
7751
7752   mp->is_ip6 = is_ipv6;
7753   S (mp);
7754
7755   /* Use a control ping for synchronization */
7756   M (CONTROL_PING, mp_ping);
7757   S (mp_ping);
7758
7759   W (ret);
7760   return ret;
7761 }
7762
7763 static int
7764 api_dhcp_proxy_set_vss (vat_main_t * vam)
7765 {
7766   unformat_input_t *i = vam->input;
7767   vl_api_dhcp_proxy_set_vss_t *mp;
7768   u8 is_ipv6 = 0;
7769   u8 is_add = 1;
7770   u32 tbl_id;
7771   u8 tbl_id_set = 0;
7772   u32 oui;
7773   u8 oui_set = 0;
7774   u32 fib_id;
7775   u8 fib_id_set = 0;
7776   int ret;
7777
7778   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7779     {
7780       if (unformat (i, "tbl_id %d", &tbl_id))
7781         tbl_id_set = 1;
7782       if (unformat (i, "fib_id %d", &fib_id))
7783         fib_id_set = 1;
7784       if (unformat (i, "oui %d", &oui))
7785         oui_set = 1;
7786       else if (unformat (i, "ipv6"))
7787         is_ipv6 = 1;
7788       else if (unformat (i, "del"))
7789         is_add = 0;
7790       else
7791         {
7792           clib_warning ("parse error '%U'", format_unformat_error, i);
7793           return -99;
7794         }
7795     }
7796
7797   if (tbl_id_set == 0)
7798     {
7799       errmsg ("missing tbl id");
7800       return -99;
7801     }
7802
7803   if (fib_id_set == 0)
7804     {
7805       errmsg ("missing fib id");
7806       return -99;
7807     }
7808   if (oui_set == 0)
7809     {
7810       errmsg ("missing oui");
7811       return -99;
7812     }
7813
7814   M (DHCP_PROXY_SET_VSS, mp);
7815   mp->tbl_id = ntohl (tbl_id);
7816   mp->fib_id = ntohl (fib_id);
7817   mp->oui = ntohl (oui);
7818   mp->is_ipv6 = is_ipv6;
7819   mp->is_add = is_add;
7820
7821   S (mp);
7822   W (ret);
7823   return ret;
7824 }
7825
7826 static int
7827 api_dhcp_client_config (vat_main_t * vam)
7828 {
7829   unformat_input_t *i = vam->input;
7830   vl_api_dhcp_client_config_t *mp;
7831   u32 sw_if_index;
7832   u8 sw_if_index_set = 0;
7833   u8 is_add = 1;
7834   u8 *hostname = 0;
7835   u8 disable_event = 0;
7836   int ret;
7837
7838   /* Parse args required to build the message */
7839   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7840     {
7841       if (unformat (i, "del"))
7842         is_add = 0;
7843       else
7844         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7845         sw_if_index_set = 1;
7846       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7847         sw_if_index_set = 1;
7848       else if (unformat (i, "hostname %s", &hostname))
7849         ;
7850       else if (unformat (i, "disable_event"))
7851         disable_event = 1;
7852       else
7853         break;
7854     }
7855
7856   if (sw_if_index_set == 0)
7857     {
7858       errmsg ("missing interface name or sw_if_index");
7859       return -99;
7860     }
7861
7862   if (vec_len (hostname) > 63)
7863     {
7864       errmsg ("hostname too long");
7865     }
7866   vec_add1 (hostname, 0);
7867
7868   /* Construct the API message */
7869   M (DHCP_CLIENT_CONFIG, mp);
7870
7871   mp->sw_if_index = ntohl (sw_if_index);
7872   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7873   vec_free (hostname);
7874   mp->is_add = is_add;
7875   mp->want_dhcp_event = disable_event ? 0 : 1;
7876   mp->pid = getpid ();
7877
7878   /* send it... */
7879   S (mp);
7880
7881   /* Wait for a reply, return good/bad news  */
7882   W (ret);
7883   return ret;
7884 }
7885
7886 static int
7887 api_set_ip_flow_hash (vat_main_t * vam)
7888 {
7889   unformat_input_t *i = vam->input;
7890   vl_api_set_ip_flow_hash_t *mp;
7891   u32 vrf_id = 0;
7892   u8 is_ipv6 = 0;
7893   u8 vrf_id_set = 0;
7894   u8 src = 0;
7895   u8 dst = 0;
7896   u8 sport = 0;
7897   u8 dport = 0;
7898   u8 proto = 0;
7899   u8 reverse = 0;
7900   int ret;
7901
7902   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7903     {
7904       if (unformat (i, "vrf %d", &vrf_id))
7905         vrf_id_set = 1;
7906       else if (unformat (i, "ipv6"))
7907         is_ipv6 = 1;
7908       else if (unformat (i, "src"))
7909         src = 1;
7910       else if (unformat (i, "dst"))
7911         dst = 1;
7912       else if (unformat (i, "sport"))
7913         sport = 1;
7914       else if (unformat (i, "dport"))
7915         dport = 1;
7916       else if (unformat (i, "proto"))
7917         proto = 1;
7918       else if (unformat (i, "reverse"))
7919         reverse = 1;
7920
7921       else
7922         {
7923           clib_warning ("parse error '%U'", format_unformat_error, i);
7924           return -99;
7925         }
7926     }
7927
7928   if (vrf_id_set == 0)
7929     {
7930       errmsg ("missing vrf id");
7931       return -99;
7932     }
7933
7934   M (SET_IP_FLOW_HASH, mp);
7935   mp->src = src;
7936   mp->dst = dst;
7937   mp->sport = sport;
7938   mp->dport = dport;
7939   mp->proto = proto;
7940   mp->reverse = reverse;
7941   mp->vrf_id = ntohl (vrf_id);
7942   mp->is_ipv6 = is_ipv6;
7943
7944   S (mp);
7945   W (ret);
7946   return ret;
7947 }
7948
7949 static int
7950 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7951 {
7952   unformat_input_t *i = vam->input;
7953   vl_api_sw_interface_ip6_enable_disable_t *mp;
7954   u32 sw_if_index;
7955   u8 sw_if_index_set = 0;
7956   u8 enable = 0;
7957   int ret;
7958
7959   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7960     {
7961       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7962         sw_if_index_set = 1;
7963       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7964         sw_if_index_set = 1;
7965       else if (unformat (i, "enable"))
7966         enable = 1;
7967       else if (unformat (i, "disable"))
7968         enable = 0;
7969       else
7970         {
7971           clib_warning ("parse error '%U'", format_unformat_error, i);
7972           return -99;
7973         }
7974     }
7975
7976   if (sw_if_index_set == 0)
7977     {
7978       errmsg ("missing interface name or sw_if_index");
7979       return -99;
7980     }
7981
7982   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
7983
7984   mp->sw_if_index = ntohl (sw_if_index);
7985   mp->enable = enable;
7986
7987   S (mp);
7988   W (ret);
7989   return ret;
7990 }
7991
7992 static int
7993 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7994 {
7995   unformat_input_t *i = vam->input;
7996   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7997   u32 sw_if_index;
7998   u8 sw_if_index_set = 0;
7999   u8 v6_address_set = 0;
8000   ip6_address_t v6address;
8001   int ret;
8002
8003   /* Parse args required to build the message */
8004   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8005     {
8006       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8007         sw_if_index_set = 1;
8008       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8009         sw_if_index_set = 1;
8010       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8011         v6_address_set = 1;
8012       else
8013         break;
8014     }
8015
8016   if (sw_if_index_set == 0)
8017     {
8018       errmsg ("missing interface name or sw_if_index");
8019       return -99;
8020     }
8021   if (!v6_address_set)
8022     {
8023       errmsg ("no address set");
8024       return -99;
8025     }
8026
8027   /* Construct the API message */
8028   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
8029
8030   mp->sw_if_index = ntohl (sw_if_index);
8031   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8032
8033   /* send it... */
8034   S (mp);
8035
8036   /* Wait for a reply, return good/bad news  */
8037   W (ret);
8038   return ret;
8039 }
8040
8041 static int
8042 api_ip6nd_proxy_add_del (vat_main_t * vam)
8043 {
8044   unformat_input_t *i = vam->input;
8045   vl_api_ip6nd_proxy_add_del_t *mp;
8046   u32 sw_if_index = ~0;
8047   u8 v6_address_set = 0;
8048   ip6_address_t v6address;
8049   u8 is_del = 0;
8050   int ret;
8051
8052   /* Parse args required to build the message */
8053   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8054     {
8055       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8056         ;
8057       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8058         ;
8059       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8060         v6_address_set = 1;
8061       if (unformat (i, "del"))
8062         is_del = 1;
8063       else
8064         {
8065           clib_warning ("parse error '%U'", format_unformat_error, i);
8066           return -99;
8067         }
8068     }
8069
8070   if (sw_if_index == ~0)
8071     {
8072       errmsg ("missing interface name or sw_if_index");
8073       return -99;
8074     }
8075   if (!v6_address_set)
8076     {
8077       errmsg ("no address set");
8078       return -99;
8079     }
8080
8081   /* Construct the API message */
8082   M (IP6ND_PROXY_ADD_DEL, mp);
8083
8084   mp->is_del = is_del;
8085   mp->sw_if_index = ntohl (sw_if_index);
8086   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8087
8088   /* send it... */
8089   S (mp);
8090
8091   /* Wait for a reply, return good/bad news  */
8092   W (ret);
8093   return ret;
8094 }
8095
8096 static int
8097 api_ip6nd_proxy_dump (vat_main_t * vam)
8098 {
8099   vl_api_ip6nd_proxy_dump_t *mp;
8100   vl_api_control_ping_t *mp_ping;
8101   int ret;
8102
8103   M (IP6ND_PROXY_DUMP, mp);
8104
8105   S (mp);
8106
8107   /* Use a control ping for synchronization */
8108   M (CONTROL_PING, mp_ping);
8109   S (mp_ping);
8110
8111   W (ret);
8112   return ret;
8113 }
8114
8115 static void vl_api_ip6nd_proxy_details_t_handler
8116   (vl_api_ip6nd_proxy_details_t * mp)
8117 {
8118   vat_main_t *vam = &vat_main;
8119
8120   print (vam->ofp, "host %U sw_if_index %d",
8121          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
8122 }
8123
8124 static void vl_api_ip6nd_proxy_details_t_handler_json
8125   (vl_api_ip6nd_proxy_details_t * mp)
8126 {
8127   vat_main_t *vam = &vat_main;
8128   struct in6_addr ip6;
8129   vat_json_node_t *node = NULL;
8130
8131   if (VAT_JSON_ARRAY != vam->json_tree.type)
8132     {
8133       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8134       vat_json_init_array (&vam->json_tree);
8135     }
8136   node = vat_json_array_add (&vam->json_tree);
8137
8138   vat_json_init_object (node);
8139   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
8140
8141   clib_memcpy (&ip6, mp->address, sizeof (ip6));
8142   vat_json_object_add_ip6 (node, "host", ip6);
8143 }
8144
8145 static int
8146 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
8147 {
8148   unformat_input_t *i = vam->input;
8149   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
8150   u32 sw_if_index;
8151   u8 sw_if_index_set = 0;
8152   u32 address_length = 0;
8153   u8 v6_address_set = 0;
8154   ip6_address_t v6address;
8155   u8 use_default = 0;
8156   u8 no_advertise = 0;
8157   u8 off_link = 0;
8158   u8 no_autoconfig = 0;
8159   u8 no_onlink = 0;
8160   u8 is_no = 0;
8161   u32 val_lifetime = 0;
8162   u32 pref_lifetime = 0;
8163   int ret;
8164
8165   /* Parse args required to build the message */
8166   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8167     {
8168       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8169         sw_if_index_set = 1;
8170       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8171         sw_if_index_set = 1;
8172       else if (unformat (i, "%U/%d",
8173                          unformat_ip6_address, &v6address, &address_length))
8174         v6_address_set = 1;
8175       else if (unformat (i, "val_life %d", &val_lifetime))
8176         ;
8177       else if (unformat (i, "pref_life %d", &pref_lifetime))
8178         ;
8179       else if (unformat (i, "def"))
8180         use_default = 1;
8181       else if (unformat (i, "noadv"))
8182         no_advertise = 1;
8183       else if (unformat (i, "offl"))
8184         off_link = 1;
8185       else if (unformat (i, "noauto"))
8186         no_autoconfig = 1;
8187       else if (unformat (i, "nolink"))
8188         no_onlink = 1;
8189       else if (unformat (i, "isno"))
8190         is_no = 1;
8191       else
8192         {
8193           clib_warning ("parse error '%U'", format_unformat_error, i);
8194           return -99;
8195         }
8196     }
8197
8198   if (sw_if_index_set == 0)
8199     {
8200       errmsg ("missing interface name or sw_if_index");
8201       return -99;
8202     }
8203   if (!v6_address_set)
8204     {
8205       errmsg ("no address set");
8206       return -99;
8207     }
8208
8209   /* Construct the API message */
8210   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
8211
8212   mp->sw_if_index = ntohl (sw_if_index);
8213   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8214   mp->address_length = address_length;
8215   mp->use_default = use_default;
8216   mp->no_advertise = no_advertise;
8217   mp->off_link = off_link;
8218   mp->no_autoconfig = no_autoconfig;
8219   mp->no_onlink = no_onlink;
8220   mp->is_no = is_no;
8221   mp->val_lifetime = ntohl (val_lifetime);
8222   mp->pref_lifetime = ntohl (pref_lifetime);
8223
8224   /* send it... */
8225   S (mp);
8226
8227   /* Wait for a reply, return good/bad news  */
8228   W (ret);
8229   return ret;
8230 }
8231
8232 static int
8233 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
8234 {
8235   unformat_input_t *i = vam->input;
8236   vl_api_sw_interface_ip6nd_ra_config_t *mp;
8237   u32 sw_if_index;
8238   u8 sw_if_index_set = 0;
8239   u8 suppress = 0;
8240   u8 managed = 0;
8241   u8 other = 0;
8242   u8 ll_option = 0;
8243   u8 send_unicast = 0;
8244   u8 cease = 0;
8245   u8 is_no = 0;
8246   u8 default_router = 0;
8247   u32 max_interval = 0;
8248   u32 min_interval = 0;
8249   u32 lifetime = 0;
8250   u32 initial_count = 0;
8251   u32 initial_interval = 0;
8252   int ret;
8253
8254
8255   /* Parse args required to build the message */
8256   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8257     {
8258       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8259         sw_if_index_set = 1;
8260       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8261         sw_if_index_set = 1;
8262       else if (unformat (i, "maxint %d", &max_interval))
8263         ;
8264       else if (unformat (i, "minint %d", &min_interval))
8265         ;
8266       else if (unformat (i, "life %d", &lifetime))
8267         ;
8268       else if (unformat (i, "count %d", &initial_count))
8269         ;
8270       else if (unformat (i, "interval %d", &initial_interval))
8271         ;
8272       else if (unformat (i, "suppress") || unformat (i, "surpress"))
8273         suppress = 1;
8274       else if (unformat (i, "managed"))
8275         managed = 1;
8276       else if (unformat (i, "other"))
8277         other = 1;
8278       else if (unformat (i, "ll"))
8279         ll_option = 1;
8280       else if (unformat (i, "send"))
8281         send_unicast = 1;
8282       else if (unformat (i, "cease"))
8283         cease = 1;
8284       else if (unformat (i, "isno"))
8285         is_no = 1;
8286       else if (unformat (i, "def"))
8287         default_router = 1;
8288       else
8289         {
8290           clib_warning ("parse error '%U'", format_unformat_error, i);
8291           return -99;
8292         }
8293     }
8294
8295   if (sw_if_index_set == 0)
8296     {
8297       errmsg ("missing interface name or sw_if_index");
8298       return -99;
8299     }
8300
8301   /* Construct the API message */
8302   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
8303
8304   mp->sw_if_index = ntohl (sw_if_index);
8305   mp->max_interval = ntohl (max_interval);
8306   mp->min_interval = ntohl (min_interval);
8307   mp->lifetime = ntohl (lifetime);
8308   mp->initial_count = ntohl (initial_count);
8309   mp->initial_interval = ntohl (initial_interval);
8310   mp->suppress = suppress;
8311   mp->managed = managed;
8312   mp->other = other;
8313   mp->ll_option = ll_option;
8314   mp->send_unicast = send_unicast;
8315   mp->cease = cease;
8316   mp->is_no = is_no;
8317   mp->default_router = default_router;
8318
8319   /* send it... */
8320   S (mp);
8321
8322   /* Wait for a reply, return good/bad news  */
8323   W (ret);
8324   return ret;
8325 }
8326
8327 static int
8328 api_set_arp_neighbor_limit (vat_main_t * vam)
8329 {
8330   unformat_input_t *i = vam->input;
8331   vl_api_set_arp_neighbor_limit_t *mp;
8332   u32 arp_nbr_limit;
8333   u8 limit_set = 0;
8334   u8 is_ipv6 = 0;
8335   int ret;
8336
8337   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8338     {
8339       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
8340         limit_set = 1;
8341       else if (unformat (i, "ipv6"))
8342         is_ipv6 = 1;
8343       else
8344         {
8345           clib_warning ("parse error '%U'", format_unformat_error, i);
8346           return -99;
8347         }
8348     }
8349
8350   if (limit_set == 0)
8351     {
8352       errmsg ("missing limit value");
8353       return -99;
8354     }
8355
8356   M (SET_ARP_NEIGHBOR_LIMIT, mp);
8357
8358   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
8359   mp->is_ipv6 = is_ipv6;
8360
8361   S (mp);
8362   W (ret);
8363   return ret;
8364 }
8365
8366 static int
8367 api_l2_patch_add_del (vat_main_t * vam)
8368 {
8369   unformat_input_t *i = vam->input;
8370   vl_api_l2_patch_add_del_t *mp;
8371   u32 rx_sw_if_index;
8372   u8 rx_sw_if_index_set = 0;
8373   u32 tx_sw_if_index;
8374   u8 tx_sw_if_index_set = 0;
8375   u8 is_add = 1;
8376   int ret;
8377
8378   /* Parse args required to build the message */
8379   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8380     {
8381       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
8382         rx_sw_if_index_set = 1;
8383       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
8384         tx_sw_if_index_set = 1;
8385       else if (unformat (i, "rx"))
8386         {
8387           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8388             {
8389               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8390                             &rx_sw_if_index))
8391                 rx_sw_if_index_set = 1;
8392             }
8393           else
8394             break;
8395         }
8396       else if (unformat (i, "tx"))
8397         {
8398           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8399             {
8400               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8401                             &tx_sw_if_index))
8402                 tx_sw_if_index_set = 1;
8403             }
8404           else
8405             break;
8406         }
8407       else if (unformat (i, "del"))
8408         is_add = 0;
8409       else
8410         break;
8411     }
8412
8413   if (rx_sw_if_index_set == 0)
8414     {
8415       errmsg ("missing rx interface name or rx_sw_if_index");
8416       return -99;
8417     }
8418
8419   if (tx_sw_if_index_set == 0)
8420     {
8421       errmsg ("missing tx interface name or tx_sw_if_index");
8422       return -99;
8423     }
8424
8425   M (L2_PATCH_ADD_DEL, mp);
8426
8427   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
8428   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
8429   mp->is_add = is_add;
8430
8431   S (mp);
8432   W (ret);
8433   return ret;
8434 }
8435
8436 u8 is_del;
8437 u8 localsid_addr[16];
8438 u8 end_psp;
8439 u8 behavior;
8440 u32 sw_if_index;
8441 u32 vlan_index;
8442 u32 fib_table;
8443 u8 nh_addr[16];
8444
8445 static int
8446 api_sr_localsid_add_del (vat_main_t * vam)
8447 {
8448   unformat_input_t *i = vam->input;
8449   vl_api_sr_localsid_add_del_t *mp;
8450
8451   u8 is_del;
8452   ip6_address_t localsid;
8453   u8 end_psp = 0;
8454   u8 behavior = ~0;
8455   u32 sw_if_index;
8456   u32 fib_table = ~(u32) 0;
8457   ip6_address_t next_hop;
8458
8459   bool nexthop_set = 0;
8460
8461   int ret;
8462
8463   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8464     {
8465       if (unformat (i, "del"))
8466         is_del = 1;
8467       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
8468       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
8469         nexthop_set = 1;
8470       else if (unformat (i, "behavior %u", &behavior));
8471       else if (unformat (i, "sw_if_index %u", &sw_if_index));
8472       else if (unformat (i, "fib-table %u", &fib_table));
8473       else if (unformat (i, "end.psp %u", &behavior));
8474       else
8475         break;
8476     }
8477
8478   M (SR_LOCALSID_ADD_DEL, mp);
8479
8480   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
8481   if (nexthop_set)
8482     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
8483   mp->behavior = behavior;
8484   mp->sw_if_index = ntohl (sw_if_index);
8485   mp->fib_table = ntohl (fib_table);
8486   mp->end_psp = end_psp;
8487   mp->is_del = is_del;
8488
8489   S (mp);
8490   W (ret);
8491   return ret;
8492 }
8493
8494 static int
8495 api_ioam_enable (vat_main_t * vam)
8496 {
8497   unformat_input_t *input = vam->input;
8498   vl_api_ioam_enable_t *mp;
8499   u32 id = 0;
8500   int has_trace_option = 0;
8501   int has_pot_option = 0;
8502   int has_seqno_option = 0;
8503   int has_analyse_option = 0;
8504   int ret;
8505
8506   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8507     {
8508       if (unformat (input, "trace"))
8509         has_trace_option = 1;
8510       else if (unformat (input, "pot"))
8511         has_pot_option = 1;
8512       else if (unformat (input, "seqno"))
8513         has_seqno_option = 1;
8514       else if (unformat (input, "analyse"))
8515         has_analyse_option = 1;
8516       else
8517         break;
8518     }
8519   M (IOAM_ENABLE, mp);
8520   mp->id = htons (id);
8521   mp->seqno = has_seqno_option;
8522   mp->analyse = has_analyse_option;
8523   mp->pot_enable = has_pot_option;
8524   mp->trace_enable = has_trace_option;
8525
8526   S (mp);
8527   W (ret);
8528   return ret;
8529 }
8530
8531
8532 static int
8533 api_ioam_disable (vat_main_t * vam)
8534 {
8535   vl_api_ioam_disable_t *mp;
8536   int ret;
8537
8538   M (IOAM_DISABLE, mp);
8539   S (mp);
8540   W (ret);
8541   return ret;
8542 }
8543
8544 #define foreach_tcp_proto_field                 \
8545 _(src_port)                                     \
8546 _(dst_port)
8547
8548 #define foreach_udp_proto_field                 \
8549 _(src_port)                                     \
8550 _(dst_port)
8551
8552 #define foreach_ip4_proto_field                 \
8553 _(src_address)                                  \
8554 _(dst_address)                                  \
8555 _(tos)                                          \
8556 _(length)                                       \
8557 _(fragment_id)                                  \
8558 _(ttl)                                          \
8559 _(protocol)                                     \
8560 _(checksum)
8561
8562 typedef struct
8563 {
8564   u16 src_port, dst_port;
8565 } tcpudp_header_t;
8566
8567 #if VPP_API_TEST_BUILTIN == 0
8568 uword
8569 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8570 {
8571   u8 **maskp = va_arg (*args, u8 **);
8572   u8 *mask = 0;
8573   u8 found_something = 0;
8574   tcp_header_t *tcp;
8575
8576 #define _(a) u8 a=0;
8577   foreach_tcp_proto_field;
8578 #undef _
8579
8580   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8581     {
8582       if (0);
8583 #define _(a) else if (unformat (input, #a)) a=1;
8584       foreach_tcp_proto_field
8585 #undef _
8586         else
8587         break;
8588     }
8589
8590 #define _(a) found_something += a;
8591   foreach_tcp_proto_field;
8592 #undef _
8593
8594   if (found_something == 0)
8595     return 0;
8596
8597   vec_validate (mask, sizeof (*tcp) - 1);
8598
8599   tcp = (tcp_header_t *) mask;
8600
8601 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8602   foreach_tcp_proto_field;
8603 #undef _
8604
8605   *maskp = mask;
8606   return 1;
8607 }
8608
8609 uword
8610 unformat_udp_mask (unformat_input_t * input, va_list * args)
8611 {
8612   u8 **maskp = va_arg (*args, u8 **);
8613   u8 *mask = 0;
8614   u8 found_something = 0;
8615   udp_header_t *udp;
8616
8617 #define _(a) u8 a=0;
8618   foreach_udp_proto_field;
8619 #undef _
8620
8621   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8622     {
8623       if (0);
8624 #define _(a) else if (unformat (input, #a)) a=1;
8625       foreach_udp_proto_field
8626 #undef _
8627         else
8628         break;
8629     }
8630
8631 #define _(a) found_something += a;
8632   foreach_udp_proto_field;
8633 #undef _
8634
8635   if (found_something == 0)
8636     return 0;
8637
8638   vec_validate (mask, sizeof (*udp) - 1);
8639
8640   udp = (udp_header_t *) mask;
8641
8642 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8643   foreach_udp_proto_field;
8644 #undef _
8645
8646   *maskp = mask;
8647   return 1;
8648 }
8649
8650 uword
8651 unformat_l4_mask (unformat_input_t * input, va_list * args)
8652 {
8653   u8 **maskp = va_arg (*args, u8 **);
8654   u16 src_port = 0, dst_port = 0;
8655   tcpudp_header_t *tcpudp;
8656
8657   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8658     {
8659       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8660         return 1;
8661       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8662         return 1;
8663       else if (unformat (input, "src_port"))
8664         src_port = 0xFFFF;
8665       else if (unformat (input, "dst_port"))
8666         dst_port = 0xFFFF;
8667       else
8668         return 0;
8669     }
8670
8671   if (!src_port && !dst_port)
8672     return 0;
8673
8674   u8 *mask = 0;
8675   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8676
8677   tcpudp = (tcpudp_header_t *) mask;
8678   tcpudp->src_port = src_port;
8679   tcpudp->dst_port = dst_port;
8680
8681   *maskp = mask;
8682
8683   return 1;
8684 }
8685
8686 uword
8687 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8688 {
8689   u8 **maskp = va_arg (*args, u8 **);
8690   u8 *mask = 0;
8691   u8 found_something = 0;
8692   ip4_header_t *ip;
8693
8694 #define _(a) u8 a=0;
8695   foreach_ip4_proto_field;
8696 #undef _
8697   u8 version = 0;
8698   u8 hdr_length = 0;
8699
8700
8701   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8702     {
8703       if (unformat (input, "version"))
8704         version = 1;
8705       else if (unformat (input, "hdr_length"))
8706         hdr_length = 1;
8707       else if (unformat (input, "src"))
8708         src_address = 1;
8709       else if (unformat (input, "dst"))
8710         dst_address = 1;
8711       else if (unformat (input, "proto"))
8712         protocol = 1;
8713
8714 #define _(a) else if (unformat (input, #a)) a=1;
8715       foreach_ip4_proto_field
8716 #undef _
8717         else
8718         break;
8719     }
8720
8721 #define _(a) found_something += a;
8722   foreach_ip4_proto_field;
8723 #undef _
8724
8725   if (found_something == 0)
8726     return 0;
8727
8728   vec_validate (mask, sizeof (*ip) - 1);
8729
8730   ip = (ip4_header_t *) mask;
8731
8732 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8733   foreach_ip4_proto_field;
8734 #undef _
8735
8736   ip->ip_version_and_header_length = 0;
8737
8738   if (version)
8739     ip->ip_version_and_header_length |= 0xF0;
8740
8741   if (hdr_length)
8742     ip->ip_version_and_header_length |= 0x0F;
8743
8744   *maskp = mask;
8745   return 1;
8746 }
8747
8748 #define foreach_ip6_proto_field                 \
8749 _(src_address)                                  \
8750 _(dst_address)                                  \
8751 _(payload_length)                               \
8752 _(hop_limit)                                    \
8753 _(protocol)
8754
8755 uword
8756 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8757 {
8758   u8 **maskp = va_arg (*args, u8 **);
8759   u8 *mask = 0;
8760   u8 found_something = 0;
8761   ip6_header_t *ip;
8762   u32 ip_version_traffic_class_and_flow_label;
8763
8764 #define _(a) u8 a=0;
8765   foreach_ip6_proto_field;
8766 #undef _
8767   u8 version = 0;
8768   u8 traffic_class = 0;
8769   u8 flow_label = 0;
8770
8771   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8772     {
8773       if (unformat (input, "version"))
8774         version = 1;
8775       else if (unformat (input, "traffic-class"))
8776         traffic_class = 1;
8777       else if (unformat (input, "flow-label"))
8778         flow_label = 1;
8779       else if (unformat (input, "src"))
8780         src_address = 1;
8781       else if (unformat (input, "dst"))
8782         dst_address = 1;
8783       else if (unformat (input, "proto"))
8784         protocol = 1;
8785
8786 #define _(a) else if (unformat (input, #a)) a=1;
8787       foreach_ip6_proto_field
8788 #undef _
8789         else
8790         break;
8791     }
8792
8793 #define _(a) found_something += a;
8794   foreach_ip6_proto_field;
8795 #undef _
8796
8797   if (found_something == 0)
8798     return 0;
8799
8800   vec_validate (mask, sizeof (*ip) - 1);
8801
8802   ip = (ip6_header_t *) mask;
8803
8804 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8805   foreach_ip6_proto_field;
8806 #undef _
8807
8808   ip_version_traffic_class_and_flow_label = 0;
8809
8810   if (version)
8811     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8812
8813   if (traffic_class)
8814     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8815
8816   if (flow_label)
8817     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8818
8819   ip->ip_version_traffic_class_and_flow_label =
8820     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8821
8822   *maskp = mask;
8823   return 1;
8824 }
8825
8826 uword
8827 unformat_l3_mask (unformat_input_t * input, va_list * args)
8828 {
8829   u8 **maskp = va_arg (*args, u8 **);
8830
8831   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8832     {
8833       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8834         return 1;
8835       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8836         return 1;
8837       else
8838         break;
8839     }
8840   return 0;
8841 }
8842
8843 uword
8844 unformat_l2_mask (unformat_input_t * input, va_list * args)
8845 {
8846   u8 **maskp = va_arg (*args, u8 **);
8847   u8 *mask = 0;
8848   u8 src = 0;
8849   u8 dst = 0;
8850   u8 proto = 0;
8851   u8 tag1 = 0;
8852   u8 tag2 = 0;
8853   u8 ignore_tag1 = 0;
8854   u8 ignore_tag2 = 0;
8855   u8 cos1 = 0;
8856   u8 cos2 = 0;
8857   u8 dot1q = 0;
8858   u8 dot1ad = 0;
8859   int len = 14;
8860
8861   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8862     {
8863       if (unformat (input, "src"))
8864         src = 1;
8865       else if (unformat (input, "dst"))
8866         dst = 1;
8867       else if (unformat (input, "proto"))
8868         proto = 1;
8869       else if (unformat (input, "tag1"))
8870         tag1 = 1;
8871       else if (unformat (input, "tag2"))
8872         tag2 = 1;
8873       else if (unformat (input, "ignore-tag1"))
8874         ignore_tag1 = 1;
8875       else if (unformat (input, "ignore-tag2"))
8876         ignore_tag2 = 1;
8877       else if (unformat (input, "cos1"))
8878         cos1 = 1;
8879       else if (unformat (input, "cos2"))
8880         cos2 = 1;
8881       else if (unformat (input, "dot1q"))
8882         dot1q = 1;
8883       else if (unformat (input, "dot1ad"))
8884         dot1ad = 1;
8885       else
8886         break;
8887     }
8888   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8889        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8890     return 0;
8891
8892   if (tag1 || ignore_tag1 || cos1 || dot1q)
8893     len = 18;
8894   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8895     len = 22;
8896
8897   vec_validate (mask, len - 1);
8898
8899   if (dst)
8900     memset (mask, 0xff, 6);
8901
8902   if (src)
8903     memset (mask + 6, 0xff, 6);
8904
8905   if (tag2 || dot1ad)
8906     {
8907       /* inner vlan tag */
8908       if (tag2)
8909         {
8910           mask[19] = 0xff;
8911           mask[18] = 0x0f;
8912         }
8913       if (cos2)
8914         mask[18] |= 0xe0;
8915       if (proto)
8916         mask[21] = mask[20] = 0xff;
8917       if (tag1)
8918         {
8919           mask[15] = 0xff;
8920           mask[14] = 0x0f;
8921         }
8922       if (cos1)
8923         mask[14] |= 0xe0;
8924       *maskp = mask;
8925       return 1;
8926     }
8927   if (tag1 | dot1q)
8928     {
8929       if (tag1)
8930         {
8931           mask[15] = 0xff;
8932           mask[14] = 0x0f;
8933         }
8934       if (cos1)
8935         mask[14] |= 0xe0;
8936       if (proto)
8937         mask[16] = mask[17] = 0xff;
8938
8939       *maskp = mask;
8940       return 1;
8941     }
8942   if (cos2)
8943     mask[18] |= 0xe0;
8944   if (cos1)
8945     mask[14] |= 0xe0;
8946   if (proto)
8947     mask[12] = mask[13] = 0xff;
8948
8949   *maskp = mask;
8950   return 1;
8951 }
8952
8953 uword
8954 unformat_classify_mask (unformat_input_t * input, va_list * args)
8955 {
8956   u8 **maskp = va_arg (*args, u8 **);
8957   u32 *skipp = va_arg (*args, u32 *);
8958   u32 *matchp = va_arg (*args, u32 *);
8959   u32 match;
8960   u8 *mask = 0;
8961   u8 *l2 = 0;
8962   u8 *l3 = 0;
8963   u8 *l4 = 0;
8964   int i;
8965
8966   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8967     {
8968       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8969         ;
8970       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8971         ;
8972       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8973         ;
8974       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8975         ;
8976       else
8977         break;
8978     }
8979
8980   if (l4 && !l3)
8981     {
8982       vec_free (mask);
8983       vec_free (l2);
8984       vec_free (l4);
8985       return 0;
8986     }
8987
8988   if (mask || l2 || l3 || l4)
8989     {
8990       if (l2 || l3 || l4)
8991         {
8992           /* "With a free Ethernet header in every package" */
8993           if (l2 == 0)
8994             vec_validate (l2, 13);
8995           mask = l2;
8996           if (vec_len (l3))
8997             {
8998               vec_append (mask, l3);
8999               vec_free (l3);
9000             }
9001           if (vec_len (l4))
9002             {
9003               vec_append (mask, l4);
9004               vec_free (l4);
9005             }
9006         }
9007
9008       /* Scan forward looking for the first significant mask octet */
9009       for (i = 0; i < vec_len (mask); i++)
9010         if (mask[i])
9011           break;
9012
9013       /* compute (skip, match) params */
9014       *skipp = i / sizeof (u32x4);
9015       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9016
9017       /* Pad mask to an even multiple of the vector size */
9018       while (vec_len (mask) % sizeof (u32x4))
9019         vec_add1 (mask, 0);
9020
9021       match = vec_len (mask) / sizeof (u32x4);
9022
9023       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9024         {
9025           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9026           if (*tmp || *(tmp + 1))
9027             break;
9028           match--;
9029         }
9030       if (match == 0)
9031         clib_warning ("BUG: match 0");
9032
9033       _vec_len (mask) = match * sizeof (u32x4);
9034
9035       *matchp = match;
9036       *maskp = mask;
9037
9038       return 1;
9039     }
9040
9041   return 0;
9042 }
9043 #endif /* VPP_API_TEST_BUILTIN */
9044
9045 #define foreach_l2_next                         \
9046 _(drop, DROP)                                   \
9047 _(ethernet, ETHERNET_INPUT)                     \
9048 _(ip4, IP4_INPUT)                               \
9049 _(ip6, IP6_INPUT)
9050
9051 uword
9052 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9053 {
9054   u32 *miss_next_indexp = va_arg (*args, u32 *);
9055   u32 next_index = 0;
9056   u32 tmp;
9057
9058 #define _(n,N) \
9059   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9060   foreach_l2_next;
9061 #undef _
9062
9063   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 #define foreach_ip_next                         \
9077 _(drop, DROP)                                   \
9078 _(local, LOCAL)                                 \
9079 _(rewrite, REWRITE)
9080
9081 uword
9082 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9083 {
9084   u32 *miss_next_indexp = va_arg (*args, u32 *);
9085   u32 next_index = 0;
9086   u32 tmp;
9087
9088 #define _(n,N) \
9089   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9090   foreach_ip_next;
9091 #undef _
9092
9093   if (unformat (input, "%d", &tmp))
9094     {
9095       next_index = tmp;
9096       goto out;
9097     }
9098
9099   return 0;
9100
9101 out:
9102   *miss_next_indexp = next_index;
9103   return 1;
9104 }
9105
9106 #define foreach_acl_next                        \
9107 _(deny, DENY)
9108
9109 uword
9110 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9111 {
9112   u32 *miss_next_indexp = va_arg (*args, u32 *);
9113   u32 next_index = 0;
9114   u32 tmp;
9115
9116 #define _(n,N) \
9117   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9118   foreach_acl_next;
9119 #undef _
9120
9121   if (unformat (input, "permit"))
9122     {
9123       next_index = ~0;
9124       goto out;
9125     }
9126   else if (unformat (input, "%d", &tmp))
9127     {
9128       next_index = tmp;
9129       goto out;
9130     }
9131
9132   return 0;
9133
9134 out:
9135   *miss_next_indexp = next_index;
9136   return 1;
9137 }
9138
9139 uword
9140 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9141 {
9142   u32 *r = va_arg (*args, u32 *);
9143
9144   if (unformat (input, "conform-color"))
9145     *r = POLICE_CONFORM;
9146   else if (unformat (input, "exceed-color"))
9147     *r = POLICE_EXCEED;
9148   else
9149     return 0;
9150
9151   return 1;
9152 }
9153
9154 static int
9155 api_classify_add_del_table (vat_main_t * vam)
9156 {
9157   unformat_input_t *i = vam->input;
9158   vl_api_classify_add_del_table_t *mp;
9159
9160   u32 nbuckets = 2;
9161   u32 skip = ~0;
9162   u32 match = ~0;
9163   int is_add = 1;
9164   int del_chain = 0;
9165   u32 table_index = ~0;
9166   u32 next_table_index = ~0;
9167   u32 miss_next_index = ~0;
9168   u32 memory_size = 32 << 20;
9169   u8 *mask = 0;
9170   u32 current_data_flag = 0;
9171   int current_data_offset = 0;
9172   int ret;
9173
9174   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9175     {
9176       if (unformat (i, "del"))
9177         is_add = 0;
9178       else if (unformat (i, "del-chain"))
9179         {
9180           is_add = 0;
9181           del_chain = 1;
9182         }
9183       else if (unformat (i, "buckets %d", &nbuckets))
9184         ;
9185       else if (unformat (i, "memory_size %d", &memory_size))
9186         ;
9187       else if (unformat (i, "skip %d", &skip))
9188         ;
9189       else if (unformat (i, "match %d", &match))
9190         ;
9191       else if (unformat (i, "table %d", &table_index))
9192         ;
9193       else if (unformat (i, "mask %U", unformat_classify_mask,
9194                          &mask, &skip, &match))
9195         ;
9196       else if (unformat (i, "next-table %d", &next_table_index))
9197         ;
9198       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
9199                          &miss_next_index))
9200         ;
9201       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
9202                          &miss_next_index))
9203         ;
9204       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
9205                          &miss_next_index))
9206         ;
9207       else if (unformat (i, "current-data-flag %d", &current_data_flag))
9208         ;
9209       else if (unformat (i, "current-data-offset %d", &current_data_offset))
9210         ;
9211       else
9212         break;
9213     }
9214
9215   if (is_add && mask == 0)
9216     {
9217       errmsg ("Mask required");
9218       return -99;
9219     }
9220
9221   if (is_add && skip == ~0)
9222     {
9223       errmsg ("skip count required");
9224       return -99;
9225     }
9226
9227   if (is_add && match == ~0)
9228     {
9229       errmsg ("match count required");
9230       return -99;
9231     }
9232
9233   if (!is_add && table_index == ~0)
9234     {
9235       errmsg ("table index required for delete");
9236       return -99;
9237     }
9238
9239   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
9240
9241   mp->is_add = is_add;
9242   mp->del_chain = del_chain;
9243   mp->table_index = ntohl (table_index);
9244   mp->nbuckets = ntohl (nbuckets);
9245   mp->memory_size = ntohl (memory_size);
9246   mp->skip_n_vectors = ntohl (skip);
9247   mp->match_n_vectors = ntohl (match);
9248   mp->next_table_index = ntohl (next_table_index);
9249   mp->miss_next_index = ntohl (miss_next_index);
9250   mp->current_data_flag = ntohl (current_data_flag);
9251   mp->current_data_offset = ntohl (current_data_offset);
9252   clib_memcpy (mp->mask, mask, vec_len (mask));
9253
9254   vec_free (mask);
9255
9256   S (mp);
9257   W (ret);
9258   return ret;
9259 }
9260
9261 #if VPP_API_TEST_BUILTIN == 0
9262 uword
9263 unformat_l4_match (unformat_input_t * input, va_list * args)
9264 {
9265   u8 **matchp = va_arg (*args, u8 **);
9266
9267   u8 *proto_header = 0;
9268   int src_port = 0;
9269   int dst_port = 0;
9270
9271   tcpudp_header_t h;
9272
9273   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9274     {
9275       if (unformat (input, "src_port %d", &src_port))
9276         ;
9277       else if (unformat (input, "dst_port %d", &dst_port))
9278         ;
9279       else
9280         return 0;
9281     }
9282
9283   h.src_port = clib_host_to_net_u16 (src_port);
9284   h.dst_port = clib_host_to_net_u16 (dst_port);
9285   vec_validate (proto_header, sizeof (h) - 1);
9286   memcpy (proto_header, &h, sizeof (h));
9287
9288   *matchp = proto_header;
9289
9290   return 1;
9291 }
9292
9293 uword
9294 unformat_ip4_match (unformat_input_t * input, va_list * args)
9295 {
9296   u8 **matchp = va_arg (*args, u8 **);
9297   u8 *match = 0;
9298   ip4_header_t *ip;
9299   int version = 0;
9300   u32 version_val;
9301   int hdr_length = 0;
9302   u32 hdr_length_val;
9303   int src = 0, dst = 0;
9304   ip4_address_t src_val, dst_val;
9305   int proto = 0;
9306   u32 proto_val;
9307   int tos = 0;
9308   u32 tos_val;
9309   int length = 0;
9310   u32 length_val;
9311   int fragment_id = 0;
9312   u32 fragment_id_val;
9313   int ttl = 0;
9314   int ttl_val;
9315   int checksum = 0;
9316   u32 checksum_val;
9317
9318   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9319     {
9320       if (unformat (input, "version %d", &version_val))
9321         version = 1;
9322       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9323         hdr_length = 1;
9324       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9325         src = 1;
9326       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9327         dst = 1;
9328       else if (unformat (input, "proto %d", &proto_val))
9329         proto = 1;
9330       else if (unformat (input, "tos %d", &tos_val))
9331         tos = 1;
9332       else if (unformat (input, "length %d", &length_val))
9333         length = 1;
9334       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9335         fragment_id = 1;
9336       else if (unformat (input, "ttl %d", &ttl_val))
9337         ttl = 1;
9338       else if (unformat (input, "checksum %d", &checksum_val))
9339         checksum = 1;
9340       else
9341         break;
9342     }
9343
9344   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9345       + ttl + checksum == 0)
9346     return 0;
9347
9348   /*
9349    * Aligned because we use the real comparison functions
9350    */
9351   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9352
9353   ip = (ip4_header_t *) match;
9354
9355   /* These are realistically matched in practice */
9356   if (src)
9357     ip->src_address.as_u32 = src_val.as_u32;
9358
9359   if (dst)
9360     ip->dst_address.as_u32 = dst_val.as_u32;
9361
9362   if (proto)
9363     ip->protocol = proto_val;
9364
9365
9366   /* These are not, but they're included for completeness */
9367   if (version)
9368     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9369
9370   if (hdr_length)
9371     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9372
9373   if (tos)
9374     ip->tos = tos_val;
9375
9376   if (length)
9377     ip->length = clib_host_to_net_u16 (length_val);
9378
9379   if (ttl)
9380     ip->ttl = ttl_val;
9381
9382   if (checksum)
9383     ip->checksum = clib_host_to_net_u16 (checksum_val);
9384
9385   *matchp = match;
9386   return 1;
9387 }
9388
9389 uword
9390 unformat_ip6_match (unformat_input_t * input, va_list * args)
9391 {
9392   u8 **matchp = va_arg (*args, u8 **);
9393   u8 *match = 0;
9394   ip6_header_t *ip;
9395   int version = 0;
9396   u32 version_val;
9397   u8 traffic_class = 0;
9398   u32 traffic_class_val = 0;
9399   u8 flow_label = 0;
9400   u8 flow_label_val;
9401   int src = 0, dst = 0;
9402   ip6_address_t src_val, dst_val;
9403   int proto = 0;
9404   u32 proto_val;
9405   int payload_length = 0;
9406   u32 payload_length_val;
9407   int hop_limit = 0;
9408   int hop_limit_val;
9409   u32 ip_version_traffic_class_and_flow_label;
9410
9411   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9412     {
9413       if (unformat (input, "version %d", &version_val))
9414         version = 1;
9415       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9416         traffic_class = 1;
9417       else if (unformat (input, "flow_label %d", &flow_label_val))
9418         flow_label = 1;
9419       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9420         src = 1;
9421       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9422         dst = 1;
9423       else if (unformat (input, "proto %d", &proto_val))
9424         proto = 1;
9425       else if (unformat (input, "payload_length %d", &payload_length_val))
9426         payload_length = 1;
9427       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9428         hop_limit = 1;
9429       else
9430         break;
9431     }
9432
9433   if (version + traffic_class + flow_label + src + dst + proto +
9434       payload_length + hop_limit == 0)
9435     return 0;
9436
9437   /*
9438    * Aligned because we use the real comparison functions
9439    */
9440   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9441
9442   ip = (ip6_header_t *) match;
9443
9444   if (src)
9445     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9446
9447   if (dst)
9448     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9449
9450   if (proto)
9451     ip->protocol = proto_val;
9452
9453   ip_version_traffic_class_and_flow_label = 0;
9454
9455   if (version)
9456     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9457
9458   if (traffic_class)
9459     ip_version_traffic_class_and_flow_label |=
9460       (traffic_class_val & 0xFF) << 20;
9461
9462   if (flow_label)
9463     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9464
9465   ip->ip_version_traffic_class_and_flow_label =
9466     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9467
9468   if (payload_length)
9469     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9470
9471   if (hop_limit)
9472     ip->hop_limit = hop_limit_val;
9473
9474   *matchp = match;
9475   return 1;
9476 }
9477
9478 uword
9479 unformat_l3_match (unformat_input_t * input, va_list * args)
9480 {
9481   u8 **matchp = va_arg (*args, u8 **);
9482
9483   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9484     {
9485       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9486         return 1;
9487       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9488         return 1;
9489       else
9490         break;
9491     }
9492   return 0;
9493 }
9494
9495 uword
9496 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9497 {
9498   u8 *tagp = va_arg (*args, u8 *);
9499   u32 tag;
9500
9501   if (unformat (input, "%d", &tag))
9502     {
9503       tagp[0] = (tag >> 8) & 0x0F;
9504       tagp[1] = tag & 0xFF;
9505       return 1;
9506     }
9507
9508   return 0;
9509 }
9510
9511 uword
9512 unformat_l2_match (unformat_input_t * input, va_list * args)
9513 {
9514   u8 **matchp = va_arg (*args, u8 **);
9515   u8 *match = 0;
9516   u8 src = 0;
9517   u8 src_val[6];
9518   u8 dst = 0;
9519   u8 dst_val[6];
9520   u8 proto = 0;
9521   u16 proto_val;
9522   u8 tag1 = 0;
9523   u8 tag1_val[2];
9524   u8 tag2 = 0;
9525   u8 tag2_val[2];
9526   int len = 14;
9527   u8 ignore_tag1 = 0;
9528   u8 ignore_tag2 = 0;
9529   u8 cos1 = 0;
9530   u8 cos2 = 0;
9531   u32 cos1_val = 0;
9532   u32 cos2_val = 0;
9533
9534   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9535     {
9536       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9537         src = 1;
9538       else
9539         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9540         dst = 1;
9541       else if (unformat (input, "proto %U",
9542                          unformat_ethernet_type_host_byte_order, &proto_val))
9543         proto = 1;
9544       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9545         tag1 = 1;
9546       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9547         tag2 = 1;
9548       else if (unformat (input, "ignore-tag1"))
9549         ignore_tag1 = 1;
9550       else if (unformat (input, "ignore-tag2"))
9551         ignore_tag2 = 1;
9552       else if (unformat (input, "cos1 %d", &cos1_val))
9553         cos1 = 1;
9554       else if (unformat (input, "cos2 %d", &cos2_val))
9555         cos2 = 1;
9556       else
9557         break;
9558     }
9559   if ((src + dst + proto + tag1 + tag2 +
9560        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9561     return 0;
9562
9563   if (tag1 || ignore_tag1 || cos1)
9564     len = 18;
9565   if (tag2 || ignore_tag2 || cos2)
9566     len = 22;
9567
9568   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9569
9570   if (dst)
9571     clib_memcpy (match, dst_val, 6);
9572
9573   if (src)
9574     clib_memcpy (match + 6, src_val, 6);
9575
9576   if (tag2)
9577     {
9578       /* inner vlan tag */
9579       match[19] = tag2_val[1];
9580       match[18] = tag2_val[0];
9581       if (cos2)
9582         match[18] |= (cos2_val & 0x7) << 5;
9583       if (proto)
9584         {
9585           match[21] = proto_val & 0xff;
9586           match[20] = proto_val >> 8;
9587         }
9588       if (tag1)
9589         {
9590           match[15] = tag1_val[1];
9591           match[14] = tag1_val[0];
9592         }
9593       if (cos1)
9594         match[14] |= (cos1_val & 0x7) << 5;
9595       *matchp = match;
9596       return 1;
9597     }
9598   if (tag1)
9599     {
9600       match[15] = tag1_val[1];
9601       match[14] = tag1_val[0];
9602       if (proto)
9603         {
9604           match[17] = proto_val & 0xff;
9605           match[16] = proto_val >> 8;
9606         }
9607       if (cos1)
9608         match[14] |= (cos1_val & 0x7) << 5;
9609
9610       *matchp = match;
9611       return 1;
9612     }
9613   if (cos2)
9614     match[18] |= (cos2_val & 0x7) << 5;
9615   if (cos1)
9616     match[14] |= (cos1_val & 0x7) << 5;
9617   if (proto)
9618     {
9619       match[13] = proto_val & 0xff;
9620       match[12] = proto_val >> 8;
9621     }
9622
9623   *matchp = match;
9624   return 1;
9625 }
9626 #endif
9627
9628 uword
9629 api_unformat_classify_match (unformat_input_t * input, va_list * args)
9630 {
9631   u8 **matchp = va_arg (*args, u8 **);
9632   u32 skip_n_vectors = va_arg (*args, u32);
9633   u32 match_n_vectors = va_arg (*args, u32);
9634
9635   u8 *match = 0;
9636   u8 *l2 = 0;
9637   u8 *l3 = 0;
9638   u8 *l4 = 0;
9639
9640   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9641     {
9642       if (unformat (input, "hex %U", unformat_hex_string, &match))
9643         ;
9644       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9645         ;
9646       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9647         ;
9648       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9649         ;
9650       else
9651         break;
9652     }
9653
9654   if (l4 && !l3)
9655     {
9656       vec_free (match);
9657       vec_free (l2);
9658       vec_free (l4);
9659       return 0;
9660     }
9661
9662   if (match || l2 || l3 || l4)
9663     {
9664       if (l2 || l3 || l4)
9665         {
9666           /* "Win a free Ethernet header in every packet" */
9667           if (l2 == 0)
9668             vec_validate_aligned (l2, 13, sizeof (u32x4));
9669           match = l2;
9670           if (vec_len (l3))
9671             {
9672               vec_append_aligned (match, l3, sizeof (u32x4));
9673               vec_free (l3);
9674             }
9675           if (vec_len (l4))
9676             {
9677               vec_append_aligned (match, l4, sizeof (u32x4));
9678               vec_free (l4);
9679             }
9680         }
9681
9682       /* Make sure the vector is big enough even if key is all 0's */
9683       vec_validate_aligned
9684         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9685          sizeof (u32x4));
9686
9687       /* Set size, include skipped vectors */
9688       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9689
9690       *matchp = match;
9691
9692       return 1;
9693     }
9694
9695   return 0;
9696 }
9697
9698 static int
9699 api_classify_add_del_session (vat_main_t * vam)
9700 {
9701   unformat_input_t *i = vam->input;
9702   vl_api_classify_add_del_session_t *mp;
9703   int is_add = 1;
9704   u32 table_index = ~0;
9705   u32 hit_next_index = ~0;
9706   u32 opaque_index = ~0;
9707   u8 *match = 0;
9708   i32 advance = 0;
9709   u32 skip_n_vectors = 0;
9710   u32 match_n_vectors = 0;
9711   u32 action = 0;
9712   u32 metadata = 0;
9713   int ret;
9714
9715   /*
9716    * Warning: you have to supply skip_n and match_n
9717    * because the API client cant simply look at the classify
9718    * table object.
9719    */
9720
9721   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9722     {
9723       if (unformat (i, "del"))
9724         is_add = 0;
9725       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
9726                          &hit_next_index))
9727         ;
9728       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9729                          &hit_next_index))
9730         ;
9731       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
9732                          &hit_next_index))
9733         ;
9734       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9735         ;
9736       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9737         ;
9738       else if (unformat (i, "opaque-index %d", &opaque_index))
9739         ;
9740       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9741         ;
9742       else if (unformat (i, "match_n %d", &match_n_vectors))
9743         ;
9744       else if (unformat (i, "match %U", api_unformat_classify_match,
9745                          &match, skip_n_vectors, match_n_vectors))
9746         ;
9747       else if (unformat (i, "advance %d", &advance))
9748         ;
9749       else if (unformat (i, "table-index %d", &table_index))
9750         ;
9751       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9752         action = 1;
9753       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9754         action = 2;
9755       else if (unformat (i, "action %d", &action))
9756         ;
9757       else if (unformat (i, "metadata %d", &metadata))
9758         ;
9759       else
9760         break;
9761     }
9762
9763   if (table_index == ~0)
9764     {
9765       errmsg ("Table index required");
9766       return -99;
9767     }
9768
9769   if (is_add && match == 0)
9770     {
9771       errmsg ("Match value required");
9772       return -99;
9773     }
9774
9775   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
9776
9777   mp->is_add = is_add;
9778   mp->table_index = ntohl (table_index);
9779   mp->hit_next_index = ntohl (hit_next_index);
9780   mp->opaque_index = ntohl (opaque_index);
9781   mp->advance = ntohl (advance);
9782   mp->action = action;
9783   mp->metadata = ntohl (metadata);
9784   clib_memcpy (mp->match, match, vec_len (match));
9785   vec_free (match);
9786
9787   S (mp);
9788   W (ret);
9789   return ret;
9790 }
9791
9792 static int
9793 api_classify_set_interface_ip_table (vat_main_t * vam)
9794 {
9795   unformat_input_t *i = vam->input;
9796   vl_api_classify_set_interface_ip_table_t *mp;
9797   u32 sw_if_index;
9798   int sw_if_index_set;
9799   u32 table_index = ~0;
9800   u8 is_ipv6 = 0;
9801   int ret;
9802
9803   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9804     {
9805       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9806         sw_if_index_set = 1;
9807       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9808         sw_if_index_set = 1;
9809       else if (unformat (i, "table %d", &table_index))
9810         ;
9811       else
9812         {
9813           clib_warning ("parse error '%U'", format_unformat_error, i);
9814           return -99;
9815         }
9816     }
9817
9818   if (sw_if_index_set == 0)
9819     {
9820       errmsg ("missing interface name or sw_if_index");
9821       return -99;
9822     }
9823
9824
9825   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
9826
9827   mp->sw_if_index = ntohl (sw_if_index);
9828   mp->table_index = ntohl (table_index);
9829   mp->is_ipv6 = is_ipv6;
9830
9831   S (mp);
9832   W (ret);
9833   return ret;
9834 }
9835
9836 static int
9837 api_classify_set_interface_l2_tables (vat_main_t * vam)
9838 {
9839   unformat_input_t *i = vam->input;
9840   vl_api_classify_set_interface_l2_tables_t *mp;
9841   u32 sw_if_index;
9842   int sw_if_index_set;
9843   u32 ip4_table_index = ~0;
9844   u32 ip6_table_index = ~0;
9845   u32 other_table_index = ~0;
9846   u32 is_input = 1;
9847   int ret;
9848
9849   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9850     {
9851       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9852         sw_if_index_set = 1;
9853       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9854         sw_if_index_set = 1;
9855       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9856         ;
9857       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9858         ;
9859       else if (unformat (i, "other-table %d", &other_table_index))
9860         ;
9861       else if (unformat (i, "is-input %d", &is_input))
9862         ;
9863       else
9864         {
9865           clib_warning ("parse error '%U'", format_unformat_error, i);
9866           return -99;
9867         }
9868     }
9869
9870   if (sw_if_index_set == 0)
9871     {
9872       errmsg ("missing interface name or sw_if_index");
9873       return -99;
9874     }
9875
9876
9877   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
9878
9879   mp->sw_if_index = ntohl (sw_if_index);
9880   mp->ip4_table_index = ntohl (ip4_table_index);
9881   mp->ip6_table_index = ntohl (ip6_table_index);
9882   mp->other_table_index = ntohl (other_table_index);
9883   mp->is_input = (u8) is_input;
9884
9885   S (mp);
9886   W (ret);
9887   return ret;
9888 }
9889
9890 static int
9891 api_set_ipfix_exporter (vat_main_t * vam)
9892 {
9893   unformat_input_t *i = vam->input;
9894   vl_api_set_ipfix_exporter_t *mp;
9895   ip4_address_t collector_address;
9896   u8 collector_address_set = 0;
9897   u32 collector_port = ~0;
9898   ip4_address_t src_address;
9899   u8 src_address_set = 0;
9900   u32 vrf_id = ~0;
9901   u32 path_mtu = ~0;
9902   u32 template_interval = ~0;
9903   u8 udp_checksum = 0;
9904   int ret;
9905
9906   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9907     {
9908       if (unformat (i, "collector_address %U", unformat_ip4_address,
9909                     &collector_address))
9910         collector_address_set = 1;
9911       else if (unformat (i, "collector_port %d", &collector_port))
9912         ;
9913       else if (unformat (i, "src_address %U", unformat_ip4_address,
9914                          &src_address))
9915         src_address_set = 1;
9916       else if (unformat (i, "vrf_id %d", &vrf_id))
9917         ;
9918       else if (unformat (i, "path_mtu %d", &path_mtu))
9919         ;
9920       else if (unformat (i, "template_interval %d", &template_interval))
9921         ;
9922       else if (unformat (i, "udp_checksum"))
9923         udp_checksum = 1;
9924       else
9925         break;
9926     }
9927
9928   if (collector_address_set == 0)
9929     {
9930       errmsg ("collector_address required");
9931       return -99;
9932     }
9933
9934   if (src_address_set == 0)
9935     {
9936       errmsg ("src_address required");
9937       return -99;
9938     }
9939
9940   M (SET_IPFIX_EXPORTER, mp);
9941
9942   memcpy (mp->collector_address, collector_address.data,
9943           sizeof (collector_address.data));
9944   mp->collector_port = htons ((u16) collector_port);
9945   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9946   mp->vrf_id = htonl (vrf_id);
9947   mp->path_mtu = htonl (path_mtu);
9948   mp->template_interval = htonl (template_interval);
9949   mp->udp_checksum = udp_checksum;
9950
9951   S (mp);
9952   W (ret);
9953   return ret;
9954 }
9955
9956 static int
9957 api_set_ipfix_classify_stream (vat_main_t * vam)
9958 {
9959   unformat_input_t *i = vam->input;
9960   vl_api_set_ipfix_classify_stream_t *mp;
9961   u32 domain_id = 0;
9962   u32 src_port = UDP_DST_PORT_ipfix;
9963   int ret;
9964
9965   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9966     {
9967       if (unformat (i, "domain %d", &domain_id))
9968         ;
9969       else if (unformat (i, "src_port %d", &src_port))
9970         ;
9971       else
9972         {
9973           errmsg ("unknown input `%U'", format_unformat_error, i);
9974           return -99;
9975         }
9976     }
9977
9978   M (SET_IPFIX_CLASSIFY_STREAM, mp);
9979
9980   mp->domain_id = htonl (domain_id);
9981   mp->src_port = htons ((u16) src_port);
9982
9983   S (mp);
9984   W (ret);
9985   return ret;
9986 }
9987
9988 static int
9989 api_ipfix_classify_table_add_del (vat_main_t * vam)
9990 {
9991   unformat_input_t *i = vam->input;
9992   vl_api_ipfix_classify_table_add_del_t *mp;
9993   int is_add = -1;
9994   u32 classify_table_index = ~0;
9995   u8 ip_version = 0;
9996   u8 transport_protocol = 255;
9997   int ret;
9998
9999   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10000     {
10001       if (unformat (i, "add"))
10002         is_add = 1;
10003       else if (unformat (i, "del"))
10004         is_add = 0;
10005       else if (unformat (i, "table %d", &classify_table_index))
10006         ;
10007       else if (unformat (i, "ip4"))
10008         ip_version = 4;
10009       else if (unformat (i, "ip6"))
10010         ip_version = 6;
10011       else if (unformat (i, "tcp"))
10012         transport_protocol = 6;
10013       else if (unformat (i, "udp"))
10014         transport_protocol = 17;
10015       else
10016         {
10017           errmsg ("unknown input `%U'", format_unformat_error, i);
10018           return -99;
10019         }
10020     }
10021
10022   if (is_add == -1)
10023     {
10024       errmsg ("expecting: add|del");
10025       return -99;
10026     }
10027   if (classify_table_index == ~0)
10028     {
10029       errmsg ("classifier table not specified");
10030       return -99;
10031     }
10032   if (ip_version == 0)
10033     {
10034       errmsg ("IP version not specified");
10035       return -99;
10036     }
10037
10038   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10039
10040   mp->is_add = is_add;
10041   mp->table_id = htonl (classify_table_index);
10042   mp->ip_version = ip_version;
10043   mp->transport_protocol = transport_protocol;
10044
10045   S (mp);
10046   W (ret);
10047   return ret;
10048 }
10049
10050 static int
10051 api_get_node_index (vat_main_t * vam)
10052 {
10053   unformat_input_t *i = vam->input;
10054   vl_api_get_node_index_t *mp;
10055   u8 *name = 0;
10056   int ret;
10057
10058   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10059     {
10060       if (unformat (i, "node %s", &name))
10061         ;
10062       else
10063         break;
10064     }
10065   if (name == 0)
10066     {
10067       errmsg ("node name required");
10068       return -99;
10069     }
10070   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10071     {
10072       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10073       return -99;
10074     }
10075
10076   M (GET_NODE_INDEX, mp);
10077   clib_memcpy (mp->node_name, name, vec_len (name));
10078   vec_free (name);
10079
10080   S (mp);
10081   W (ret);
10082   return ret;
10083 }
10084
10085 static int
10086 api_get_next_index (vat_main_t * vam)
10087 {
10088   unformat_input_t *i = vam->input;
10089   vl_api_get_next_index_t *mp;
10090   u8 *node_name = 0, *next_node_name = 0;
10091   int ret;
10092
10093   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10094     {
10095       if (unformat (i, "node-name %s", &node_name))
10096         ;
10097       else if (unformat (i, "next-node-name %s", &next_node_name))
10098         break;
10099     }
10100
10101   if (node_name == 0)
10102     {
10103       errmsg ("node name required");
10104       return -99;
10105     }
10106   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10107     {
10108       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10109       return -99;
10110     }
10111
10112   if (next_node_name == 0)
10113     {
10114       errmsg ("next node name required");
10115       return -99;
10116     }
10117   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10118     {
10119       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10120       return -99;
10121     }
10122
10123   M (GET_NEXT_INDEX, mp);
10124   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10125   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10126   vec_free (node_name);
10127   vec_free (next_node_name);
10128
10129   S (mp);
10130   W (ret);
10131   return ret;
10132 }
10133
10134 static int
10135 api_add_node_next (vat_main_t * vam)
10136 {
10137   unformat_input_t *i = vam->input;
10138   vl_api_add_node_next_t *mp;
10139   u8 *name = 0;
10140   u8 *next = 0;
10141   int ret;
10142
10143   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10144     {
10145       if (unformat (i, "node %s", &name))
10146         ;
10147       else if (unformat (i, "next %s", &next))
10148         ;
10149       else
10150         break;
10151     }
10152   if (name == 0)
10153     {
10154       errmsg ("node name required");
10155       return -99;
10156     }
10157   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10158     {
10159       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10160       return -99;
10161     }
10162   if (next == 0)
10163     {
10164       errmsg ("next node required");
10165       return -99;
10166     }
10167   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10168     {
10169       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10170       return -99;
10171     }
10172
10173   M (ADD_NODE_NEXT, mp);
10174   clib_memcpy (mp->node_name, name, vec_len (name));
10175   clib_memcpy (mp->next_name, next, vec_len (next));
10176   vec_free (name);
10177   vec_free (next);
10178
10179   S (mp);
10180   W (ret);
10181   return ret;
10182 }
10183
10184 static int
10185 api_l2tpv3_create_tunnel (vat_main_t * vam)
10186 {
10187   unformat_input_t *i = vam->input;
10188   ip6_address_t client_address, our_address;
10189   int client_address_set = 0;
10190   int our_address_set = 0;
10191   u32 local_session_id = 0;
10192   u32 remote_session_id = 0;
10193   u64 local_cookie = 0;
10194   u64 remote_cookie = 0;
10195   u8 l2_sublayer_present = 0;
10196   vl_api_l2tpv3_create_tunnel_t *mp;
10197   int ret;
10198
10199   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10200     {
10201       if (unformat (i, "client_address %U", unformat_ip6_address,
10202                     &client_address))
10203         client_address_set = 1;
10204       else if (unformat (i, "our_address %U", unformat_ip6_address,
10205                          &our_address))
10206         our_address_set = 1;
10207       else if (unformat (i, "local_session_id %d", &local_session_id))
10208         ;
10209       else if (unformat (i, "remote_session_id %d", &remote_session_id))
10210         ;
10211       else if (unformat (i, "local_cookie %lld", &local_cookie))
10212         ;
10213       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10214         ;
10215       else if (unformat (i, "l2-sublayer-present"))
10216         l2_sublayer_present = 1;
10217       else
10218         break;
10219     }
10220
10221   if (client_address_set == 0)
10222     {
10223       errmsg ("client_address required");
10224       return -99;
10225     }
10226
10227   if (our_address_set == 0)
10228     {
10229       errmsg ("our_address required");
10230       return -99;
10231     }
10232
10233   M (L2TPV3_CREATE_TUNNEL, mp);
10234
10235   clib_memcpy (mp->client_address, client_address.as_u8,
10236                sizeof (mp->client_address));
10237
10238   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10239
10240   mp->local_session_id = ntohl (local_session_id);
10241   mp->remote_session_id = ntohl (remote_session_id);
10242   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10243   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10244   mp->l2_sublayer_present = l2_sublayer_present;
10245   mp->is_ipv6 = 1;
10246
10247   S (mp);
10248   W (ret);
10249   return ret;
10250 }
10251
10252 static int
10253 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10254 {
10255   unformat_input_t *i = vam->input;
10256   u32 sw_if_index;
10257   u8 sw_if_index_set = 0;
10258   u64 new_local_cookie = 0;
10259   u64 new_remote_cookie = 0;
10260   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10261   int ret;
10262
10263   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10264     {
10265       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10266         sw_if_index_set = 1;
10267       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10268         sw_if_index_set = 1;
10269       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10270         ;
10271       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10272         ;
10273       else
10274         break;
10275     }
10276
10277   if (sw_if_index_set == 0)
10278     {
10279       errmsg ("missing interface name or sw_if_index");
10280       return -99;
10281     }
10282
10283   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
10284
10285   mp->sw_if_index = ntohl (sw_if_index);
10286   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10287   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10288
10289   S (mp);
10290   W (ret);
10291   return ret;
10292 }
10293
10294 static int
10295 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10296 {
10297   unformat_input_t *i = vam->input;
10298   vl_api_l2tpv3_interface_enable_disable_t *mp;
10299   u32 sw_if_index;
10300   u8 sw_if_index_set = 0;
10301   u8 enable_disable = 1;
10302   int ret;
10303
10304   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10305     {
10306       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10307         sw_if_index_set = 1;
10308       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10309         sw_if_index_set = 1;
10310       else if (unformat (i, "enable"))
10311         enable_disable = 1;
10312       else if (unformat (i, "disable"))
10313         enable_disable = 0;
10314       else
10315         break;
10316     }
10317
10318   if (sw_if_index_set == 0)
10319     {
10320       errmsg ("missing interface name or sw_if_index");
10321       return -99;
10322     }
10323
10324   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
10325
10326   mp->sw_if_index = ntohl (sw_if_index);
10327   mp->enable_disable = enable_disable;
10328
10329   S (mp);
10330   W (ret);
10331   return ret;
10332 }
10333
10334 static int
10335 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10336 {
10337   unformat_input_t *i = vam->input;
10338   vl_api_l2tpv3_set_lookup_key_t *mp;
10339   u8 key = ~0;
10340   int ret;
10341
10342   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10343     {
10344       if (unformat (i, "lookup_v6_src"))
10345         key = L2T_LOOKUP_SRC_ADDRESS;
10346       else if (unformat (i, "lookup_v6_dst"))
10347         key = L2T_LOOKUP_DST_ADDRESS;
10348       else if (unformat (i, "lookup_session_id"))
10349         key = L2T_LOOKUP_SESSION_ID;
10350       else
10351         break;
10352     }
10353
10354   if (key == (u8) ~ 0)
10355     {
10356       errmsg ("l2tp session lookup key unset");
10357       return -99;
10358     }
10359
10360   M (L2TPV3_SET_LOOKUP_KEY, mp);
10361
10362   mp->key = key;
10363
10364   S (mp);
10365   W (ret);
10366   return ret;
10367 }
10368
10369 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10370   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10371 {
10372   vat_main_t *vam = &vat_main;
10373
10374   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10375          format_ip6_address, mp->our_address,
10376          format_ip6_address, mp->client_address,
10377          clib_net_to_host_u32 (mp->sw_if_index));
10378
10379   print (vam->ofp,
10380          "   local cookies %016llx %016llx remote cookie %016llx",
10381          clib_net_to_host_u64 (mp->local_cookie[0]),
10382          clib_net_to_host_u64 (mp->local_cookie[1]),
10383          clib_net_to_host_u64 (mp->remote_cookie));
10384
10385   print (vam->ofp, "   local session-id %d remote session-id %d",
10386          clib_net_to_host_u32 (mp->local_session_id),
10387          clib_net_to_host_u32 (mp->remote_session_id));
10388
10389   print (vam->ofp, "   l2 specific sublayer %s\n",
10390          mp->l2_sublayer_present ? "preset" : "absent");
10391
10392 }
10393
10394 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10395   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10396 {
10397   vat_main_t *vam = &vat_main;
10398   vat_json_node_t *node = NULL;
10399   struct in6_addr addr;
10400
10401   if (VAT_JSON_ARRAY != vam->json_tree.type)
10402     {
10403       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10404       vat_json_init_array (&vam->json_tree);
10405     }
10406   node = vat_json_array_add (&vam->json_tree);
10407
10408   vat_json_init_object (node);
10409
10410   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10411   vat_json_object_add_ip6 (node, "our_address", addr);
10412   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10413   vat_json_object_add_ip6 (node, "client_address", addr);
10414
10415   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10416   vat_json_init_array (lc);
10417   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10418   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10419   vat_json_object_add_uint (node, "remote_cookie",
10420                             clib_net_to_host_u64 (mp->remote_cookie));
10421
10422   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10423   vat_json_object_add_uint (node, "local_session_id",
10424                             clib_net_to_host_u32 (mp->local_session_id));
10425   vat_json_object_add_uint (node, "remote_session_id",
10426                             clib_net_to_host_u32 (mp->remote_session_id));
10427   vat_json_object_add_string_copy (node, "l2_sublayer",
10428                                    mp->l2_sublayer_present ? (u8 *) "present"
10429                                    : (u8 *) "absent");
10430 }
10431
10432 static int
10433 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10434 {
10435   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10436   vl_api_control_ping_t *mp_ping;
10437   int ret;
10438
10439   /* Get list of l2tpv3-tunnel interfaces */
10440   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
10441   S (mp);
10442
10443   /* Use a control ping for synchronization */
10444   M (CONTROL_PING, mp_ping);
10445   S (mp_ping);
10446
10447   W (ret);
10448   return ret;
10449 }
10450
10451
10452 static void vl_api_sw_interface_tap_details_t_handler
10453   (vl_api_sw_interface_tap_details_t * mp)
10454 {
10455   vat_main_t *vam = &vat_main;
10456
10457   print (vam->ofp, "%-16s %d",
10458          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10459 }
10460
10461 static void vl_api_sw_interface_tap_details_t_handler_json
10462   (vl_api_sw_interface_tap_details_t * mp)
10463 {
10464   vat_main_t *vam = &vat_main;
10465   vat_json_node_t *node = NULL;
10466
10467   if (VAT_JSON_ARRAY != vam->json_tree.type)
10468     {
10469       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10470       vat_json_init_array (&vam->json_tree);
10471     }
10472   node = vat_json_array_add (&vam->json_tree);
10473
10474   vat_json_init_object (node);
10475   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10476   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10477 }
10478
10479 static int
10480 api_sw_interface_tap_dump (vat_main_t * vam)
10481 {
10482   vl_api_sw_interface_tap_dump_t *mp;
10483   vl_api_control_ping_t *mp_ping;
10484   int ret;
10485
10486   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10487   /* Get list of tap interfaces */
10488   M (SW_INTERFACE_TAP_DUMP, mp);
10489   S (mp);
10490
10491   /* Use a control ping for synchronization */
10492   M (CONTROL_PING, mp_ping);
10493   S (mp_ping);
10494
10495   W (ret);
10496   return ret;
10497 }
10498
10499 static uword unformat_vxlan_decap_next
10500   (unformat_input_t * input, va_list * args)
10501 {
10502   u32 *result = va_arg (*args, u32 *);
10503   u32 tmp;
10504
10505   if (unformat (input, "l2"))
10506     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10507   else if (unformat (input, "%d", &tmp))
10508     *result = tmp;
10509   else
10510     return 0;
10511   return 1;
10512 }
10513
10514 static int
10515 api_vxlan_add_del_tunnel (vat_main_t * vam)
10516 {
10517   unformat_input_t *line_input = vam->input;
10518   vl_api_vxlan_add_del_tunnel_t *mp;
10519   ip46_address_t src, dst;
10520   u8 is_add = 1;
10521   u8 ipv4_set = 0, ipv6_set = 0;
10522   u8 src_set = 0;
10523   u8 dst_set = 0;
10524   u8 grp_set = 0;
10525   u32 mcast_sw_if_index = ~0;
10526   u32 encap_vrf_id = 0;
10527   u32 decap_next_index = ~0;
10528   u32 vni = 0;
10529   int ret;
10530
10531   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10532   memset (&src, 0, sizeof src);
10533   memset (&dst, 0, sizeof dst);
10534
10535   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10536     {
10537       if (unformat (line_input, "del"))
10538         is_add = 0;
10539       else
10540         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10541         {
10542           ipv4_set = 1;
10543           src_set = 1;
10544         }
10545       else
10546         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10547         {
10548           ipv4_set = 1;
10549           dst_set = 1;
10550         }
10551       else
10552         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10553         {
10554           ipv6_set = 1;
10555           src_set = 1;
10556         }
10557       else
10558         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10559         {
10560           ipv6_set = 1;
10561           dst_set = 1;
10562         }
10563       else if (unformat (line_input, "group %U %U",
10564                          unformat_ip4_address, &dst.ip4,
10565                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10566         {
10567           grp_set = dst_set = 1;
10568           ipv4_set = 1;
10569         }
10570       else if (unformat (line_input, "group %U",
10571                          unformat_ip4_address, &dst.ip4))
10572         {
10573           grp_set = dst_set = 1;
10574           ipv4_set = 1;
10575         }
10576       else if (unformat (line_input, "group %U %U",
10577                          unformat_ip6_address, &dst.ip6,
10578                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10579         {
10580           grp_set = dst_set = 1;
10581           ipv6_set = 1;
10582         }
10583       else if (unformat (line_input, "group %U",
10584                          unformat_ip6_address, &dst.ip6))
10585         {
10586           grp_set = dst_set = 1;
10587           ipv6_set = 1;
10588         }
10589       else
10590         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10591         ;
10592       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10593         ;
10594       else if (unformat (line_input, "decap-next %U",
10595                          unformat_vxlan_decap_next, &decap_next_index))
10596         ;
10597       else if (unformat (line_input, "vni %d", &vni))
10598         ;
10599       else
10600         {
10601           errmsg ("parse error '%U'", format_unformat_error, line_input);
10602           return -99;
10603         }
10604     }
10605
10606   if (src_set == 0)
10607     {
10608       errmsg ("tunnel src address not specified");
10609       return -99;
10610     }
10611   if (dst_set == 0)
10612     {
10613       errmsg ("tunnel dst address not specified");
10614       return -99;
10615     }
10616
10617   if (grp_set && !ip46_address_is_multicast (&dst))
10618     {
10619       errmsg ("tunnel group address not multicast");
10620       return -99;
10621     }
10622   if (grp_set && mcast_sw_if_index == ~0)
10623     {
10624       errmsg ("tunnel nonexistent multicast device");
10625       return -99;
10626     }
10627   if (grp_set == 0 && ip46_address_is_multicast (&dst))
10628     {
10629       errmsg ("tunnel dst address must be unicast");
10630       return -99;
10631     }
10632
10633
10634   if (ipv4_set && ipv6_set)
10635     {
10636       errmsg ("both IPv4 and IPv6 addresses specified");
10637       return -99;
10638     }
10639
10640   if ((vni == 0) || (vni >> 24))
10641     {
10642       errmsg ("vni not specified or out of range");
10643       return -99;
10644     }
10645
10646   M (VXLAN_ADD_DEL_TUNNEL, mp);
10647
10648   if (ipv6_set)
10649     {
10650       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10651       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10652     }
10653   else
10654     {
10655       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10656       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10657     }
10658   mp->encap_vrf_id = ntohl (encap_vrf_id);
10659   mp->decap_next_index = ntohl (decap_next_index);
10660   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10661   mp->vni = ntohl (vni);
10662   mp->is_add = is_add;
10663   mp->is_ipv6 = ipv6_set;
10664
10665   S (mp);
10666   W (ret);
10667   return ret;
10668 }
10669
10670 static void vl_api_vxlan_tunnel_details_t_handler
10671   (vl_api_vxlan_tunnel_details_t * mp)
10672 {
10673   vat_main_t *vam = &vat_main;
10674   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
10675   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
10676
10677   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
10678          ntohl (mp->sw_if_index),
10679          format_ip46_address, &src, IP46_TYPE_ANY,
10680          format_ip46_address, &dst, IP46_TYPE_ANY,
10681          ntohl (mp->encap_vrf_id),
10682          ntohl (mp->decap_next_index), ntohl (mp->vni),
10683          ntohl (mp->mcast_sw_if_index));
10684 }
10685
10686 static void vl_api_vxlan_tunnel_details_t_handler_json
10687   (vl_api_vxlan_tunnel_details_t * mp)
10688 {
10689   vat_main_t *vam = &vat_main;
10690   vat_json_node_t *node = NULL;
10691
10692   if (VAT_JSON_ARRAY != vam->json_tree.type)
10693     {
10694       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10695       vat_json_init_array (&vam->json_tree);
10696     }
10697   node = vat_json_array_add (&vam->json_tree);
10698
10699   vat_json_init_object (node);
10700   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10701   if (mp->is_ipv6)
10702     {
10703       struct in6_addr ip6;
10704
10705       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10706       vat_json_object_add_ip6 (node, "src_address", ip6);
10707       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10708       vat_json_object_add_ip6 (node, "dst_address", ip6);
10709     }
10710   else
10711     {
10712       struct in_addr ip4;
10713
10714       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10715       vat_json_object_add_ip4 (node, "src_address", ip4);
10716       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10717       vat_json_object_add_ip4 (node, "dst_address", ip4);
10718     }
10719   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10720   vat_json_object_add_uint (node, "decap_next_index",
10721                             ntohl (mp->decap_next_index));
10722   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10723   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10724   vat_json_object_add_uint (node, "mcast_sw_if_index",
10725                             ntohl (mp->mcast_sw_if_index));
10726 }
10727
10728 static int
10729 api_vxlan_tunnel_dump (vat_main_t * vam)
10730 {
10731   unformat_input_t *i = vam->input;
10732   vl_api_vxlan_tunnel_dump_t *mp;
10733   vl_api_control_ping_t *mp_ping;
10734   u32 sw_if_index;
10735   u8 sw_if_index_set = 0;
10736   int ret;
10737
10738   /* Parse args required to build the message */
10739   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10740     {
10741       if (unformat (i, "sw_if_index %d", &sw_if_index))
10742         sw_if_index_set = 1;
10743       else
10744         break;
10745     }
10746
10747   if (sw_if_index_set == 0)
10748     {
10749       sw_if_index = ~0;
10750     }
10751
10752   if (!vam->json_output)
10753     {
10754       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
10755              "sw_if_index", "src_address", "dst_address",
10756              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
10757     }
10758
10759   /* Get list of vxlan-tunnel interfaces */
10760   M (VXLAN_TUNNEL_DUMP, mp);
10761
10762   mp->sw_if_index = htonl (sw_if_index);
10763
10764   S (mp);
10765
10766   /* Use a control ping for synchronization */
10767   M (CONTROL_PING, mp_ping);
10768   S (mp_ping);
10769
10770   W (ret);
10771   return ret;
10772 }
10773
10774 static int
10775 api_gre_add_del_tunnel (vat_main_t * vam)
10776 {
10777   unformat_input_t *line_input = vam->input;
10778   vl_api_gre_add_del_tunnel_t *mp;
10779   ip4_address_t src4, dst4;
10780   u8 is_add = 1;
10781   u8 teb = 0;
10782   u8 src_set = 0;
10783   u8 dst_set = 0;
10784   u32 outer_fib_id = 0;
10785   int ret;
10786
10787   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10788     {
10789       if (unformat (line_input, "del"))
10790         is_add = 0;
10791       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10792         src_set = 1;
10793       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10794         dst_set = 1;
10795       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10796         ;
10797       else if (unformat (line_input, "teb"))
10798         teb = 1;
10799       else
10800         {
10801           errmsg ("parse error '%U'", format_unformat_error, line_input);
10802           return -99;
10803         }
10804     }
10805
10806   if (src_set == 0)
10807     {
10808       errmsg ("tunnel src address not specified");
10809       return -99;
10810     }
10811   if (dst_set == 0)
10812     {
10813       errmsg ("tunnel dst address not specified");
10814       return -99;
10815     }
10816
10817
10818   M (GRE_ADD_DEL_TUNNEL, mp);
10819
10820   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10821   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10822   mp->outer_fib_id = ntohl (outer_fib_id);
10823   mp->is_add = is_add;
10824   mp->teb = teb;
10825
10826   S (mp);
10827   W (ret);
10828   return ret;
10829 }
10830
10831 static void vl_api_gre_tunnel_details_t_handler
10832   (vl_api_gre_tunnel_details_t * mp)
10833 {
10834   vat_main_t *vam = &vat_main;
10835
10836   print (vam->ofp, "%11d%15U%15U%6d%14d",
10837          ntohl (mp->sw_if_index),
10838          format_ip4_address, &mp->src_address,
10839          format_ip4_address, &mp->dst_address,
10840          mp->teb, ntohl (mp->outer_fib_id));
10841 }
10842
10843 static void vl_api_gre_tunnel_details_t_handler_json
10844   (vl_api_gre_tunnel_details_t * mp)
10845 {
10846   vat_main_t *vam = &vat_main;
10847   vat_json_node_t *node = NULL;
10848   struct in_addr ip4;
10849
10850   if (VAT_JSON_ARRAY != vam->json_tree.type)
10851     {
10852       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10853       vat_json_init_array (&vam->json_tree);
10854     }
10855   node = vat_json_array_add (&vam->json_tree);
10856
10857   vat_json_init_object (node);
10858   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10859   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10860   vat_json_object_add_ip4 (node, "src_address", ip4);
10861   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10862   vat_json_object_add_ip4 (node, "dst_address", ip4);
10863   vat_json_object_add_uint (node, "teb", mp->teb);
10864   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10865 }
10866
10867 static int
10868 api_gre_tunnel_dump (vat_main_t * vam)
10869 {
10870   unformat_input_t *i = vam->input;
10871   vl_api_gre_tunnel_dump_t *mp;
10872   vl_api_control_ping_t *mp_ping;
10873   u32 sw_if_index;
10874   u8 sw_if_index_set = 0;
10875   int ret;
10876
10877   /* Parse args required to build the message */
10878   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10879     {
10880       if (unformat (i, "sw_if_index %d", &sw_if_index))
10881         sw_if_index_set = 1;
10882       else
10883         break;
10884     }
10885
10886   if (sw_if_index_set == 0)
10887     {
10888       sw_if_index = ~0;
10889     }
10890
10891   if (!vam->json_output)
10892     {
10893       print (vam->ofp, "%11s%15s%15s%6s%14s",
10894              "sw_if_index", "src_address", "dst_address", "teb",
10895              "outer_fib_id");
10896     }
10897
10898   /* Get list of gre-tunnel interfaces */
10899   M (GRE_TUNNEL_DUMP, mp);
10900
10901   mp->sw_if_index = htonl (sw_if_index);
10902
10903   S (mp);
10904
10905   /* Use a control ping for synchronization */
10906   M (CONTROL_PING, mp_ping);
10907   S (mp_ping);
10908
10909   W (ret);
10910   return ret;
10911 }
10912
10913 static int
10914 api_l2_fib_clear_table (vat_main_t * vam)
10915 {
10916 //  unformat_input_t * i = vam->input;
10917   vl_api_l2_fib_clear_table_t *mp;
10918   int ret;
10919
10920   M (L2_FIB_CLEAR_TABLE, mp);
10921
10922   S (mp);
10923   W (ret);
10924   return ret;
10925 }
10926
10927 static int
10928 api_l2_interface_efp_filter (vat_main_t * vam)
10929 {
10930   unformat_input_t *i = vam->input;
10931   vl_api_l2_interface_efp_filter_t *mp;
10932   u32 sw_if_index;
10933   u8 enable = 1;
10934   u8 sw_if_index_set = 0;
10935   int ret;
10936
10937   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10938     {
10939       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10940         sw_if_index_set = 1;
10941       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10942         sw_if_index_set = 1;
10943       else if (unformat (i, "enable"))
10944         enable = 1;
10945       else if (unformat (i, "disable"))
10946         enable = 0;
10947       else
10948         {
10949           clib_warning ("parse error '%U'", format_unformat_error, i);
10950           return -99;
10951         }
10952     }
10953
10954   if (sw_if_index_set == 0)
10955     {
10956       errmsg ("missing sw_if_index");
10957       return -99;
10958     }
10959
10960   M (L2_INTERFACE_EFP_FILTER, mp);
10961
10962   mp->sw_if_index = ntohl (sw_if_index);
10963   mp->enable_disable = enable;
10964
10965   S (mp);
10966   W (ret);
10967   return ret;
10968 }
10969
10970 #define foreach_vtr_op                          \
10971 _("disable",  L2_VTR_DISABLED)                  \
10972 _("push-1",  L2_VTR_PUSH_1)                     \
10973 _("push-2",  L2_VTR_PUSH_2)                     \
10974 _("pop-1",  L2_VTR_POP_1)                       \
10975 _("pop-2",  L2_VTR_POP_2)                       \
10976 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10977 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10978 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10979 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10980
10981 static int
10982 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10983 {
10984   unformat_input_t *i = vam->input;
10985   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10986   u32 sw_if_index;
10987   u8 sw_if_index_set = 0;
10988   u8 vtr_op_set = 0;
10989   u32 vtr_op = 0;
10990   u32 push_dot1q = 1;
10991   u32 tag1 = ~0;
10992   u32 tag2 = ~0;
10993   int ret;
10994
10995   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10996     {
10997       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10998         sw_if_index_set = 1;
10999       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11000         sw_if_index_set = 1;
11001       else if (unformat (i, "vtr_op %d", &vtr_op))
11002         vtr_op_set = 1;
11003 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
11004       foreach_vtr_op
11005 #undef _
11006         else if (unformat (i, "push_dot1q %d", &push_dot1q))
11007         ;
11008       else if (unformat (i, "tag1 %d", &tag1))
11009         ;
11010       else if (unformat (i, "tag2 %d", &tag2))
11011         ;
11012       else
11013         {
11014           clib_warning ("parse error '%U'", format_unformat_error, i);
11015           return -99;
11016         }
11017     }
11018
11019   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
11020     {
11021       errmsg ("missing vtr operation or sw_if_index");
11022       return -99;
11023     }
11024
11025   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
11026   mp->sw_if_index = ntohl (sw_if_index);
11027   mp->vtr_op = ntohl (vtr_op);
11028   mp->push_dot1q = ntohl (push_dot1q);
11029   mp->tag1 = ntohl (tag1);
11030   mp->tag2 = ntohl (tag2);
11031
11032   S (mp);
11033   W (ret);
11034   return ret;
11035 }
11036
11037 static int
11038 api_create_vhost_user_if (vat_main_t * vam)
11039 {
11040   unformat_input_t *i = vam->input;
11041   vl_api_create_vhost_user_if_t *mp;
11042   u8 *file_name;
11043   u8 is_server = 0;
11044   u8 file_name_set = 0;
11045   u32 custom_dev_instance = ~0;
11046   u8 hwaddr[6];
11047   u8 use_custom_mac = 0;
11048   u8 *tag = 0;
11049   int ret;
11050
11051   /* Shut up coverity */
11052   memset (hwaddr, 0, sizeof (hwaddr));
11053
11054   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11055     {
11056       if (unformat (i, "socket %s", &file_name))
11057         {
11058           file_name_set = 1;
11059         }
11060       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11061         ;
11062       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
11063         use_custom_mac = 1;
11064       else if (unformat (i, "server"))
11065         is_server = 1;
11066       else if (unformat (i, "tag %s", &tag))
11067         ;
11068       else
11069         break;
11070     }
11071
11072   if (file_name_set == 0)
11073     {
11074       errmsg ("missing socket file name");
11075       return -99;
11076     }
11077
11078   if (vec_len (file_name) > 255)
11079     {
11080       errmsg ("socket file name too long");
11081       return -99;
11082     }
11083   vec_add1 (file_name, 0);
11084
11085   M (CREATE_VHOST_USER_IF, mp);
11086
11087   mp->is_server = is_server;
11088   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11089   vec_free (file_name);
11090   if (custom_dev_instance != ~0)
11091     {
11092       mp->renumber = 1;
11093       mp->custom_dev_instance = ntohl (custom_dev_instance);
11094     }
11095   mp->use_custom_mac = use_custom_mac;
11096   clib_memcpy (mp->mac_address, hwaddr, 6);
11097   if (tag)
11098     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
11099   vec_free (tag);
11100
11101   S (mp);
11102   W (ret);
11103   return ret;
11104 }
11105
11106 static int
11107 api_modify_vhost_user_if (vat_main_t * vam)
11108 {
11109   unformat_input_t *i = vam->input;
11110   vl_api_modify_vhost_user_if_t *mp;
11111   u8 *file_name;
11112   u8 is_server = 0;
11113   u8 file_name_set = 0;
11114   u32 custom_dev_instance = ~0;
11115   u8 sw_if_index_set = 0;
11116   u32 sw_if_index = (u32) ~ 0;
11117   int ret;
11118
11119   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11120     {
11121       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11122         sw_if_index_set = 1;
11123       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11124         sw_if_index_set = 1;
11125       else if (unformat (i, "socket %s", &file_name))
11126         {
11127           file_name_set = 1;
11128         }
11129       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11130         ;
11131       else if (unformat (i, "server"))
11132         is_server = 1;
11133       else
11134         break;
11135     }
11136
11137   if (sw_if_index_set == 0)
11138     {
11139       errmsg ("missing sw_if_index or interface name");
11140       return -99;
11141     }
11142
11143   if (file_name_set == 0)
11144     {
11145       errmsg ("missing socket file name");
11146       return -99;
11147     }
11148
11149   if (vec_len (file_name) > 255)
11150     {
11151       errmsg ("socket file name too long");
11152       return -99;
11153     }
11154   vec_add1 (file_name, 0);
11155
11156   M (MODIFY_VHOST_USER_IF, mp);
11157
11158   mp->sw_if_index = ntohl (sw_if_index);
11159   mp->is_server = is_server;
11160   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11161   vec_free (file_name);
11162   if (custom_dev_instance != ~0)
11163     {
11164       mp->renumber = 1;
11165       mp->custom_dev_instance = ntohl (custom_dev_instance);
11166     }
11167
11168   S (mp);
11169   W (ret);
11170   return ret;
11171 }
11172
11173 static int
11174 api_delete_vhost_user_if (vat_main_t * vam)
11175 {
11176   unformat_input_t *i = vam->input;
11177   vl_api_delete_vhost_user_if_t *mp;
11178   u32 sw_if_index = ~0;
11179   u8 sw_if_index_set = 0;
11180   int ret;
11181
11182   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11183     {
11184       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11185         sw_if_index_set = 1;
11186       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11187         sw_if_index_set = 1;
11188       else
11189         break;
11190     }
11191
11192   if (sw_if_index_set == 0)
11193     {
11194       errmsg ("missing sw_if_index or interface name");
11195       return -99;
11196     }
11197
11198
11199   M (DELETE_VHOST_USER_IF, mp);
11200
11201   mp->sw_if_index = ntohl (sw_if_index);
11202
11203   S (mp);
11204   W (ret);
11205   return ret;
11206 }
11207
11208 static void vl_api_sw_interface_vhost_user_details_t_handler
11209   (vl_api_sw_interface_vhost_user_details_t * mp)
11210 {
11211   vat_main_t *vam = &vat_main;
11212
11213   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
11214          (char *) mp->interface_name,
11215          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11216          clib_net_to_host_u64 (mp->features), mp->is_server,
11217          ntohl (mp->num_regions), (char *) mp->sock_filename);
11218   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
11219 }
11220
11221 static void vl_api_sw_interface_vhost_user_details_t_handler_json
11222   (vl_api_sw_interface_vhost_user_details_t * mp)
11223 {
11224   vat_main_t *vam = &vat_main;
11225   vat_json_node_t *node = NULL;
11226
11227   if (VAT_JSON_ARRAY != vam->json_tree.type)
11228     {
11229       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11230       vat_json_init_array (&vam->json_tree);
11231     }
11232   node = vat_json_array_add (&vam->json_tree);
11233
11234   vat_json_init_object (node);
11235   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11236   vat_json_object_add_string_copy (node, "interface_name",
11237                                    mp->interface_name);
11238   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11239                             ntohl (mp->virtio_net_hdr_sz));
11240   vat_json_object_add_uint (node, "features",
11241                             clib_net_to_host_u64 (mp->features));
11242   vat_json_object_add_uint (node, "is_server", mp->is_server);
11243   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11244   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11245   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11246 }
11247
11248 static int
11249 api_sw_interface_vhost_user_dump (vat_main_t * vam)
11250 {
11251   vl_api_sw_interface_vhost_user_dump_t *mp;
11252   vl_api_control_ping_t *mp_ping;
11253   int ret;
11254   print (vam->ofp,
11255          "Interface name           idx hdr_sz features server regions filename");
11256
11257   /* Get list of vhost-user interfaces */
11258   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
11259   S (mp);
11260
11261   /* Use a control ping for synchronization */
11262   M (CONTROL_PING, mp_ping);
11263   S (mp_ping);
11264
11265   W (ret);
11266   return ret;
11267 }
11268
11269 static int
11270 api_show_version (vat_main_t * vam)
11271 {
11272   vl_api_show_version_t *mp;
11273   int ret;
11274
11275   M (SHOW_VERSION, mp);
11276
11277   S (mp);
11278   W (ret);
11279   return ret;
11280 }
11281
11282
11283 static int
11284 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11285 {
11286   unformat_input_t *line_input = vam->input;
11287   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11288   ip4_address_t local4, remote4;
11289   ip6_address_t local6, remote6;
11290   u8 is_add = 1;
11291   u8 ipv4_set = 0, ipv6_set = 0;
11292   u8 local_set = 0;
11293   u8 remote_set = 0;
11294   u32 encap_vrf_id = 0;
11295   u32 decap_vrf_id = 0;
11296   u8 protocol = ~0;
11297   u32 vni;
11298   u8 vni_set = 0;
11299   int ret;
11300
11301   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11302     {
11303       if (unformat (line_input, "del"))
11304         is_add = 0;
11305       else if (unformat (line_input, "local %U",
11306                          unformat_ip4_address, &local4))
11307         {
11308           local_set = 1;
11309           ipv4_set = 1;
11310         }
11311       else if (unformat (line_input, "remote %U",
11312                          unformat_ip4_address, &remote4))
11313         {
11314           remote_set = 1;
11315           ipv4_set = 1;
11316         }
11317       else if (unformat (line_input, "local %U",
11318                          unformat_ip6_address, &local6))
11319         {
11320           local_set = 1;
11321           ipv6_set = 1;
11322         }
11323       else if (unformat (line_input, "remote %U",
11324                          unformat_ip6_address, &remote6))
11325         {
11326           remote_set = 1;
11327           ipv6_set = 1;
11328         }
11329       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11330         ;
11331       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11332         ;
11333       else if (unformat (line_input, "vni %d", &vni))
11334         vni_set = 1;
11335       else if (unformat (line_input, "next-ip4"))
11336         protocol = 1;
11337       else if (unformat (line_input, "next-ip6"))
11338         protocol = 2;
11339       else if (unformat (line_input, "next-ethernet"))
11340         protocol = 3;
11341       else if (unformat (line_input, "next-nsh"))
11342         protocol = 4;
11343       else
11344         {
11345           errmsg ("parse error '%U'", format_unformat_error, line_input);
11346           return -99;
11347         }
11348     }
11349
11350   if (local_set == 0)
11351     {
11352       errmsg ("tunnel local address not specified");
11353       return -99;
11354     }
11355   if (remote_set == 0)
11356     {
11357       errmsg ("tunnel remote address not specified");
11358       return -99;
11359     }
11360   if (ipv4_set && ipv6_set)
11361     {
11362       errmsg ("both IPv4 and IPv6 addresses specified");
11363       return -99;
11364     }
11365
11366   if (vni_set == 0)
11367     {
11368       errmsg ("vni not specified");
11369       return -99;
11370     }
11371
11372   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
11373
11374
11375   if (ipv6_set)
11376     {
11377       clib_memcpy (&mp->local, &local6, sizeof (local6));
11378       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11379     }
11380   else
11381     {
11382       clib_memcpy (&mp->local, &local4, sizeof (local4));
11383       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11384     }
11385
11386   mp->encap_vrf_id = ntohl (encap_vrf_id);
11387   mp->decap_vrf_id = ntohl (decap_vrf_id);
11388   mp->protocol = protocol;
11389   mp->vni = ntohl (vni);
11390   mp->is_add = is_add;
11391   mp->is_ipv6 = ipv6_set;
11392
11393   S (mp);
11394   W (ret);
11395   return ret;
11396 }
11397
11398 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11399   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11400 {
11401   vat_main_t *vam = &vat_main;
11402
11403   print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11404          ntohl (mp->sw_if_index),
11405          format_ip46_address, &(mp->local[0]),
11406          format_ip46_address, &(mp->remote[0]),
11407          ntohl (mp->vni),
11408          ntohl (mp->protocol),
11409          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11410 }
11411
11412 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11413   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11414 {
11415   vat_main_t *vam = &vat_main;
11416   vat_json_node_t *node = NULL;
11417   struct in_addr ip4;
11418   struct in6_addr ip6;
11419
11420   if (VAT_JSON_ARRAY != vam->json_tree.type)
11421     {
11422       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11423       vat_json_init_array (&vam->json_tree);
11424     }
11425   node = vat_json_array_add (&vam->json_tree);
11426
11427   vat_json_init_object (node);
11428   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11429   if (mp->is_ipv6)
11430     {
11431       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11432       vat_json_object_add_ip6 (node, "local", ip6);
11433       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11434       vat_json_object_add_ip6 (node, "remote", ip6);
11435     }
11436   else
11437     {
11438       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11439       vat_json_object_add_ip4 (node, "local", ip4);
11440       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11441       vat_json_object_add_ip4 (node, "remote", ip4);
11442     }
11443   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11444   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11445   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11446   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11447   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11448 }
11449
11450 static int
11451 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11452 {
11453   unformat_input_t *i = vam->input;
11454   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11455   vl_api_control_ping_t *mp_ping;
11456   u32 sw_if_index;
11457   u8 sw_if_index_set = 0;
11458   int ret;
11459
11460   /* Parse args required to build the message */
11461   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11462     {
11463       if (unformat (i, "sw_if_index %d", &sw_if_index))
11464         sw_if_index_set = 1;
11465       else
11466         break;
11467     }
11468
11469   if (sw_if_index_set == 0)
11470     {
11471       sw_if_index = ~0;
11472     }
11473
11474   if (!vam->json_output)
11475     {
11476       print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11477              "sw_if_index", "local", "remote", "vni",
11478              "protocol", "encap_vrf_id", "decap_vrf_id");
11479     }
11480
11481   /* Get list of vxlan-tunnel interfaces */
11482   M (VXLAN_GPE_TUNNEL_DUMP, mp);
11483
11484   mp->sw_if_index = htonl (sw_if_index);
11485
11486   S (mp);
11487
11488   /* Use a control ping for synchronization */
11489   M (CONTROL_PING, mp_ping);
11490   S (mp_ping);
11491
11492   W (ret);
11493   return ret;
11494 }
11495
11496 u8 *
11497 format_l2_fib_mac_address (u8 * s, va_list * args)
11498 {
11499   u8 *a = va_arg (*args, u8 *);
11500
11501   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11502                  a[2], a[3], a[4], a[5], a[6], a[7]);
11503 }
11504
11505 static void vl_api_l2_fib_table_entry_t_handler
11506   (vl_api_l2_fib_table_entry_t * mp)
11507 {
11508   vat_main_t *vam = &vat_main;
11509
11510   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11511          "       %d       %d     %d",
11512          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11513          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11514          mp->bvi_mac);
11515 }
11516
11517 static void vl_api_l2_fib_table_entry_t_handler_json
11518   (vl_api_l2_fib_table_entry_t * mp)
11519 {
11520   vat_main_t *vam = &vat_main;
11521   vat_json_node_t *node = NULL;
11522
11523   if (VAT_JSON_ARRAY != vam->json_tree.type)
11524     {
11525       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11526       vat_json_init_array (&vam->json_tree);
11527     }
11528   node = vat_json_array_add (&vam->json_tree);
11529
11530   vat_json_init_object (node);
11531   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11532   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11533   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11534   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11535   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11536   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11537 }
11538
11539 static int
11540 api_l2_fib_table_dump (vat_main_t * vam)
11541 {
11542   unformat_input_t *i = vam->input;
11543   vl_api_l2_fib_table_dump_t *mp;
11544   vl_api_control_ping_t *mp_ping;
11545   u32 bd_id;
11546   u8 bd_id_set = 0;
11547   int ret;
11548
11549   /* Parse args required to build the message */
11550   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11551     {
11552       if (unformat (i, "bd_id %d", &bd_id))
11553         bd_id_set = 1;
11554       else
11555         break;
11556     }
11557
11558   if (bd_id_set == 0)
11559     {
11560       errmsg ("missing bridge domain");
11561       return -99;
11562     }
11563
11564   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
11565
11566   /* Get list of l2 fib entries */
11567   M (L2_FIB_TABLE_DUMP, mp);
11568
11569   mp->bd_id = ntohl (bd_id);
11570   S (mp);
11571
11572   /* Use a control ping for synchronization */
11573   M (CONTROL_PING, mp_ping);
11574   S (mp_ping);
11575
11576   W (ret);
11577   return ret;
11578 }
11579
11580
11581 static int
11582 api_interface_name_renumber (vat_main_t * vam)
11583 {
11584   unformat_input_t *line_input = vam->input;
11585   vl_api_interface_name_renumber_t *mp;
11586   u32 sw_if_index = ~0;
11587   u32 new_show_dev_instance = ~0;
11588   int ret;
11589
11590   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11591     {
11592       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
11593                     &sw_if_index))
11594         ;
11595       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11596         ;
11597       else if (unformat (line_input, "new_show_dev_instance %d",
11598                          &new_show_dev_instance))
11599         ;
11600       else
11601         break;
11602     }
11603
11604   if (sw_if_index == ~0)
11605     {
11606       errmsg ("missing interface name or sw_if_index");
11607       return -99;
11608     }
11609
11610   if (new_show_dev_instance == ~0)
11611     {
11612       errmsg ("missing new_show_dev_instance");
11613       return -99;
11614     }
11615
11616   M (INTERFACE_NAME_RENUMBER, mp);
11617
11618   mp->sw_if_index = ntohl (sw_if_index);
11619   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11620
11621   S (mp);
11622   W (ret);
11623   return ret;
11624 }
11625
11626 static int
11627 api_want_ip4_arp_events (vat_main_t * vam)
11628 {
11629   unformat_input_t *line_input = vam->input;
11630   vl_api_want_ip4_arp_events_t *mp;
11631   ip4_address_t address;
11632   int address_set = 0;
11633   u32 enable_disable = 1;
11634   int ret;
11635
11636   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11637     {
11638       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11639         address_set = 1;
11640       else if (unformat (line_input, "del"))
11641         enable_disable = 0;
11642       else
11643         break;
11644     }
11645
11646   if (address_set == 0)
11647     {
11648       errmsg ("missing addresses");
11649       return -99;
11650     }
11651
11652   M (WANT_IP4_ARP_EVENTS, mp);
11653   mp->enable_disable = enable_disable;
11654   mp->pid = getpid ();
11655   mp->address = address.as_u32;
11656
11657   S (mp);
11658   W (ret);
11659   return ret;
11660 }
11661
11662 static int
11663 api_want_ip6_nd_events (vat_main_t * vam)
11664 {
11665   unformat_input_t *line_input = vam->input;
11666   vl_api_want_ip6_nd_events_t *mp;
11667   ip6_address_t address;
11668   int address_set = 0;
11669   u32 enable_disable = 1;
11670   int ret;
11671
11672   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11673     {
11674       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11675         address_set = 1;
11676       else if (unformat (line_input, "del"))
11677         enable_disable = 0;
11678       else
11679         break;
11680     }
11681
11682   if (address_set == 0)
11683     {
11684       errmsg ("missing addresses");
11685       return -99;
11686     }
11687
11688   M (WANT_IP6_ND_EVENTS, mp);
11689   mp->enable_disable = enable_disable;
11690   mp->pid = getpid ();
11691   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11692
11693   S (mp);
11694   W (ret);
11695   return ret;
11696 }
11697
11698 static int
11699 api_input_acl_set_interface (vat_main_t * vam)
11700 {
11701   unformat_input_t *i = vam->input;
11702   vl_api_input_acl_set_interface_t *mp;
11703   u32 sw_if_index;
11704   int sw_if_index_set;
11705   u32 ip4_table_index = ~0;
11706   u32 ip6_table_index = ~0;
11707   u32 l2_table_index = ~0;
11708   u8 is_add = 1;
11709   int ret;
11710
11711   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11712     {
11713       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11714         sw_if_index_set = 1;
11715       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11716         sw_if_index_set = 1;
11717       else if (unformat (i, "del"))
11718         is_add = 0;
11719       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11720         ;
11721       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11722         ;
11723       else if (unformat (i, "l2-table %d", &l2_table_index))
11724         ;
11725       else
11726         {
11727           clib_warning ("parse error '%U'", format_unformat_error, i);
11728           return -99;
11729         }
11730     }
11731
11732   if (sw_if_index_set == 0)
11733     {
11734       errmsg ("missing interface name or sw_if_index");
11735       return -99;
11736     }
11737
11738   M (INPUT_ACL_SET_INTERFACE, mp);
11739
11740   mp->sw_if_index = ntohl (sw_if_index);
11741   mp->ip4_table_index = ntohl (ip4_table_index);
11742   mp->ip6_table_index = ntohl (ip6_table_index);
11743   mp->l2_table_index = ntohl (l2_table_index);
11744   mp->is_add = is_add;
11745
11746   S (mp);
11747   W (ret);
11748   return ret;
11749 }
11750
11751 static int
11752 api_ip_address_dump (vat_main_t * vam)
11753 {
11754   unformat_input_t *i = vam->input;
11755   vl_api_ip_address_dump_t *mp;
11756   vl_api_control_ping_t *mp_ping;
11757   u32 sw_if_index = ~0;
11758   u8 sw_if_index_set = 0;
11759   u8 ipv4_set = 0;
11760   u8 ipv6_set = 0;
11761   int ret;
11762
11763   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11764     {
11765       if (unformat (i, "sw_if_index %d", &sw_if_index))
11766         sw_if_index_set = 1;
11767       else
11768         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11769         sw_if_index_set = 1;
11770       else if (unformat (i, "ipv4"))
11771         ipv4_set = 1;
11772       else if (unformat (i, "ipv6"))
11773         ipv6_set = 1;
11774       else
11775         break;
11776     }
11777
11778   if (ipv4_set && ipv6_set)
11779     {
11780       errmsg ("ipv4 and ipv6 flags cannot be both set");
11781       return -99;
11782     }
11783
11784   if ((!ipv4_set) && (!ipv6_set))
11785     {
11786       errmsg ("no ipv4 nor ipv6 flag set");
11787       return -99;
11788     }
11789
11790   if (sw_if_index_set == 0)
11791     {
11792       errmsg ("missing interface name or sw_if_index");
11793       return -99;
11794     }
11795
11796   vam->current_sw_if_index = sw_if_index;
11797   vam->is_ipv6 = ipv6_set;
11798
11799   M (IP_ADDRESS_DUMP, mp);
11800   mp->sw_if_index = ntohl (sw_if_index);
11801   mp->is_ipv6 = ipv6_set;
11802   S (mp);
11803
11804   /* Use a control ping for synchronization */
11805   M (CONTROL_PING, mp_ping);
11806   S (mp_ping);
11807
11808   W (ret);
11809   return ret;
11810 }
11811
11812 static int
11813 api_ip_dump (vat_main_t * vam)
11814 {
11815   vl_api_ip_dump_t *mp;
11816   vl_api_control_ping_t *mp_ping;
11817   unformat_input_t *in = vam->input;
11818   int ipv4_set = 0;
11819   int ipv6_set = 0;
11820   int is_ipv6;
11821   int i;
11822   int ret;
11823
11824   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11825     {
11826       if (unformat (in, "ipv4"))
11827         ipv4_set = 1;
11828       else if (unformat (in, "ipv6"))
11829         ipv6_set = 1;
11830       else
11831         break;
11832     }
11833
11834   if (ipv4_set && ipv6_set)
11835     {
11836       errmsg ("ipv4 and ipv6 flags cannot be both set");
11837       return -99;
11838     }
11839
11840   if ((!ipv4_set) && (!ipv6_set))
11841     {
11842       errmsg ("no ipv4 nor ipv6 flag set");
11843       return -99;
11844     }
11845
11846   is_ipv6 = ipv6_set;
11847   vam->is_ipv6 = is_ipv6;
11848
11849   /* free old data */
11850   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11851     {
11852       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11853     }
11854   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11855
11856   M (IP_DUMP, mp);
11857   mp->is_ipv6 = ipv6_set;
11858   S (mp);
11859
11860   /* Use a control ping for synchronization */
11861   M (CONTROL_PING, mp_ping);
11862   S (mp_ping);
11863
11864   W (ret);
11865   return ret;
11866 }
11867
11868 static int
11869 api_ipsec_spd_add_del (vat_main_t * vam)
11870 {
11871   unformat_input_t *i = vam->input;
11872   vl_api_ipsec_spd_add_del_t *mp;
11873   u32 spd_id = ~0;
11874   u8 is_add = 1;
11875   int ret;
11876
11877   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11878     {
11879       if (unformat (i, "spd_id %d", &spd_id))
11880         ;
11881       else if (unformat (i, "del"))
11882         is_add = 0;
11883       else
11884         {
11885           clib_warning ("parse error '%U'", format_unformat_error, i);
11886           return -99;
11887         }
11888     }
11889   if (spd_id == ~0)
11890     {
11891       errmsg ("spd_id must be set");
11892       return -99;
11893     }
11894
11895   M (IPSEC_SPD_ADD_DEL, mp);
11896
11897   mp->spd_id = ntohl (spd_id);
11898   mp->is_add = is_add;
11899
11900   S (mp);
11901   W (ret);
11902   return ret;
11903 }
11904
11905 static int
11906 api_ipsec_interface_add_del_spd (vat_main_t * vam)
11907 {
11908   unformat_input_t *i = vam->input;
11909   vl_api_ipsec_interface_add_del_spd_t *mp;
11910   u32 sw_if_index;
11911   u8 sw_if_index_set = 0;
11912   u32 spd_id = (u32) ~ 0;
11913   u8 is_add = 1;
11914   int ret;
11915
11916   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11917     {
11918       if (unformat (i, "del"))
11919         is_add = 0;
11920       else if (unformat (i, "spd_id %d", &spd_id))
11921         ;
11922       else
11923         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11924         sw_if_index_set = 1;
11925       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11926         sw_if_index_set = 1;
11927       else
11928         {
11929           clib_warning ("parse error '%U'", format_unformat_error, i);
11930           return -99;
11931         }
11932
11933     }
11934
11935   if (spd_id == (u32) ~ 0)
11936     {
11937       errmsg ("spd_id must be set");
11938       return -99;
11939     }
11940
11941   if (sw_if_index_set == 0)
11942     {
11943       errmsg ("missing interface name or sw_if_index");
11944       return -99;
11945     }
11946
11947   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
11948
11949   mp->spd_id = ntohl (spd_id);
11950   mp->sw_if_index = ntohl (sw_if_index);
11951   mp->is_add = is_add;
11952
11953   S (mp);
11954   W (ret);
11955   return ret;
11956 }
11957
11958 static int
11959 api_ipsec_spd_add_del_entry (vat_main_t * vam)
11960 {
11961   unformat_input_t *i = vam->input;
11962   vl_api_ipsec_spd_add_del_entry_t *mp;
11963   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11964   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11965   i32 priority = 0;
11966   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11967   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11968   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11969   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11970   int ret;
11971
11972   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11973   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11974   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11975   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11976   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11977   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11978
11979   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11980     {
11981       if (unformat (i, "del"))
11982         is_add = 0;
11983       if (unformat (i, "outbound"))
11984         is_outbound = 1;
11985       if (unformat (i, "inbound"))
11986         is_outbound = 0;
11987       else if (unformat (i, "spd_id %d", &spd_id))
11988         ;
11989       else if (unformat (i, "sa_id %d", &sa_id))
11990         ;
11991       else if (unformat (i, "priority %d", &priority))
11992         ;
11993       else if (unformat (i, "protocol %d", &protocol))
11994         ;
11995       else if (unformat (i, "lport_start %d", &lport_start))
11996         ;
11997       else if (unformat (i, "lport_stop %d", &lport_stop))
11998         ;
11999       else if (unformat (i, "rport_start %d", &rport_start))
12000         ;
12001       else if (unformat (i, "rport_stop %d", &rport_stop))
12002         ;
12003       else
12004         if (unformat
12005             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
12006         {
12007           is_ipv6 = 0;
12008           is_ip_any = 0;
12009         }
12010       else
12011         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
12012         {
12013           is_ipv6 = 0;
12014           is_ip_any = 0;
12015         }
12016       else
12017         if (unformat
12018             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
12019         {
12020           is_ipv6 = 0;
12021           is_ip_any = 0;
12022         }
12023       else
12024         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
12025         {
12026           is_ipv6 = 0;
12027           is_ip_any = 0;
12028         }
12029       else
12030         if (unformat
12031             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
12032         {
12033           is_ipv6 = 1;
12034           is_ip_any = 0;
12035         }
12036       else
12037         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
12038         {
12039           is_ipv6 = 1;
12040           is_ip_any = 0;
12041         }
12042       else
12043         if (unformat
12044             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
12045         {
12046           is_ipv6 = 1;
12047           is_ip_any = 0;
12048         }
12049       else
12050         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
12051         {
12052           is_ipv6 = 1;
12053           is_ip_any = 0;
12054         }
12055       else
12056         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
12057         {
12058           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
12059             {
12060               clib_warning ("unsupported action: 'resolve'");
12061               return -99;
12062             }
12063         }
12064       else
12065         {
12066           clib_warning ("parse error '%U'", format_unformat_error, i);
12067           return -99;
12068         }
12069
12070     }
12071
12072   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
12073
12074   mp->spd_id = ntohl (spd_id);
12075   mp->priority = ntohl (priority);
12076   mp->is_outbound = is_outbound;
12077
12078   mp->is_ipv6 = is_ipv6;
12079   if (is_ipv6 || is_ip_any)
12080     {
12081       clib_memcpy (mp->remote_address_start, &raddr6_start,
12082                    sizeof (ip6_address_t));
12083       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
12084                    sizeof (ip6_address_t));
12085       clib_memcpy (mp->local_address_start, &laddr6_start,
12086                    sizeof (ip6_address_t));
12087       clib_memcpy (mp->local_address_stop, &laddr6_stop,
12088                    sizeof (ip6_address_t));
12089     }
12090   else
12091     {
12092       clib_memcpy (mp->remote_address_start, &raddr4_start,
12093                    sizeof (ip4_address_t));
12094       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
12095                    sizeof (ip4_address_t));
12096       clib_memcpy (mp->local_address_start, &laddr4_start,
12097                    sizeof (ip4_address_t));
12098       clib_memcpy (mp->local_address_stop, &laddr4_stop,
12099                    sizeof (ip4_address_t));
12100     }
12101   mp->protocol = (u8) protocol;
12102   mp->local_port_start = ntohs ((u16) lport_start);
12103   mp->local_port_stop = ntohs ((u16) lport_stop);
12104   mp->remote_port_start = ntohs ((u16) rport_start);
12105   mp->remote_port_stop = ntohs ((u16) rport_stop);
12106   mp->policy = (u8) policy;
12107   mp->sa_id = ntohl (sa_id);
12108   mp->is_add = is_add;
12109   mp->is_ip_any = is_ip_any;
12110   S (mp);
12111   W (ret);
12112   return ret;
12113 }
12114
12115 static int
12116 api_ipsec_sad_add_del_entry (vat_main_t * vam)
12117 {
12118   unformat_input_t *i = vam->input;
12119   vl_api_ipsec_sad_add_del_entry_t *mp;
12120   u32 sad_id = 0, spi = 0;
12121   u8 *ck = 0, *ik = 0;
12122   u8 is_add = 1;
12123
12124   u8 protocol = IPSEC_PROTOCOL_AH;
12125   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
12126   u32 crypto_alg = 0, integ_alg = 0;
12127   ip4_address_t tun_src4;
12128   ip4_address_t tun_dst4;
12129   ip6_address_t tun_src6;
12130   ip6_address_t tun_dst6;
12131   int ret;
12132
12133   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12134     {
12135       if (unformat (i, "del"))
12136         is_add = 0;
12137       else if (unformat (i, "sad_id %d", &sad_id))
12138         ;
12139       else if (unformat (i, "spi %d", &spi))
12140         ;
12141       else if (unformat (i, "esp"))
12142         protocol = IPSEC_PROTOCOL_ESP;
12143       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
12144         {
12145           is_tunnel = 1;
12146           is_tunnel_ipv6 = 0;
12147         }
12148       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
12149         {
12150           is_tunnel = 1;
12151           is_tunnel_ipv6 = 0;
12152         }
12153       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
12154         {
12155           is_tunnel = 1;
12156           is_tunnel_ipv6 = 1;
12157         }
12158       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
12159         {
12160           is_tunnel = 1;
12161           is_tunnel_ipv6 = 1;
12162         }
12163       else
12164         if (unformat
12165             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12166         {
12167           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12168               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12169             {
12170               clib_warning ("unsupported crypto-alg: '%U'",
12171                             format_ipsec_crypto_alg, crypto_alg);
12172               return -99;
12173             }
12174         }
12175       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12176         ;
12177       else
12178         if (unformat
12179             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12180         {
12181           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12182               integ_alg >= IPSEC_INTEG_N_ALG)
12183             {
12184               clib_warning ("unsupported integ-alg: '%U'",
12185                             format_ipsec_integ_alg, integ_alg);
12186               return -99;
12187             }
12188         }
12189       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12190         ;
12191       else
12192         {
12193           clib_warning ("parse error '%U'", format_unformat_error, i);
12194           return -99;
12195         }
12196
12197     }
12198
12199   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
12200
12201   mp->sad_id = ntohl (sad_id);
12202   mp->is_add = is_add;
12203   mp->protocol = protocol;
12204   mp->spi = ntohl (spi);
12205   mp->is_tunnel = is_tunnel;
12206   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12207   mp->crypto_algorithm = crypto_alg;
12208   mp->integrity_algorithm = integ_alg;
12209   mp->crypto_key_length = vec_len (ck);
12210   mp->integrity_key_length = vec_len (ik);
12211
12212   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12213     mp->crypto_key_length = sizeof (mp->crypto_key);
12214
12215   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12216     mp->integrity_key_length = sizeof (mp->integrity_key);
12217
12218   if (ck)
12219     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12220   if (ik)
12221     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12222
12223   if (is_tunnel)
12224     {
12225       if (is_tunnel_ipv6)
12226         {
12227           clib_memcpy (mp->tunnel_src_address, &tun_src6,
12228                        sizeof (ip6_address_t));
12229           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12230                        sizeof (ip6_address_t));
12231         }
12232       else
12233         {
12234           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12235                        sizeof (ip4_address_t));
12236           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12237                        sizeof (ip4_address_t));
12238         }
12239     }
12240
12241   S (mp);
12242   W (ret);
12243   return ret;
12244 }
12245
12246 static int
12247 api_ipsec_sa_set_key (vat_main_t * vam)
12248 {
12249   unformat_input_t *i = vam->input;
12250   vl_api_ipsec_sa_set_key_t *mp;
12251   u32 sa_id;
12252   u8 *ck = 0, *ik = 0;
12253   int ret;
12254
12255   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12256     {
12257       if (unformat (i, "sa_id %d", &sa_id))
12258         ;
12259       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12260         ;
12261       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12262         ;
12263       else
12264         {
12265           clib_warning ("parse error '%U'", format_unformat_error, i);
12266           return -99;
12267         }
12268     }
12269
12270   M (IPSEC_SA_SET_KEY, mp);
12271
12272   mp->sa_id = ntohl (sa_id);
12273   mp->crypto_key_length = vec_len (ck);
12274   mp->integrity_key_length = vec_len (ik);
12275
12276   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12277     mp->crypto_key_length = sizeof (mp->crypto_key);
12278
12279   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12280     mp->integrity_key_length = sizeof (mp->integrity_key);
12281
12282   if (ck)
12283     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12284   if (ik)
12285     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12286
12287   S (mp);
12288   W (ret);
12289   return ret;
12290 }
12291
12292 static int
12293 api_ikev2_profile_add_del (vat_main_t * vam)
12294 {
12295   unformat_input_t *i = vam->input;
12296   vl_api_ikev2_profile_add_del_t *mp;
12297   u8 is_add = 1;
12298   u8 *name = 0;
12299   int ret;
12300
12301   const char *valid_chars = "a-zA-Z0-9_";
12302
12303   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12304     {
12305       if (unformat (i, "del"))
12306         is_add = 0;
12307       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12308         vec_add1 (name, 0);
12309       else
12310         {
12311           errmsg ("parse error '%U'", format_unformat_error, i);
12312           return -99;
12313         }
12314     }
12315
12316   if (!vec_len (name))
12317     {
12318       errmsg ("profile name must be specified");
12319       return -99;
12320     }
12321
12322   if (vec_len (name) > 64)
12323     {
12324       errmsg ("profile name too long");
12325       return -99;
12326     }
12327
12328   M (IKEV2_PROFILE_ADD_DEL, mp);
12329
12330   clib_memcpy (mp->name, name, vec_len (name));
12331   mp->is_add = is_add;
12332   vec_free (name);
12333
12334   S (mp);
12335   W (ret);
12336   return ret;
12337 }
12338
12339 static int
12340 api_ikev2_profile_set_auth (vat_main_t * vam)
12341 {
12342   unformat_input_t *i = vam->input;
12343   vl_api_ikev2_profile_set_auth_t *mp;
12344   u8 *name = 0;
12345   u8 *data = 0;
12346   u32 auth_method = 0;
12347   u8 is_hex = 0;
12348   int ret;
12349
12350   const char *valid_chars = "a-zA-Z0-9_";
12351
12352   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12353     {
12354       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12355         vec_add1 (name, 0);
12356       else if (unformat (i, "auth_method %U",
12357                          unformat_ikev2_auth_method, &auth_method))
12358         ;
12359       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12360         is_hex = 1;
12361       else if (unformat (i, "auth_data %v", &data))
12362         ;
12363       else
12364         {
12365           errmsg ("parse error '%U'", format_unformat_error, i);
12366           return -99;
12367         }
12368     }
12369
12370   if (!vec_len (name))
12371     {
12372       errmsg ("profile name must be specified");
12373       return -99;
12374     }
12375
12376   if (vec_len (name) > 64)
12377     {
12378       errmsg ("profile name too long");
12379       return -99;
12380     }
12381
12382   if (!vec_len (data))
12383     {
12384       errmsg ("auth_data must be specified");
12385       return -99;
12386     }
12387
12388   if (!auth_method)
12389     {
12390       errmsg ("auth_method must be specified");
12391       return -99;
12392     }
12393
12394   M (IKEV2_PROFILE_SET_AUTH, mp);
12395
12396   mp->is_hex = is_hex;
12397   mp->auth_method = (u8) auth_method;
12398   mp->data_len = vec_len (data);
12399   clib_memcpy (mp->name, name, vec_len (name));
12400   clib_memcpy (mp->data, data, vec_len (data));
12401   vec_free (name);
12402   vec_free (data);
12403
12404   S (mp);
12405   W (ret);
12406   return ret;
12407 }
12408
12409 static int
12410 api_ikev2_profile_set_id (vat_main_t * vam)
12411 {
12412   unformat_input_t *i = vam->input;
12413   vl_api_ikev2_profile_set_id_t *mp;
12414   u8 *name = 0;
12415   u8 *data = 0;
12416   u8 is_local = 0;
12417   u32 id_type = 0;
12418   ip4_address_t ip4;
12419   int ret;
12420
12421   const char *valid_chars = "a-zA-Z0-9_";
12422
12423   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12424     {
12425       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12426         vec_add1 (name, 0);
12427       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12428         ;
12429       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12430         {
12431           data = vec_new (u8, 4);
12432           clib_memcpy (data, ip4.as_u8, 4);
12433         }
12434       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12435         ;
12436       else if (unformat (i, "id_data %v", &data))
12437         ;
12438       else if (unformat (i, "local"))
12439         is_local = 1;
12440       else if (unformat (i, "remote"))
12441         is_local = 0;
12442       else
12443         {
12444           errmsg ("parse error '%U'", format_unformat_error, i);
12445           return -99;
12446         }
12447     }
12448
12449   if (!vec_len (name))
12450     {
12451       errmsg ("profile name must be specified");
12452       return -99;
12453     }
12454
12455   if (vec_len (name) > 64)
12456     {
12457       errmsg ("profile name too long");
12458       return -99;
12459     }
12460
12461   if (!vec_len (data))
12462     {
12463       errmsg ("id_data must be specified");
12464       return -99;
12465     }
12466
12467   if (!id_type)
12468     {
12469       errmsg ("id_type must be specified");
12470       return -99;
12471     }
12472
12473   M (IKEV2_PROFILE_SET_ID, mp);
12474
12475   mp->is_local = is_local;
12476   mp->id_type = (u8) id_type;
12477   mp->data_len = vec_len (data);
12478   clib_memcpy (mp->name, name, vec_len (name));
12479   clib_memcpy (mp->data, data, vec_len (data));
12480   vec_free (name);
12481   vec_free (data);
12482
12483   S (mp);
12484   W (ret);
12485   return ret;
12486 }
12487
12488 static int
12489 api_ikev2_profile_set_ts (vat_main_t * vam)
12490 {
12491   unformat_input_t *i = vam->input;
12492   vl_api_ikev2_profile_set_ts_t *mp;
12493   u8 *name = 0;
12494   u8 is_local = 0;
12495   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12496   ip4_address_t start_addr, end_addr;
12497
12498   const char *valid_chars = "a-zA-Z0-9_";
12499   int ret;
12500
12501   start_addr.as_u32 = 0;
12502   end_addr.as_u32 = (u32) ~ 0;
12503
12504   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12505     {
12506       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12507         vec_add1 (name, 0);
12508       else if (unformat (i, "protocol %d", &proto))
12509         ;
12510       else if (unformat (i, "start_port %d", &start_port))
12511         ;
12512       else if (unformat (i, "end_port %d", &end_port))
12513         ;
12514       else
12515         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12516         ;
12517       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12518         ;
12519       else if (unformat (i, "local"))
12520         is_local = 1;
12521       else if (unformat (i, "remote"))
12522         is_local = 0;
12523       else
12524         {
12525           errmsg ("parse error '%U'", format_unformat_error, i);
12526           return -99;
12527         }
12528     }
12529
12530   if (!vec_len (name))
12531     {
12532       errmsg ("profile name must be specified");
12533       return -99;
12534     }
12535
12536   if (vec_len (name) > 64)
12537     {
12538       errmsg ("profile name too long");
12539       return -99;
12540     }
12541
12542   M (IKEV2_PROFILE_SET_TS, mp);
12543
12544   mp->is_local = is_local;
12545   mp->proto = (u8) proto;
12546   mp->start_port = (u16) start_port;
12547   mp->end_port = (u16) end_port;
12548   mp->start_addr = start_addr.as_u32;
12549   mp->end_addr = end_addr.as_u32;
12550   clib_memcpy (mp->name, name, vec_len (name));
12551   vec_free (name);
12552
12553   S (mp);
12554   W (ret);
12555   return ret;
12556 }
12557
12558 static int
12559 api_ikev2_set_local_key (vat_main_t * vam)
12560 {
12561   unformat_input_t *i = vam->input;
12562   vl_api_ikev2_set_local_key_t *mp;
12563   u8 *file = 0;
12564   int ret;
12565
12566   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12567     {
12568       if (unformat (i, "file %v", &file))
12569         vec_add1 (file, 0);
12570       else
12571         {
12572           errmsg ("parse error '%U'", format_unformat_error, i);
12573           return -99;
12574         }
12575     }
12576
12577   if (!vec_len (file))
12578     {
12579       errmsg ("RSA key file must be specified");
12580       return -99;
12581     }
12582
12583   if (vec_len (file) > 256)
12584     {
12585       errmsg ("file name too long");
12586       return -99;
12587     }
12588
12589   M (IKEV2_SET_LOCAL_KEY, mp);
12590
12591   clib_memcpy (mp->key_file, file, vec_len (file));
12592   vec_free (file);
12593
12594   S (mp);
12595   W (ret);
12596   return ret;
12597 }
12598
12599 static int
12600 api_ikev2_set_responder (vat_main_t * vam)
12601 {
12602   unformat_input_t *i = vam->input;
12603   vl_api_ikev2_set_responder_t *mp;
12604   int ret;
12605   u8 *name = 0;
12606   u32 sw_if_index = ~0;
12607   ip4_address_t address;
12608
12609   const char *valid_chars = "a-zA-Z0-9_";
12610
12611   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12612     {
12613       if (unformat
12614           (i, "%U interface %d address %U", unformat_token, valid_chars,
12615            &name, &sw_if_index, unformat_ip4_address, &address))
12616         vec_add1 (name, 0);
12617       else
12618         {
12619           errmsg ("parse error '%U'", format_unformat_error, i);
12620           return -99;
12621         }
12622     }
12623
12624   if (!vec_len (name))
12625     {
12626       errmsg ("profile name must be specified");
12627       return -99;
12628     }
12629
12630   if (vec_len (name) > 64)
12631     {
12632       errmsg ("profile name too long");
12633       return -99;
12634     }
12635
12636   M (IKEV2_SET_RESPONDER, mp);
12637
12638   clib_memcpy (mp->name, name, vec_len (name));
12639   vec_free (name);
12640
12641   mp->sw_if_index = sw_if_index;
12642   clib_memcpy (mp->address, &address, sizeof (address));
12643
12644   S (mp);
12645   W (ret);
12646   return ret;
12647 }
12648
12649 static int
12650 api_ikev2_set_ike_transforms (vat_main_t * vam)
12651 {
12652   unformat_input_t *i = vam->input;
12653   vl_api_ikev2_set_ike_transforms_t *mp;
12654   int ret;
12655   u8 *name = 0;
12656   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
12657
12658   const char *valid_chars = "a-zA-Z0-9_";
12659
12660   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12661     {
12662       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
12663                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
12664         vec_add1 (name, 0);
12665       else
12666         {
12667           errmsg ("parse error '%U'", format_unformat_error, i);
12668           return -99;
12669         }
12670     }
12671
12672   if (!vec_len (name))
12673     {
12674       errmsg ("profile name must be specified");
12675       return -99;
12676     }
12677
12678   if (vec_len (name) > 64)
12679     {
12680       errmsg ("profile name too long");
12681       return -99;
12682     }
12683
12684   M (IKEV2_SET_IKE_TRANSFORMS, mp);
12685
12686   clib_memcpy (mp->name, name, vec_len (name));
12687   vec_free (name);
12688   mp->crypto_alg = crypto_alg;
12689   mp->crypto_key_size = crypto_key_size;
12690   mp->integ_alg = integ_alg;
12691   mp->dh_group = dh_group;
12692
12693   S (mp);
12694   W (ret);
12695   return ret;
12696 }
12697
12698
12699 static int
12700 api_ikev2_set_esp_transforms (vat_main_t * vam)
12701 {
12702   unformat_input_t *i = vam->input;
12703   vl_api_ikev2_set_esp_transforms_t *mp;
12704   int ret;
12705   u8 *name = 0;
12706   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
12707
12708   const char *valid_chars = "a-zA-Z0-9_";
12709
12710   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12711     {
12712       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
12713                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
12714         vec_add1 (name, 0);
12715       else
12716         {
12717           errmsg ("parse error '%U'", format_unformat_error, i);
12718           return -99;
12719         }
12720     }
12721
12722   if (!vec_len (name))
12723     {
12724       errmsg ("profile name must be specified");
12725       return -99;
12726     }
12727
12728   if (vec_len (name) > 64)
12729     {
12730       errmsg ("profile name too long");
12731       return -99;
12732     }
12733
12734   M (IKEV2_SET_ESP_TRANSFORMS, mp);
12735
12736   clib_memcpy (mp->name, name, vec_len (name));
12737   vec_free (name);
12738   mp->crypto_alg = crypto_alg;
12739   mp->crypto_key_size = crypto_key_size;
12740   mp->integ_alg = integ_alg;
12741   mp->dh_group = dh_group;
12742
12743   S (mp);
12744   W (ret);
12745   return ret;
12746 }
12747
12748 static int
12749 api_ikev2_set_sa_lifetime (vat_main_t * vam)
12750 {
12751   unformat_input_t *i = vam->input;
12752   vl_api_ikev2_set_sa_lifetime_t *mp;
12753   int ret;
12754   u8 *name = 0;
12755   u64 lifetime, lifetime_maxdata;
12756   u32 lifetime_jitter, handover;
12757
12758   const char *valid_chars = "a-zA-Z0-9_";
12759
12760   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12761     {
12762       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
12763                     &lifetime, &lifetime_jitter, &handover,
12764                     &lifetime_maxdata))
12765         vec_add1 (name, 0);
12766       else
12767         {
12768           errmsg ("parse error '%U'", format_unformat_error, i);
12769           return -99;
12770         }
12771     }
12772
12773   if (!vec_len (name))
12774     {
12775       errmsg ("profile name must be specified");
12776       return -99;
12777     }
12778
12779   if (vec_len (name) > 64)
12780     {
12781       errmsg ("profile name too long");
12782       return -99;
12783     }
12784
12785   M (IKEV2_SET_SA_LIFETIME, mp);
12786
12787   clib_memcpy (mp->name, name, vec_len (name));
12788   vec_free (name);
12789   mp->lifetime = lifetime;
12790   mp->lifetime_jitter = lifetime_jitter;
12791   mp->handover = handover;
12792   mp->lifetime_maxdata = lifetime_maxdata;
12793
12794   S (mp);
12795   W (ret);
12796   return ret;
12797 }
12798
12799 static int
12800 api_ikev2_initiate_sa_init (vat_main_t * vam)
12801 {
12802   unformat_input_t *i = vam->input;
12803   vl_api_ikev2_initiate_sa_init_t *mp;
12804   int ret;
12805   u8 *name = 0;
12806
12807   const char *valid_chars = "a-zA-Z0-9_";
12808
12809   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12810     {
12811       if (unformat (i, "%U", unformat_token, valid_chars, &name))
12812         vec_add1 (name, 0);
12813       else
12814         {
12815           errmsg ("parse error '%U'", format_unformat_error, i);
12816           return -99;
12817         }
12818     }
12819
12820   if (!vec_len (name))
12821     {
12822       errmsg ("profile name must be specified");
12823       return -99;
12824     }
12825
12826   if (vec_len (name) > 64)
12827     {
12828       errmsg ("profile name too long");
12829       return -99;
12830     }
12831
12832   M (IKEV2_INITIATE_SA_INIT, mp);
12833
12834   clib_memcpy (mp->name, name, vec_len (name));
12835   vec_free (name);
12836
12837   S (mp);
12838   W (ret);
12839   return ret;
12840 }
12841
12842 static int
12843 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
12844 {
12845   unformat_input_t *i = vam->input;
12846   vl_api_ikev2_initiate_del_ike_sa_t *mp;
12847   int ret;
12848   u64 ispi;
12849
12850
12851   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12852     {
12853       if (unformat (i, "%lx", &ispi))
12854         ;
12855       else
12856         {
12857           errmsg ("parse error '%U'", format_unformat_error, i);
12858           return -99;
12859         }
12860     }
12861
12862   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
12863
12864   mp->ispi = ispi;
12865
12866   S (mp);
12867   W (ret);
12868   return ret;
12869 }
12870
12871 static int
12872 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
12873 {
12874   unformat_input_t *i = vam->input;
12875   vl_api_ikev2_initiate_del_child_sa_t *mp;
12876   int ret;
12877   u32 ispi;
12878
12879
12880   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12881     {
12882       if (unformat (i, "%x", &ispi))
12883         ;
12884       else
12885         {
12886           errmsg ("parse error '%U'", format_unformat_error, i);
12887           return -99;
12888         }
12889     }
12890
12891   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
12892
12893   mp->ispi = ispi;
12894
12895   S (mp);
12896   W (ret);
12897   return ret;
12898 }
12899
12900 static int
12901 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
12902 {
12903   unformat_input_t *i = vam->input;
12904   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
12905   int ret;
12906   u32 ispi;
12907
12908
12909   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12910     {
12911       if (unformat (i, "%x", &ispi))
12912         ;
12913       else
12914         {
12915           errmsg ("parse error '%U'", format_unformat_error, i);
12916           return -99;
12917         }
12918     }
12919
12920   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
12921
12922   mp->ispi = ispi;
12923
12924   S (mp);
12925   W (ret);
12926   return ret;
12927 }
12928
12929 /*
12930  * MAP
12931  */
12932 static int
12933 api_map_add_domain (vat_main_t * vam)
12934 {
12935   unformat_input_t *i = vam->input;
12936   vl_api_map_add_domain_t *mp;
12937
12938   ip4_address_t ip4_prefix;
12939   ip6_address_t ip6_prefix;
12940   ip6_address_t ip6_src;
12941   u32 num_m_args = 0;
12942   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12943     0, psid_length = 0;
12944   u8 is_translation = 0;
12945   u32 mtu = 0;
12946   u32 ip6_src_len = 128;
12947   int ret;
12948
12949   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12950     {
12951       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12952                     &ip4_prefix, &ip4_prefix_len))
12953         num_m_args++;
12954       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12955                          &ip6_prefix, &ip6_prefix_len))
12956         num_m_args++;
12957       else
12958         if (unformat
12959             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12960              &ip6_src_len))
12961         num_m_args++;
12962       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12963         num_m_args++;
12964       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12965         num_m_args++;
12966       else if (unformat (i, "psid-offset %d", &psid_offset))
12967         num_m_args++;
12968       else if (unformat (i, "psid-len %d", &psid_length))
12969         num_m_args++;
12970       else if (unformat (i, "mtu %d", &mtu))
12971         num_m_args++;
12972       else if (unformat (i, "map-t"))
12973         is_translation = 1;
12974       else
12975         {
12976           clib_warning ("parse error '%U'", format_unformat_error, i);
12977           return -99;
12978         }
12979     }
12980
12981   if (num_m_args < 3)
12982     {
12983       errmsg ("mandatory argument(s) missing");
12984       return -99;
12985     }
12986
12987   /* Construct the API message */
12988   M (MAP_ADD_DOMAIN, mp);
12989
12990   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12991   mp->ip4_prefix_len = ip4_prefix_len;
12992
12993   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12994   mp->ip6_prefix_len = ip6_prefix_len;
12995
12996   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12997   mp->ip6_src_prefix_len = ip6_src_len;
12998
12999   mp->ea_bits_len = ea_bits_len;
13000   mp->psid_offset = psid_offset;
13001   mp->psid_length = psid_length;
13002   mp->is_translation = is_translation;
13003   mp->mtu = htons (mtu);
13004
13005   /* send it... */
13006   S (mp);
13007
13008   /* Wait for a reply, return good/bad news  */
13009   W (ret);
13010   return ret;
13011 }
13012
13013 static int
13014 api_map_del_domain (vat_main_t * vam)
13015 {
13016   unformat_input_t *i = vam->input;
13017   vl_api_map_del_domain_t *mp;
13018
13019   u32 num_m_args = 0;
13020   u32 index;
13021   int ret;
13022
13023   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13024     {
13025       if (unformat (i, "index %d", &index))
13026         num_m_args++;
13027       else
13028         {
13029           clib_warning ("parse error '%U'", format_unformat_error, i);
13030           return -99;
13031         }
13032     }
13033
13034   if (num_m_args != 1)
13035     {
13036       errmsg ("mandatory argument(s) missing");
13037       return -99;
13038     }
13039
13040   /* Construct the API message */
13041   M (MAP_DEL_DOMAIN, mp);
13042
13043   mp->index = ntohl (index);
13044
13045   /* send it... */
13046   S (mp);
13047
13048   /* Wait for a reply, return good/bad news  */
13049   W (ret);
13050   return ret;
13051 }
13052
13053 static int
13054 api_map_add_del_rule (vat_main_t * vam)
13055 {
13056   unformat_input_t *i = vam->input;
13057   vl_api_map_add_del_rule_t *mp;
13058   u8 is_add = 1;
13059   ip6_address_t ip6_dst;
13060   u32 num_m_args = 0, index, psid = 0;
13061   int ret;
13062
13063   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13064     {
13065       if (unformat (i, "index %d", &index))
13066         num_m_args++;
13067       else if (unformat (i, "psid %d", &psid))
13068         num_m_args++;
13069       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
13070         num_m_args++;
13071       else if (unformat (i, "del"))
13072         {
13073           is_add = 0;
13074         }
13075       else
13076         {
13077           clib_warning ("parse error '%U'", format_unformat_error, i);
13078           return -99;
13079         }
13080     }
13081
13082   /* Construct the API message */
13083   M (MAP_ADD_DEL_RULE, mp);
13084
13085   mp->index = ntohl (index);
13086   mp->is_add = is_add;
13087   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
13088   mp->psid = ntohs (psid);
13089
13090   /* send it... */
13091   S (mp);
13092
13093   /* Wait for a reply, return good/bad news  */
13094   W (ret);
13095   return ret;
13096 }
13097
13098 static int
13099 api_map_domain_dump (vat_main_t * vam)
13100 {
13101   vl_api_map_domain_dump_t *mp;
13102   vl_api_control_ping_t *mp_ping;
13103   int ret;
13104
13105   /* Construct the API message */
13106   M (MAP_DOMAIN_DUMP, mp);
13107
13108   /* send it... */
13109   S (mp);
13110
13111   /* Use a control ping for synchronization */
13112   M (CONTROL_PING, mp_ping);
13113   S (mp_ping);
13114
13115   W (ret);
13116   return ret;
13117 }
13118
13119 static int
13120 api_map_rule_dump (vat_main_t * vam)
13121 {
13122   unformat_input_t *i = vam->input;
13123   vl_api_map_rule_dump_t *mp;
13124   vl_api_control_ping_t *mp_ping;
13125   u32 domain_index = ~0;
13126   int ret;
13127
13128   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13129     {
13130       if (unformat (i, "index %u", &domain_index))
13131         ;
13132       else
13133         break;
13134     }
13135
13136   if (domain_index == ~0)
13137     {
13138       clib_warning ("parse error: domain index expected");
13139       return -99;
13140     }
13141
13142   /* Construct the API message */
13143   M (MAP_RULE_DUMP, mp);
13144
13145   mp->domain_index = htonl (domain_index);
13146
13147   /* send it... */
13148   S (mp);
13149
13150   /* Use a control ping for synchronization */
13151   M (CONTROL_PING, mp_ping);
13152   S (mp_ping);
13153
13154   W (ret);
13155   return ret;
13156 }
13157
13158 static void vl_api_map_add_domain_reply_t_handler
13159   (vl_api_map_add_domain_reply_t * mp)
13160 {
13161   vat_main_t *vam = &vat_main;
13162   i32 retval = ntohl (mp->retval);
13163
13164   if (vam->async_mode)
13165     {
13166       vam->async_errors += (retval < 0);
13167     }
13168   else
13169     {
13170       vam->retval = retval;
13171       vam->result_ready = 1;
13172     }
13173 }
13174
13175 static void vl_api_map_add_domain_reply_t_handler_json
13176   (vl_api_map_add_domain_reply_t * mp)
13177 {
13178   vat_main_t *vam = &vat_main;
13179   vat_json_node_t node;
13180
13181   vat_json_init_object (&node);
13182   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
13183   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
13184
13185   vat_json_print (vam->ofp, &node);
13186   vat_json_free (&node);
13187
13188   vam->retval = ntohl (mp->retval);
13189   vam->result_ready = 1;
13190 }
13191
13192 static int
13193 api_get_first_msg_id (vat_main_t * vam)
13194 {
13195   vl_api_get_first_msg_id_t *mp;
13196   unformat_input_t *i = vam->input;
13197   u8 *name;
13198   u8 name_set = 0;
13199   int ret;
13200
13201   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13202     {
13203       if (unformat (i, "client %s", &name))
13204         name_set = 1;
13205       else
13206         break;
13207     }
13208
13209   if (name_set == 0)
13210     {
13211       errmsg ("missing client name");
13212       return -99;
13213     }
13214   vec_add1 (name, 0);
13215
13216   if (vec_len (name) > 63)
13217     {
13218       errmsg ("client name too long");
13219       return -99;
13220     }
13221
13222   M (GET_FIRST_MSG_ID, mp);
13223   clib_memcpy (mp->name, name, vec_len (name));
13224   S (mp);
13225   W (ret);
13226   return ret;
13227 }
13228
13229 static int
13230 api_cop_interface_enable_disable (vat_main_t * vam)
13231 {
13232   unformat_input_t *line_input = vam->input;
13233   vl_api_cop_interface_enable_disable_t *mp;
13234   u32 sw_if_index = ~0;
13235   u8 enable_disable = 1;
13236   int ret;
13237
13238   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13239     {
13240       if (unformat (line_input, "disable"))
13241         enable_disable = 0;
13242       if (unformat (line_input, "enable"))
13243         enable_disable = 1;
13244       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13245                          vam, &sw_if_index))
13246         ;
13247       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13248         ;
13249       else
13250         break;
13251     }
13252
13253   if (sw_if_index == ~0)
13254     {
13255       errmsg ("missing interface name or sw_if_index");
13256       return -99;
13257     }
13258
13259   /* Construct the API message */
13260   M (COP_INTERFACE_ENABLE_DISABLE, mp);
13261   mp->sw_if_index = ntohl (sw_if_index);
13262   mp->enable_disable = enable_disable;
13263
13264   /* send it... */
13265   S (mp);
13266   /* Wait for the reply */
13267   W (ret);
13268   return ret;
13269 }
13270
13271 static int
13272 api_cop_whitelist_enable_disable (vat_main_t * vam)
13273 {
13274   unformat_input_t *line_input = vam->input;
13275   vl_api_cop_whitelist_enable_disable_t *mp;
13276   u32 sw_if_index = ~0;
13277   u8 ip4 = 0, ip6 = 0, default_cop = 0;
13278   u32 fib_id = 0;
13279   int ret;
13280
13281   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13282     {
13283       if (unformat (line_input, "ip4"))
13284         ip4 = 1;
13285       else if (unformat (line_input, "ip6"))
13286         ip6 = 1;
13287       else if (unformat (line_input, "default"))
13288         default_cop = 1;
13289       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13290                          vam, &sw_if_index))
13291         ;
13292       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13293         ;
13294       else if (unformat (line_input, "fib-id %d", &fib_id))
13295         ;
13296       else
13297         break;
13298     }
13299
13300   if (sw_if_index == ~0)
13301     {
13302       errmsg ("missing interface name or sw_if_index");
13303       return -99;
13304     }
13305
13306   /* Construct the API message */
13307   M (COP_WHITELIST_ENABLE_DISABLE, mp);
13308   mp->sw_if_index = ntohl (sw_if_index);
13309   mp->fib_id = ntohl (fib_id);
13310   mp->ip4 = ip4;
13311   mp->ip6 = ip6;
13312   mp->default_cop = default_cop;
13313
13314   /* send it... */
13315   S (mp);
13316   /* Wait for the reply */
13317   W (ret);
13318   return ret;
13319 }
13320
13321 static int
13322 api_get_node_graph (vat_main_t * vam)
13323 {
13324   vl_api_get_node_graph_t *mp;
13325   int ret;
13326
13327   M (GET_NODE_GRAPH, mp);
13328
13329   /* send it... */
13330   S (mp);
13331   /* Wait for the reply */
13332   W (ret);
13333   return ret;
13334 }
13335
13336 /* *INDENT-OFF* */
13337 /** Used for parsing LISP eids */
13338 typedef CLIB_PACKED(struct{
13339   u8 addr[16];   /**< eid address */
13340   u32 len;       /**< prefix length if IP */
13341   u8 type;      /**< type of eid */
13342 }) lisp_eid_vat_t;
13343 /* *INDENT-ON* */
13344
13345 static uword
13346 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
13347 {
13348   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
13349
13350   memset (a, 0, sizeof (a[0]));
13351
13352   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
13353     {
13354       a->type = 0;              /* ipv4 type */
13355     }
13356   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
13357     {
13358       a->type = 1;              /* ipv6 type */
13359     }
13360   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
13361     {
13362       a->type = 2;              /* mac type */
13363     }
13364   else
13365     {
13366       return 0;
13367     }
13368
13369   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
13370     {
13371       return 0;
13372     }
13373
13374   return 1;
13375 }
13376
13377 static int
13378 lisp_eid_size_vat (u8 type)
13379 {
13380   switch (type)
13381     {
13382     case 0:
13383       return 4;
13384     case 1:
13385       return 16;
13386     case 2:
13387       return 6;
13388     }
13389   return 0;
13390 }
13391
13392 static void
13393 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
13394 {
13395   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
13396 }
13397
13398 static int
13399 api_one_add_del_locator_set (vat_main_t * vam)
13400 {
13401   unformat_input_t *input = vam->input;
13402   vl_api_one_add_del_locator_set_t *mp;
13403   u8 is_add = 1;
13404   u8 *locator_set_name = NULL;
13405   u8 locator_set_name_set = 0;
13406   vl_api_local_locator_t locator, *locators = 0;
13407   u32 sw_if_index, priority, weight;
13408   u32 data_len = 0;
13409
13410   int ret;
13411   /* Parse args required to build the message */
13412   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13413     {
13414       if (unformat (input, "del"))
13415         {
13416           is_add = 0;
13417         }
13418       else if (unformat (input, "locator-set %s", &locator_set_name))
13419         {
13420           locator_set_name_set = 1;
13421         }
13422       else if (unformat (input, "sw_if_index %u p %u w %u",
13423                          &sw_if_index, &priority, &weight))
13424         {
13425           locator.sw_if_index = htonl (sw_if_index);
13426           locator.priority = priority;
13427           locator.weight = weight;
13428           vec_add1 (locators, locator);
13429         }
13430       else
13431         if (unformat
13432             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
13433              &sw_if_index, &priority, &weight))
13434         {
13435           locator.sw_if_index = htonl (sw_if_index);
13436           locator.priority = priority;
13437           locator.weight = weight;
13438           vec_add1 (locators, locator);
13439         }
13440       else
13441         break;
13442     }
13443
13444   if (locator_set_name_set == 0)
13445     {
13446       errmsg ("missing locator-set name");
13447       vec_free (locators);
13448       return -99;
13449     }
13450
13451   if (vec_len (locator_set_name) > 64)
13452     {
13453       errmsg ("locator-set name too long");
13454       vec_free (locator_set_name);
13455       vec_free (locators);
13456       return -99;
13457     }
13458   vec_add1 (locator_set_name, 0);
13459
13460   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
13461
13462   /* Construct the API message */
13463   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
13464
13465   mp->is_add = is_add;
13466   clib_memcpy (mp->locator_set_name, locator_set_name,
13467                vec_len (locator_set_name));
13468   vec_free (locator_set_name);
13469
13470   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
13471   if (locators)
13472     clib_memcpy (mp->locators, locators, data_len);
13473   vec_free (locators);
13474
13475   /* send it... */
13476   S (mp);
13477
13478   /* Wait for a reply... */
13479   W (ret);
13480   return ret;
13481 }
13482
13483 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
13484
13485 static int
13486 api_one_add_del_locator (vat_main_t * vam)
13487 {
13488   unformat_input_t *input = vam->input;
13489   vl_api_one_add_del_locator_t *mp;
13490   u32 tmp_if_index = ~0;
13491   u32 sw_if_index = ~0;
13492   u8 sw_if_index_set = 0;
13493   u8 sw_if_index_if_name_set = 0;
13494   u32 priority = ~0;
13495   u8 priority_set = 0;
13496   u32 weight = ~0;
13497   u8 weight_set = 0;
13498   u8 is_add = 1;
13499   u8 *locator_set_name = NULL;
13500   u8 locator_set_name_set = 0;
13501   int ret;
13502
13503   /* Parse args required to build the message */
13504   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13505     {
13506       if (unformat (input, "del"))
13507         {
13508           is_add = 0;
13509         }
13510       else if (unformat (input, "locator-set %s", &locator_set_name))
13511         {
13512           locator_set_name_set = 1;
13513         }
13514       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
13515                          &tmp_if_index))
13516         {
13517           sw_if_index_if_name_set = 1;
13518           sw_if_index = tmp_if_index;
13519         }
13520       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
13521         {
13522           sw_if_index_set = 1;
13523           sw_if_index = tmp_if_index;
13524         }
13525       else if (unformat (input, "p %d", &priority))
13526         {
13527           priority_set = 1;
13528         }
13529       else if (unformat (input, "w %d", &weight))
13530         {
13531           weight_set = 1;
13532         }
13533       else
13534         break;
13535     }
13536
13537   if (locator_set_name_set == 0)
13538     {
13539       errmsg ("missing locator-set name");
13540       return -99;
13541     }
13542
13543   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
13544     {
13545       errmsg ("missing sw_if_index");
13546       vec_free (locator_set_name);
13547       return -99;
13548     }
13549
13550   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
13551     {
13552       errmsg ("cannot use both params interface name and sw_if_index");
13553       vec_free (locator_set_name);
13554       return -99;
13555     }
13556
13557   if (priority_set == 0)
13558     {
13559       errmsg ("missing locator-set priority");
13560       vec_free (locator_set_name);
13561       return -99;
13562     }
13563
13564   if (weight_set == 0)
13565     {
13566       errmsg ("missing locator-set weight");
13567       vec_free (locator_set_name);
13568       return -99;
13569     }
13570
13571   if (vec_len (locator_set_name) > 64)
13572     {
13573       errmsg ("locator-set name too long");
13574       vec_free (locator_set_name);
13575       return -99;
13576     }
13577   vec_add1 (locator_set_name, 0);
13578
13579   /* Construct the API message */
13580   M (ONE_ADD_DEL_LOCATOR, mp);
13581
13582   mp->is_add = is_add;
13583   mp->sw_if_index = ntohl (sw_if_index);
13584   mp->priority = priority;
13585   mp->weight = weight;
13586   clib_memcpy (mp->locator_set_name, locator_set_name,
13587                vec_len (locator_set_name));
13588   vec_free (locator_set_name);
13589
13590   /* send it... */
13591   S (mp);
13592
13593   /* Wait for a reply... */
13594   W (ret);
13595   return ret;
13596 }
13597
13598 #define api_lisp_add_del_locator api_one_add_del_locator
13599
13600 uword
13601 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
13602 {
13603   u32 *key_id = va_arg (*args, u32 *);
13604   u8 *s = 0;
13605
13606   if (unformat (input, "%s", &s))
13607     {
13608       if (!strcmp ((char *) s, "sha1"))
13609         key_id[0] = HMAC_SHA_1_96;
13610       else if (!strcmp ((char *) s, "sha256"))
13611         key_id[0] = HMAC_SHA_256_128;
13612       else
13613         {
13614           clib_warning ("invalid key_id: '%s'", s);
13615           key_id[0] = HMAC_NO_KEY;
13616         }
13617     }
13618   else
13619     return 0;
13620
13621   vec_free (s);
13622   return 1;
13623 }
13624
13625 static int
13626 api_one_add_del_local_eid (vat_main_t * vam)
13627 {
13628   unformat_input_t *input = vam->input;
13629   vl_api_one_add_del_local_eid_t *mp;
13630   u8 is_add = 1;
13631   u8 eid_set = 0;
13632   lisp_eid_vat_t _eid, *eid = &_eid;
13633   u8 *locator_set_name = 0;
13634   u8 locator_set_name_set = 0;
13635   u32 vni = 0;
13636   u16 key_id = 0;
13637   u8 *key = 0;
13638   int ret;
13639
13640   /* Parse args required to build the message */
13641   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13642     {
13643       if (unformat (input, "del"))
13644         {
13645           is_add = 0;
13646         }
13647       else if (unformat (input, "vni %d", &vni))
13648         {
13649           ;
13650         }
13651       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13652         {
13653           eid_set = 1;
13654         }
13655       else if (unformat (input, "locator-set %s", &locator_set_name))
13656         {
13657           locator_set_name_set = 1;
13658         }
13659       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
13660         ;
13661       else if (unformat (input, "secret-key %_%v%_", &key))
13662         ;
13663       else
13664         break;
13665     }
13666
13667   if (locator_set_name_set == 0)
13668     {
13669       errmsg ("missing locator-set name");
13670       return -99;
13671     }
13672
13673   if (0 == eid_set)
13674     {
13675       errmsg ("EID address not set!");
13676       vec_free (locator_set_name);
13677       return -99;
13678     }
13679
13680   if (key && (0 == key_id))
13681     {
13682       errmsg ("invalid key_id!");
13683       return -99;
13684     }
13685
13686   if (vec_len (key) > 64)
13687     {
13688       errmsg ("key too long");
13689       vec_free (key);
13690       return -99;
13691     }
13692
13693   if (vec_len (locator_set_name) > 64)
13694     {
13695       errmsg ("locator-set name too long");
13696       vec_free (locator_set_name);
13697       return -99;
13698     }
13699   vec_add1 (locator_set_name, 0);
13700
13701   /* Construct the API message */
13702   M (ONE_ADD_DEL_LOCAL_EID, mp);
13703
13704   mp->is_add = is_add;
13705   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13706   mp->eid_type = eid->type;
13707   mp->prefix_len = eid->len;
13708   mp->vni = clib_host_to_net_u32 (vni);
13709   mp->key_id = clib_host_to_net_u16 (key_id);
13710   clib_memcpy (mp->locator_set_name, locator_set_name,
13711                vec_len (locator_set_name));
13712   clib_memcpy (mp->key, key, vec_len (key));
13713
13714   vec_free (locator_set_name);
13715   vec_free (key);
13716
13717   /* send it... */
13718   S (mp);
13719
13720   /* Wait for a reply... */
13721   W (ret);
13722   return ret;
13723 }
13724
13725 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
13726
13727 static int
13728 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
13729 {
13730   u32 dp_table = 0, vni = 0;;
13731   unformat_input_t *input = vam->input;
13732   vl_api_gpe_add_del_fwd_entry_t *mp;
13733   u8 is_add = 1;
13734   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
13735   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
13736   u8 rmt_eid_set = 0, lcl_eid_set = 0;
13737   u32 action = ~0, w;
13738   ip4_address_t rmt_rloc4, lcl_rloc4;
13739   ip6_address_t rmt_rloc6, lcl_rloc6;
13740   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
13741   int ret;
13742
13743   memset (&rloc, 0, sizeof (rloc));
13744
13745   /* Parse args required to build the message */
13746   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13747     {
13748       if (unformat (input, "del"))
13749         is_add = 0;
13750       else if (unformat (input, "add"))
13751         is_add = 1;
13752       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
13753         {
13754           rmt_eid_set = 1;
13755         }
13756       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
13757         {
13758           lcl_eid_set = 1;
13759         }
13760       else if (unformat (input, "vrf %d", &dp_table))
13761         ;
13762       else if (unformat (input, "bd %d", &dp_table))
13763         ;
13764       else if (unformat (input, "vni %d", &vni))
13765         ;
13766       else if (unformat (input, "w %d", &w))
13767         {
13768           if (!curr_rloc)
13769             {
13770               errmsg ("No RLOC configured for setting priority/weight!");
13771               return -99;
13772             }
13773           curr_rloc->weight = w;
13774         }
13775       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
13776                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
13777         {
13778           rloc.is_ip4 = 1;
13779
13780           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
13781           rloc.weight = 0;
13782           vec_add1 (lcl_locs, rloc);
13783
13784           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
13785           vec_add1 (rmt_locs, rloc);
13786           /* weight saved in rmt loc */
13787           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13788         }
13789       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
13790                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
13791         {
13792           rloc.is_ip4 = 0;
13793           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
13794           rloc.weight = 0;
13795           vec_add1 (lcl_locs, rloc);
13796
13797           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13798           vec_add1 (rmt_locs, rloc);
13799           /* weight saved in rmt loc */
13800           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13801         }
13802       else if (unformat (input, "action %d", &action))
13803         {
13804           ;
13805         }
13806       else
13807         {
13808           clib_warning ("parse error '%U'", format_unformat_error, input);
13809           return -99;
13810         }
13811     }
13812
13813   if (!rmt_eid_set)
13814     {
13815       errmsg ("remote eid addresses not set");
13816       return -99;
13817     }
13818
13819   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13820     {
13821       errmsg ("eid types don't match");
13822       return -99;
13823     }
13824
13825   if (0 == rmt_locs && (u32) ~ 0 == action)
13826     {
13827       errmsg ("action not set for negative mapping");
13828       return -99;
13829     }
13830
13831   /* Construct the API message */
13832   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
13833       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
13834
13835   mp->is_add = is_add;
13836   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13837   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13838   mp->eid_type = rmt_eid->type;
13839   mp->dp_table = clib_host_to_net_u32 (dp_table);
13840   mp->vni = clib_host_to_net_u32 (vni);
13841   mp->rmt_len = rmt_eid->len;
13842   mp->lcl_len = lcl_eid->len;
13843   mp->action = action;
13844
13845   if (0 != rmt_locs && 0 != lcl_locs)
13846     {
13847       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
13848       clib_memcpy (mp->locs, lcl_locs,
13849                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
13850
13851       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
13852       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
13853                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
13854     }
13855   vec_free (lcl_locs);
13856   vec_free (rmt_locs);
13857
13858   /* send it... */
13859   S (mp);
13860
13861   /* Wait for a reply... */
13862   W (ret);
13863   return ret;
13864 }
13865
13866 static int
13867 api_one_add_del_map_server (vat_main_t * vam)
13868 {
13869   unformat_input_t *input = vam->input;
13870   vl_api_one_add_del_map_server_t *mp;
13871   u8 is_add = 1;
13872   u8 ipv4_set = 0;
13873   u8 ipv6_set = 0;
13874   ip4_address_t ipv4;
13875   ip6_address_t ipv6;
13876   int ret;
13877
13878   /* Parse args required to build the message */
13879   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13880     {
13881       if (unformat (input, "del"))
13882         {
13883           is_add = 0;
13884         }
13885       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13886         {
13887           ipv4_set = 1;
13888         }
13889       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13890         {
13891           ipv6_set = 1;
13892         }
13893       else
13894         break;
13895     }
13896
13897   if (ipv4_set && ipv6_set)
13898     {
13899       errmsg ("both eid v4 and v6 addresses set");
13900       return -99;
13901     }
13902
13903   if (!ipv4_set && !ipv6_set)
13904     {
13905       errmsg ("eid addresses not set");
13906       return -99;
13907     }
13908
13909   /* Construct the API message */
13910   M (ONE_ADD_DEL_MAP_SERVER, mp);
13911
13912   mp->is_add = is_add;
13913   if (ipv6_set)
13914     {
13915       mp->is_ipv6 = 1;
13916       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13917     }
13918   else
13919     {
13920       mp->is_ipv6 = 0;
13921       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13922     }
13923
13924   /* send it... */
13925   S (mp);
13926
13927   /* Wait for a reply... */
13928   W (ret);
13929   return ret;
13930 }
13931
13932 #define api_lisp_add_del_map_server api_one_add_del_map_server
13933
13934 static int
13935 api_one_add_del_map_resolver (vat_main_t * vam)
13936 {
13937   unformat_input_t *input = vam->input;
13938   vl_api_one_add_del_map_resolver_t *mp;
13939   u8 is_add = 1;
13940   u8 ipv4_set = 0;
13941   u8 ipv6_set = 0;
13942   ip4_address_t ipv4;
13943   ip6_address_t ipv6;
13944   int ret;
13945
13946   /* Parse args required to build the message */
13947   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13948     {
13949       if (unformat (input, "del"))
13950         {
13951           is_add = 0;
13952         }
13953       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13954         {
13955           ipv4_set = 1;
13956         }
13957       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13958         {
13959           ipv6_set = 1;
13960         }
13961       else
13962         break;
13963     }
13964
13965   if (ipv4_set && ipv6_set)
13966     {
13967       errmsg ("both eid v4 and v6 addresses set");
13968       return -99;
13969     }
13970
13971   if (!ipv4_set && !ipv6_set)
13972     {
13973       errmsg ("eid addresses not set");
13974       return -99;
13975     }
13976
13977   /* Construct the API message */
13978   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
13979
13980   mp->is_add = is_add;
13981   if (ipv6_set)
13982     {
13983       mp->is_ipv6 = 1;
13984       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13985     }
13986   else
13987     {
13988       mp->is_ipv6 = 0;
13989       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13990     }
13991
13992   /* send it... */
13993   S (mp);
13994
13995   /* Wait for a reply... */
13996   W (ret);
13997   return ret;
13998 }
13999
14000 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14001
14002 static int
14003 api_lisp_gpe_enable_disable (vat_main_t * vam)
14004 {
14005   unformat_input_t *input = vam->input;
14006   vl_api_gpe_enable_disable_t *mp;
14007   u8 is_set = 0;
14008   u8 is_en = 1;
14009   int ret;
14010
14011   /* Parse args required to build the message */
14012   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14013     {
14014       if (unformat (input, "enable"))
14015         {
14016           is_set = 1;
14017           is_en = 1;
14018         }
14019       else if (unformat (input, "disable"))
14020         {
14021           is_set = 1;
14022           is_en = 0;
14023         }
14024       else
14025         break;
14026     }
14027
14028   if (is_set == 0)
14029     {
14030       errmsg ("Value not set");
14031       return -99;
14032     }
14033
14034   /* Construct the API message */
14035   M (GPE_ENABLE_DISABLE, mp);
14036
14037   mp->is_en = is_en;
14038
14039   /* send it... */
14040   S (mp);
14041
14042   /* Wait for a reply... */
14043   W (ret);
14044   return ret;
14045 }
14046
14047 static int
14048 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14049 {
14050   unformat_input_t *input = vam->input;
14051   vl_api_one_rloc_probe_enable_disable_t *mp;
14052   u8 is_set = 0;
14053   u8 is_en = 0;
14054   int ret;
14055
14056   /* Parse args required to build the message */
14057   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14058     {
14059       if (unformat (input, "enable"))
14060         {
14061           is_set = 1;
14062           is_en = 1;
14063         }
14064       else if (unformat (input, "disable"))
14065         is_set = 1;
14066       else
14067         break;
14068     }
14069
14070   if (!is_set)
14071     {
14072       errmsg ("Value not set");
14073       return -99;
14074     }
14075
14076   /* Construct the API message */
14077   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14078
14079   mp->is_enabled = is_en;
14080
14081   /* send it... */
14082   S (mp);
14083
14084   /* Wait for a reply... */
14085   W (ret);
14086   return ret;
14087 }
14088
14089 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14090
14091 static int
14092 api_one_map_register_enable_disable (vat_main_t * vam)
14093 {
14094   unformat_input_t *input = vam->input;
14095   vl_api_one_map_register_enable_disable_t *mp;
14096   u8 is_set = 0;
14097   u8 is_en = 0;
14098   int ret;
14099
14100   /* Parse args required to build the message */
14101   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14102     {
14103       if (unformat (input, "enable"))
14104         {
14105           is_set = 1;
14106           is_en = 1;
14107         }
14108       else if (unformat (input, "disable"))
14109         is_set = 1;
14110       else
14111         break;
14112     }
14113
14114   if (!is_set)
14115     {
14116       errmsg ("Value not set");
14117       return -99;
14118     }
14119
14120   /* Construct the API message */
14121   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14122
14123   mp->is_enabled = is_en;
14124
14125   /* send it... */
14126   S (mp);
14127
14128   /* Wait for a reply... */
14129   W (ret);
14130   return ret;
14131 }
14132
14133 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14134
14135 static int
14136 api_one_enable_disable (vat_main_t * vam)
14137 {
14138   unformat_input_t *input = vam->input;
14139   vl_api_one_enable_disable_t *mp;
14140   u8 is_set = 0;
14141   u8 is_en = 0;
14142   int ret;
14143
14144   /* Parse args required to build the message */
14145   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14146     {
14147       if (unformat (input, "enable"))
14148         {
14149           is_set = 1;
14150           is_en = 1;
14151         }
14152       else if (unformat (input, "disable"))
14153         {
14154           is_set = 1;
14155         }
14156       else
14157         break;
14158     }
14159
14160   if (!is_set)
14161     {
14162       errmsg ("Value not set");
14163       return -99;
14164     }
14165
14166   /* Construct the API message */
14167   M (ONE_ENABLE_DISABLE, mp);
14168
14169   mp->is_en = is_en;
14170
14171   /* send it... */
14172   S (mp);
14173
14174   /* Wait for a reply... */
14175   W (ret);
14176   return ret;
14177 }
14178
14179 #define api_lisp_enable_disable api_one_enable_disable
14180
14181 static int
14182 api_show_one_map_register_state (vat_main_t * vam)
14183 {
14184   vl_api_show_one_map_register_state_t *mp;
14185   int ret;
14186
14187   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
14188
14189   /* send */
14190   S (mp);
14191
14192   /* wait for reply */
14193   W (ret);
14194   return ret;
14195 }
14196
14197 #define api_show_lisp_map_register_state api_show_one_map_register_state
14198
14199 static int
14200 api_show_one_rloc_probe_state (vat_main_t * vam)
14201 {
14202   vl_api_show_one_rloc_probe_state_t *mp;
14203   int ret;
14204
14205   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
14206
14207   /* send */
14208   S (mp);
14209
14210   /* wait for reply */
14211   W (ret);
14212   return ret;
14213 }
14214
14215 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
14216
14217 static int
14218 api_show_one_map_request_mode (vat_main_t * vam)
14219 {
14220   vl_api_show_one_map_request_mode_t *mp;
14221   int ret;
14222
14223   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
14224
14225   /* send */
14226   S (mp);
14227
14228   /* wait for reply */
14229   W (ret);
14230   return ret;
14231 }
14232
14233 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
14234
14235 static int
14236 api_one_map_request_mode (vat_main_t * vam)
14237 {
14238   unformat_input_t *input = vam->input;
14239   vl_api_one_map_request_mode_t *mp;
14240   u8 mode = 0;
14241   int ret;
14242
14243   /* Parse args required to build the message */
14244   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14245     {
14246       if (unformat (input, "dst-only"))
14247         mode = 0;
14248       else if (unformat (input, "src-dst"))
14249         mode = 1;
14250       else
14251         {
14252           errmsg ("parse error '%U'", format_unformat_error, input);
14253           return -99;
14254         }
14255     }
14256
14257   M (ONE_MAP_REQUEST_MODE, mp);
14258
14259   mp->mode = mode;
14260
14261   /* send */
14262   S (mp);
14263
14264   /* wait for reply */
14265   W (ret);
14266   return ret;
14267 }
14268
14269 #define api_lisp_map_request_mode api_one_map_request_mode
14270
14271 /**
14272  * Enable/disable ONE proxy ITR.
14273  *
14274  * @param vam vpp API test context
14275  * @return return code
14276  */
14277 static int
14278 api_one_pitr_set_locator_set (vat_main_t * vam)
14279 {
14280   u8 ls_name_set = 0;
14281   unformat_input_t *input = vam->input;
14282   vl_api_one_pitr_set_locator_set_t *mp;
14283   u8 is_add = 1;
14284   u8 *ls_name = 0;
14285   int ret;
14286
14287   /* Parse args required to build the message */
14288   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14289     {
14290       if (unformat (input, "del"))
14291         is_add = 0;
14292       else if (unformat (input, "locator-set %s", &ls_name))
14293         ls_name_set = 1;
14294       else
14295         {
14296           errmsg ("parse error '%U'", format_unformat_error, input);
14297           return -99;
14298         }
14299     }
14300
14301   if (!ls_name_set)
14302     {
14303       errmsg ("locator-set name not set!");
14304       return -99;
14305     }
14306
14307   M (ONE_PITR_SET_LOCATOR_SET, mp);
14308
14309   mp->is_add = is_add;
14310   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
14311   vec_free (ls_name);
14312
14313   /* send */
14314   S (mp);
14315
14316   /* wait for reply */
14317   W (ret);
14318   return ret;
14319 }
14320
14321 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
14322
14323 static int
14324 api_show_one_pitr (vat_main_t * vam)
14325 {
14326   vl_api_show_one_pitr_t *mp;
14327   int ret;
14328
14329   if (!vam->json_output)
14330     {
14331       print (vam->ofp, "%=20s", "lisp status:");
14332     }
14333
14334   M (SHOW_ONE_PITR, mp);
14335   /* send it... */
14336   S (mp);
14337
14338   /* Wait for a reply... */
14339   W (ret);
14340   return ret;
14341 }
14342
14343 #define api_show_lisp_pitr api_show_one_pitr
14344
14345 static int
14346 api_one_use_petr (vat_main_t * vam)
14347 {
14348   unformat_input_t *input = vam->input;
14349   vl_api_one_use_petr_t *mp;
14350   u8 is_add = 0;
14351   ip_address_t ip;
14352   int ret;
14353
14354   memset (&ip, 0, sizeof (ip));
14355
14356   /* Parse args required to build the message */
14357   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14358     {
14359       if (unformat (input, "disable"))
14360         is_add = 0;
14361       else
14362         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
14363         {
14364           is_add = 1;
14365           ip_addr_version (&ip) = IP4;
14366         }
14367       else
14368         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
14369         {
14370           is_add = 1;
14371           ip_addr_version (&ip) = IP6;
14372         }
14373       else
14374         {
14375           errmsg ("parse error '%U'", format_unformat_error, input);
14376           return -99;
14377         }
14378     }
14379
14380   M (ONE_USE_PETR, mp);
14381
14382   mp->is_add = is_add;
14383   if (is_add)
14384     {
14385       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
14386       if (mp->is_ip4)
14387         clib_memcpy (mp->address, &ip, 4);
14388       else
14389         clib_memcpy (mp->address, &ip, 16);
14390     }
14391
14392   /* send */
14393   S (mp);
14394
14395   /* wait for reply */
14396   W (ret);
14397   return ret;
14398 }
14399
14400 #define api_lisp_use_petr api_one_use_petr
14401
14402 static int
14403 api_show_one_use_petr (vat_main_t * vam)
14404 {
14405   vl_api_show_one_use_petr_t *mp;
14406   int ret;
14407
14408   if (!vam->json_output)
14409     {
14410       print (vam->ofp, "%=20s", "Proxy-ETR status:");
14411     }
14412
14413   M (SHOW_ONE_USE_PETR, mp);
14414   /* send it... */
14415   S (mp);
14416
14417   /* Wait for a reply... */
14418   W (ret);
14419   return ret;
14420 }
14421
14422 #define api_show_lisp_use_petr api_show_one_use_petr
14423
14424 /**
14425  * Add/delete mapping between vni and vrf
14426  */
14427 static int
14428 api_one_eid_table_add_del_map (vat_main_t * vam)
14429 {
14430   unformat_input_t *input = vam->input;
14431   vl_api_one_eid_table_add_del_map_t *mp;
14432   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
14433   u32 vni, vrf, bd_index;
14434   int ret;
14435
14436   /* Parse args required to build the message */
14437   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14438     {
14439       if (unformat (input, "del"))
14440         is_add = 0;
14441       else if (unformat (input, "vrf %d", &vrf))
14442         vrf_set = 1;
14443       else if (unformat (input, "bd_index %d", &bd_index))
14444         bd_index_set = 1;
14445       else if (unformat (input, "vni %d", &vni))
14446         vni_set = 1;
14447       else
14448         break;
14449     }
14450
14451   if (!vni_set || (!vrf_set && !bd_index_set))
14452     {
14453       errmsg ("missing arguments!");
14454       return -99;
14455     }
14456
14457   if (vrf_set && bd_index_set)
14458     {
14459       errmsg ("error: both vrf and bd entered!");
14460       return -99;
14461     }
14462
14463   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
14464
14465   mp->is_add = is_add;
14466   mp->vni = htonl (vni);
14467   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
14468   mp->is_l2 = bd_index_set;
14469
14470   /* send */
14471   S (mp);
14472
14473   /* wait for reply */
14474   W (ret);
14475   return ret;
14476 }
14477
14478 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
14479
14480 uword
14481 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
14482 {
14483   u32 *action = va_arg (*args, u32 *);
14484   u8 *s = 0;
14485
14486   if (unformat (input, "%s", &s))
14487     {
14488       if (!strcmp ((char *) s, "no-action"))
14489         action[0] = 0;
14490       else if (!strcmp ((char *) s, "natively-forward"))
14491         action[0] = 1;
14492       else if (!strcmp ((char *) s, "send-map-request"))
14493         action[0] = 2;
14494       else if (!strcmp ((char *) s, "drop"))
14495         action[0] = 3;
14496       else
14497         {
14498           clib_warning ("invalid action: '%s'", s);
14499           action[0] = 3;
14500         }
14501     }
14502   else
14503     return 0;
14504
14505   vec_free (s);
14506   return 1;
14507 }
14508
14509 /**
14510  * Add/del remote mapping to/from ONE control plane
14511  *
14512  * @param vam vpp API test context
14513  * @return return code
14514  */
14515 static int
14516 api_one_add_del_remote_mapping (vat_main_t * vam)
14517 {
14518   unformat_input_t *input = vam->input;
14519   vl_api_one_add_del_remote_mapping_t *mp;
14520   u32 vni = 0;
14521   lisp_eid_vat_t _eid, *eid = &_eid;
14522   lisp_eid_vat_t _seid, *seid = &_seid;
14523   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
14524   u32 action = ~0, p, w, data_len;
14525   ip4_address_t rloc4;
14526   ip6_address_t rloc6;
14527   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
14528   int ret;
14529
14530   memset (&rloc, 0, sizeof (rloc));
14531
14532   /* Parse args required to build the message */
14533   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14534     {
14535       if (unformat (input, "del-all"))
14536         {
14537           del_all = 1;
14538         }
14539       else if (unformat (input, "del"))
14540         {
14541           is_add = 0;
14542         }
14543       else if (unformat (input, "add"))
14544         {
14545           is_add = 1;
14546         }
14547       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14548         {
14549           eid_set = 1;
14550         }
14551       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
14552         {
14553           seid_set = 1;
14554         }
14555       else if (unformat (input, "vni %d", &vni))
14556         {
14557           ;
14558         }
14559       else if (unformat (input, "p %d w %d", &p, &w))
14560         {
14561           if (!curr_rloc)
14562             {
14563               errmsg ("No RLOC configured for setting priority/weight!");
14564               return -99;
14565             }
14566           curr_rloc->priority = p;
14567           curr_rloc->weight = w;
14568         }
14569       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
14570         {
14571           rloc.is_ip4 = 1;
14572           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
14573           vec_add1 (rlocs, rloc);
14574           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14575         }
14576       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
14577         {
14578           rloc.is_ip4 = 0;
14579           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
14580           vec_add1 (rlocs, rloc);
14581           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14582         }
14583       else if (unformat (input, "action %U",
14584                          unformat_negative_mapping_action, &action))
14585         {
14586           ;
14587         }
14588       else
14589         {
14590           clib_warning ("parse error '%U'", format_unformat_error, input);
14591           return -99;
14592         }
14593     }
14594
14595   if (0 == eid_set)
14596     {
14597       errmsg ("missing params!");
14598       return -99;
14599     }
14600
14601   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
14602     {
14603       errmsg ("no action set for negative map-reply!");
14604       return -99;
14605     }
14606
14607   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
14608
14609   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
14610   mp->is_add = is_add;
14611   mp->vni = htonl (vni);
14612   mp->action = (u8) action;
14613   mp->is_src_dst = seid_set;
14614   mp->eid_len = eid->len;
14615   mp->seid_len = seid->len;
14616   mp->del_all = del_all;
14617   mp->eid_type = eid->type;
14618   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14619   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
14620
14621   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
14622   clib_memcpy (mp->rlocs, rlocs, data_len);
14623   vec_free (rlocs);
14624
14625   /* send it... */
14626   S (mp);
14627
14628   /* Wait for a reply... */
14629   W (ret);
14630   return ret;
14631 }
14632
14633 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
14634
14635 /**
14636  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
14637  * forwarding entries in data-plane accordingly.
14638  *
14639  * @param vam vpp API test context
14640  * @return return code
14641  */
14642 static int
14643 api_one_add_del_adjacency (vat_main_t * vam)
14644 {
14645   unformat_input_t *input = vam->input;
14646   vl_api_one_add_del_adjacency_t *mp;
14647   u32 vni = 0;
14648   ip4_address_t leid4, reid4;
14649   ip6_address_t leid6, reid6;
14650   u8 reid_mac[6] = { 0 };
14651   u8 leid_mac[6] = { 0 };
14652   u8 reid_type, leid_type;
14653   u32 leid_len = 0, reid_len = 0, len;
14654   u8 is_add = 1;
14655   int ret;
14656
14657   leid_type = reid_type = (u8) ~ 0;
14658
14659   /* Parse args required to build the message */
14660   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14661     {
14662       if (unformat (input, "del"))
14663         {
14664           is_add = 0;
14665         }
14666       else if (unformat (input, "add"))
14667         {
14668           is_add = 1;
14669         }
14670       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
14671                          &reid4, &len))
14672         {
14673           reid_type = 0;        /* ipv4 */
14674           reid_len = len;
14675         }
14676       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
14677                          &reid6, &len))
14678         {
14679           reid_type = 1;        /* ipv6 */
14680           reid_len = len;
14681         }
14682       else if (unformat (input, "reid %U", unformat_ethernet_address,
14683                          reid_mac))
14684         {
14685           reid_type = 2;        /* mac */
14686         }
14687       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
14688                          &leid4, &len))
14689         {
14690           leid_type = 0;        /* ipv4 */
14691           leid_len = len;
14692         }
14693       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
14694                          &leid6, &len))
14695         {
14696           leid_type = 1;        /* ipv6 */
14697           leid_len = len;
14698         }
14699       else if (unformat (input, "leid %U", unformat_ethernet_address,
14700                          leid_mac))
14701         {
14702           leid_type = 2;        /* mac */
14703         }
14704       else if (unformat (input, "vni %d", &vni))
14705         {
14706           ;
14707         }
14708       else
14709         {
14710           errmsg ("parse error '%U'", format_unformat_error, input);
14711           return -99;
14712         }
14713     }
14714
14715   if ((u8) ~ 0 == reid_type)
14716     {
14717       errmsg ("missing params!");
14718       return -99;
14719     }
14720
14721   if (leid_type != reid_type)
14722     {
14723       errmsg ("remote and local EIDs are of different types!");
14724       return -99;
14725     }
14726
14727   M (ONE_ADD_DEL_ADJACENCY, mp);
14728   mp->is_add = is_add;
14729   mp->vni = htonl (vni);
14730   mp->leid_len = leid_len;
14731   mp->reid_len = reid_len;
14732   mp->eid_type = reid_type;
14733
14734   switch (mp->eid_type)
14735     {
14736     case 0:
14737       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
14738       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
14739       break;
14740     case 1:
14741       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
14742       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
14743       break;
14744     case 2:
14745       clib_memcpy (mp->leid, leid_mac, 6);
14746       clib_memcpy (mp->reid, reid_mac, 6);
14747       break;
14748     default:
14749       errmsg ("unknown EID type %d!", mp->eid_type);
14750       return 0;
14751     }
14752
14753   /* send it... */
14754   S (mp);
14755
14756   /* Wait for a reply... */
14757   W (ret);
14758   return ret;
14759 }
14760
14761 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
14762
14763 uword
14764 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
14765 {
14766   u32 *mode = va_arg (*args, u32 *);
14767
14768   if (unformat (input, "lisp"))
14769     *mode = 0;
14770   else if (unformat (input, "vxlan"))
14771     *mode = 1;
14772   else
14773     return 0;
14774
14775   return 1;
14776 }
14777
14778 static int
14779 api_gpe_get_encap_mode (vat_main_t * vam)
14780 {
14781   vl_api_gpe_get_encap_mode_t *mp;
14782   int ret;
14783
14784   /* Construct the API message */
14785   M (GPE_GET_ENCAP_MODE, mp);
14786
14787   /* send it... */
14788   S (mp);
14789
14790   /* Wait for a reply... */
14791   W (ret);
14792   return ret;
14793 }
14794
14795 static int
14796 api_gpe_set_encap_mode (vat_main_t * vam)
14797 {
14798   unformat_input_t *input = vam->input;
14799   vl_api_gpe_set_encap_mode_t *mp;
14800   int ret;
14801   u32 mode = 0;
14802
14803   /* Parse args required to build the message */
14804   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14805     {
14806       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
14807         ;
14808       else
14809         break;
14810     }
14811
14812   /* Construct the API message */
14813   M (GPE_SET_ENCAP_MODE, mp);
14814
14815   mp->mode = mode;
14816
14817   /* send it... */
14818   S (mp);
14819
14820   /* Wait for a reply... */
14821   W (ret);
14822   return ret;
14823 }
14824
14825 static int
14826 api_lisp_gpe_add_del_iface (vat_main_t * vam)
14827 {
14828   unformat_input_t *input = vam->input;
14829   vl_api_gpe_add_del_iface_t *mp;
14830   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
14831   u32 dp_table = 0, vni = 0;
14832   int ret;
14833
14834   /* Parse args required to build the message */
14835   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14836     {
14837       if (unformat (input, "up"))
14838         {
14839           action_set = 1;
14840           is_add = 1;
14841         }
14842       else if (unformat (input, "down"))
14843         {
14844           action_set = 1;
14845           is_add = 0;
14846         }
14847       else if (unformat (input, "table_id %d", &dp_table))
14848         {
14849           dp_table_set = 1;
14850         }
14851       else if (unformat (input, "bd_id %d", &dp_table))
14852         {
14853           dp_table_set = 1;
14854           is_l2 = 1;
14855         }
14856       else if (unformat (input, "vni %d", &vni))
14857         {
14858           vni_set = 1;
14859         }
14860       else
14861         break;
14862     }
14863
14864   if (action_set == 0)
14865     {
14866       errmsg ("Action not set");
14867       return -99;
14868     }
14869   if (dp_table_set == 0 || vni_set == 0)
14870     {
14871       errmsg ("vni and dp_table must be set");
14872       return -99;
14873     }
14874
14875   /* Construct the API message */
14876   M (GPE_ADD_DEL_IFACE, mp);
14877
14878   mp->is_add = is_add;
14879   mp->dp_table = dp_table;
14880   mp->is_l2 = is_l2;
14881   mp->vni = vni;
14882
14883   /* send it... */
14884   S (mp);
14885
14886   /* Wait for a reply... */
14887   W (ret);
14888   return ret;
14889 }
14890
14891 /**
14892  * Add/del map request itr rlocs from ONE control plane and updates
14893  *
14894  * @param vam vpp API test context
14895  * @return return code
14896  */
14897 static int
14898 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
14899 {
14900   unformat_input_t *input = vam->input;
14901   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
14902   u8 *locator_set_name = 0;
14903   u8 locator_set_name_set = 0;
14904   u8 is_add = 1;
14905   int ret;
14906
14907   /* Parse args required to build the message */
14908   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14909     {
14910       if (unformat (input, "del"))
14911         {
14912           is_add = 0;
14913         }
14914       else if (unformat (input, "%_%v%_", &locator_set_name))
14915         {
14916           locator_set_name_set = 1;
14917         }
14918       else
14919         {
14920           clib_warning ("parse error '%U'", format_unformat_error, input);
14921           return -99;
14922         }
14923     }
14924
14925   if (is_add && !locator_set_name_set)
14926     {
14927       errmsg ("itr-rloc is not set!");
14928       return -99;
14929     }
14930
14931   if (is_add && vec_len (locator_set_name) > 64)
14932     {
14933       errmsg ("itr-rloc locator-set name too long");
14934       vec_free (locator_set_name);
14935       return -99;
14936     }
14937
14938   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
14939   mp->is_add = is_add;
14940   if (is_add)
14941     {
14942       clib_memcpy (mp->locator_set_name, locator_set_name,
14943                    vec_len (locator_set_name));
14944     }
14945   else
14946     {
14947       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
14948     }
14949   vec_free (locator_set_name);
14950
14951   /* send it... */
14952   S (mp);
14953
14954   /* Wait for a reply... */
14955   W (ret);
14956   return ret;
14957 }
14958
14959 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
14960
14961 static int
14962 api_one_locator_dump (vat_main_t * vam)
14963 {
14964   unformat_input_t *input = vam->input;
14965   vl_api_one_locator_dump_t *mp;
14966   vl_api_control_ping_t *mp_ping;
14967   u8 is_index_set = 0, is_name_set = 0;
14968   u8 *ls_name = 0;
14969   u32 ls_index = ~0;
14970   int ret;
14971
14972   /* Parse args required to build the message */
14973   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14974     {
14975       if (unformat (input, "ls_name %_%v%_", &ls_name))
14976         {
14977           is_name_set = 1;
14978         }
14979       else if (unformat (input, "ls_index %d", &ls_index))
14980         {
14981           is_index_set = 1;
14982         }
14983       else
14984         {
14985           errmsg ("parse error '%U'", format_unformat_error, input);
14986           return -99;
14987         }
14988     }
14989
14990   if (!is_index_set && !is_name_set)
14991     {
14992       errmsg ("error: expected one of index or name!");
14993       return -99;
14994     }
14995
14996   if (is_index_set && is_name_set)
14997     {
14998       errmsg ("error: only one param expected!");
14999       return -99;
15000     }
15001
15002   if (vec_len (ls_name) > 62)
15003     {
15004       errmsg ("error: locator set name too long!");
15005       return -99;
15006     }
15007
15008   if (!vam->json_output)
15009     {
15010       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
15011     }
15012
15013   M (ONE_LOCATOR_DUMP, mp);
15014   mp->is_index_set = is_index_set;
15015
15016   if (is_index_set)
15017     mp->ls_index = clib_host_to_net_u32 (ls_index);
15018   else
15019     {
15020       vec_add1 (ls_name, 0);
15021       strncpy ((char *) mp->ls_name, (char *) ls_name,
15022                sizeof (mp->ls_name) - 1);
15023     }
15024
15025   /* send it... */
15026   S (mp);
15027
15028   /* Use a control ping for synchronization */
15029   M (CONTROL_PING, mp_ping);
15030   S (mp_ping);
15031
15032   /* Wait for a reply... */
15033   W (ret);
15034   return ret;
15035 }
15036
15037 #define api_lisp_locator_dump api_one_locator_dump
15038
15039 static int
15040 api_one_locator_set_dump (vat_main_t * vam)
15041 {
15042   vl_api_one_locator_set_dump_t *mp;
15043   vl_api_control_ping_t *mp_ping;
15044   unformat_input_t *input = vam->input;
15045   u8 filter = 0;
15046   int ret;
15047
15048   /* Parse args required to build the message */
15049   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15050     {
15051       if (unformat (input, "local"))
15052         {
15053           filter = 1;
15054         }
15055       else if (unformat (input, "remote"))
15056         {
15057           filter = 2;
15058         }
15059       else
15060         {
15061           errmsg ("parse error '%U'", format_unformat_error, input);
15062           return -99;
15063         }
15064     }
15065
15066   if (!vam->json_output)
15067     {
15068       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
15069     }
15070
15071   M (ONE_LOCATOR_SET_DUMP, mp);
15072
15073   mp->filter = filter;
15074
15075   /* send it... */
15076   S (mp);
15077
15078   /* Use a control ping for synchronization */
15079   M (CONTROL_PING, mp_ping);
15080   S (mp_ping);
15081
15082   /* Wait for a reply... */
15083   W (ret);
15084   return ret;
15085 }
15086
15087 #define api_lisp_locator_set_dump api_one_locator_set_dump
15088
15089 static int
15090 api_one_eid_table_map_dump (vat_main_t * vam)
15091 {
15092   u8 is_l2 = 0;
15093   u8 mode_set = 0;
15094   unformat_input_t *input = vam->input;
15095   vl_api_one_eid_table_map_dump_t *mp;
15096   vl_api_control_ping_t *mp_ping;
15097   int ret;
15098
15099   /* Parse args required to build the message */
15100   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15101     {
15102       if (unformat (input, "l2"))
15103         {
15104           is_l2 = 1;
15105           mode_set = 1;
15106         }
15107       else if (unformat (input, "l3"))
15108         {
15109           is_l2 = 0;
15110           mode_set = 1;
15111         }
15112       else
15113         {
15114           errmsg ("parse error '%U'", format_unformat_error, input);
15115           return -99;
15116         }
15117     }
15118
15119   if (!mode_set)
15120     {
15121       errmsg ("expected one of 'l2' or 'l3' parameter!");
15122       return -99;
15123     }
15124
15125   if (!vam->json_output)
15126     {
15127       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
15128     }
15129
15130   M (ONE_EID_TABLE_MAP_DUMP, mp);
15131   mp->is_l2 = is_l2;
15132
15133   /* send it... */
15134   S (mp);
15135
15136   /* Use a control ping for synchronization */
15137   M (CONTROL_PING, mp_ping);
15138   S (mp_ping);
15139
15140   /* Wait for a reply... */
15141   W (ret);
15142   return ret;
15143 }
15144
15145 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
15146
15147 static int
15148 api_one_eid_table_vni_dump (vat_main_t * vam)
15149 {
15150   vl_api_one_eid_table_vni_dump_t *mp;
15151   vl_api_control_ping_t *mp_ping;
15152   int ret;
15153
15154   if (!vam->json_output)
15155     {
15156       print (vam->ofp, "VNI");
15157     }
15158
15159   M (ONE_EID_TABLE_VNI_DUMP, mp);
15160
15161   /* send it... */
15162   S (mp);
15163
15164   /* Use a control ping for synchronization */
15165   M (CONTROL_PING, mp_ping);
15166   S (mp_ping);
15167
15168   /* Wait for a reply... */
15169   W (ret);
15170   return ret;
15171 }
15172
15173 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
15174
15175 static int
15176 api_one_eid_table_dump (vat_main_t * vam)
15177 {
15178   unformat_input_t *i = vam->input;
15179   vl_api_one_eid_table_dump_t *mp;
15180   vl_api_control_ping_t *mp_ping;
15181   struct in_addr ip4;
15182   struct in6_addr ip6;
15183   u8 mac[6];
15184   u8 eid_type = ~0, eid_set = 0;
15185   u32 prefix_length = ~0, t, vni = 0;
15186   u8 filter = 0;
15187   int ret;
15188
15189   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15190     {
15191       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
15192         {
15193           eid_set = 1;
15194           eid_type = 0;
15195           prefix_length = t;
15196         }
15197       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
15198         {
15199           eid_set = 1;
15200           eid_type = 1;
15201           prefix_length = t;
15202         }
15203       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
15204         {
15205           eid_set = 1;
15206           eid_type = 2;
15207         }
15208       else if (unformat (i, "vni %d", &t))
15209         {
15210           vni = t;
15211         }
15212       else if (unformat (i, "local"))
15213         {
15214           filter = 1;
15215         }
15216       else if (unformat (i, "remote"))
15217         {
15218           filter = 2;
15219         }
15220       else
15221         {
15222           errmsg ("parse error '%U'", format_unformat_error, i);
15223           return -99;
15224         }
15225     }
15226
15227   if (!vam->json_output)
15228     {
15229       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
15230              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
15231     }
15232
15233   M (ONE_EID_TABLE_DUMP, mp);
15234
15235   mp->filter = filter;
15236   if (eid_set)
15237     {
15238       mp->eid_set = 1;
15239       mp->vni = htonl (vni);
15240       mp->eid_type = eid_type;
15241       switch (eid_type)
15242         {
15243         case 0:
15244           mp->prefix_length = prefix_length;
15245           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
15246           break;
15247         case 1:
15248           mp->prefix_length = prefix_length;
15249           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
15250           break;
15251         case 2:
15252           clib_memcpy (mp->eid, mac, sizeof (mac));
15253           break;
15254         default:
15255           errmsg ("unknown EID type %d!", eid_type);
15256           return -99;
15257         }
15258     }
15259
15260   /* send it... */
15261   S (mp);
15262
15263   /* Use a control ping for synchronization */
15264   M (CONTROL_PING, mp_ping);
15265   S (mp_ping);
15266
15267   /* Wait for a reply... */
15268   W (ret);
15269   return ret;
15270 }
15271
15272 #define api_lisp_eid_table_dump api_one_eid_table_dump
15273
15274 static int
15275 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
15276 {
15277   unformat_input_t *i = vam->input;
15278   vl_api_gpe_fwd_entries_get_t *mp;
15279   u8 vni_set = 0;
15280   u32 vni = ~0;
15281   int ret;
15282
15283   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15284     {
15285       if (unformat (i, "vni %d", &vni))
15286         {
15287           vni_set = 1;
15288         }
15289       else
15290         {
15291           errmsg ("parse error '%U'", format_unformat_error, i);
15292           return -99;
15293         }
15294     }
15295
15296   if (!vni_set)
15297     {
15298       errmsg ("vni not set!");
15299       return -99;
15300     }
15301
15302   if (!vam->json_output)
15303     {
15304       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
15305              "leid", "reid");
15306     }
15307
15308   M (GPE_FWD_ENTRIES_GET, mp);
15309   mp->vni = clib_host_to_net_u32 (vni);
15310
15311   /* send it... */
15312   S (mp);
15313
15314   /* Wait for a reply... */
15315   W (ret);
15316   return ret;
15317 }
15318
15319 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
15320 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
15321 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
15322 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
15323
15324 static int
15325 api_one_adjacencies_get (vat_main_t * vam)
15326 {
15327   unformat_input_t *i = vam->input;
15328   vl_api_one_adjacencies_get_t *mp;
15329   u8 vni_set = 0;
15330   u32 vni = ~0;
15331   int ret;
15332
15333   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15334     {
15335       if (unformat (i, "vni %d", &vni))
15336         {
15337           vni_set = 1;
15338         }
15339       else
15340         {
15341           errmsg ("parse error '%U'", format_unformat_error, i);
15342           return -99;
15343         }
15344     }
15345
15346   if (!vni_set)
15347     {
15348       errmsg ("vni not set!");
15349       return -99;
15350     }
15351
15352   if (!vam->json_output)
15353     {
15354       print (vam->ofp, "%s %40s", "leid", "reid");
15355     }
15356
15357   M (ONE_ADJACENCIES_GET, mp);
15358   mp->vni = clib_host_to_net_u32 (vni);
15359
15360   /* send it... */
15361   S (mp);
15362
15363   /* Wait for a reply... */
15364   W (ret);
15365   return ret;
15366 }
15367
15368 #define api_lisp_adjacencies_get api_one_adjacencies_get
15369
15370 static int
15371 api_one_map_server_dump (vat_main_t * vam)
15372 {
15373   vl_api_one_map_server_dump_t *mp;
15374   vl_api_control_ping_t *mp_ping;
15375   int ret;
15376
15377   if (!vam->json_output)
15378     {
15379       print (vam->ofp, "%=20s", "Map server");
15380     }
15381
15382   M (ONE_MAP_SERVER_DUMP, mp);
15383   /* send it... */
15384   S (mp);
15385
15386   /* Use a control ping for synchronization */
15387   M (CONTROL_PING, mp_ping);
15388   S (mp_ping);
15389
15390   /* Wait for a reply... */
15391   W (ret);
15392   return ret;
15393 }
15394
15395 #define api_lisp_map_server_dump api_one_map_server_dump
15396
15397 static int
15398 api_one_map_resolver_dump (vat_main_t * vam)
15399 {
15400   vl_api_one_map_resolver_dump_t *mp;
15401   vl_api_control_ping_t *mp_ping;
15402   int ret;
15403
15404   if (!vam->json_output)
15405     {
15406       print (vam->ofp, "%=20s", "Map resolver");
15407     }
15408
15409   M (ONE_MAP_RESOLVER_DUMP, mp);
15410   /* send it... */
15411   S (mp);
15412
15413   /* Use a control ping for synchronization */
15414   M (CONTROL_PING, mp_ping);
15415   S (mp_ping);
15416
15417   /* Wait for a reply... */
15418   W (ret);
15419   return ret;
15420 }
15421
15422 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
15423
15424 static int
15425 api_show_one_status (vat_main_t * vam)
15426 {
15427   vl_api_show_one_status_t *mp;
15428   int ret;
15429
15430   if (!vam->json_output)
15431     {
15432       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
15433     }
15434
15435   M (SHOW_ONE_STATUS, mp);
15436   /* send it... */
15437   S (mp);
15438   /* Wait for a reply... */
15439   W (ret);
15440   return ret;
15441 }
15442
15443 #define api_show_lisp_status api_show_one_status
15444
15445 static int
15446 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
15447 {
15448   vl_api_gpe_fwd_entry_path_dump_t *mp;
15449   vl_api_control_ping_t *mp_ping;
15450   unformat_input_t *i = vam->input;
15451   u32 fwd_entry_index = ~0;
15452   int ret;
15453
15454   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15455     {
15456       if (unformat (i, "index %d", &fwd_entry_index))
15457         ;
15458       else
15459         break;
15460     }
15461
15462   if (~0 == fwd_entry_index)
15463     {
15464       errmsg ("no index specified!");
15465       return -99;
15466     }
15467
15468   if (!vam->json_output)
15469     {
15470       print (vam->ofp, "first line");
15471     }
15472
15473   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
15474
15475   /* send it... */
15476   S (mp);
15477   /* Use a control ping for synchronization */
15478   M (CONTROL_PING, mp_ping);
15479   S (mp_ping);
15480
15481   /* Wait for a reply... */
15482   W (ret);
15483   return ret;
15484 }
15485
15486 static int
15487 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
15488 {
15489   vl_api_one_get_map_request_itr_rlocs_t *mp;
15490   int ret;
15491
15492   if (!vam->json_output)
15493     {
15494       print (vam->ofp, "%=20s", "itr-rlocs:");
15495     }
15496
15497   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
15498   /* send it... */
15499   S (mp);
15500   /* Wait for a reply... */
15501   W (ret);
15502   return ret;
15503 }
15504
15505 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
15506
15507 static int
15508 api_af_packet_create (vat_main_t * vam)
15509 {
15510   unformat_input_t *i = vam->input;
15511   vl_api_af_packet_create_t *mp;
15512   u8 *host_if_name = 0;
15513   u8 hw_addr[6];
15514   u8 random_hw_addr = 1;
15515   int ret;
15516
15517   memset (hw_addr, 0, sizeof (hw_addr));
15518
15519   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15520     {
15521       if (unformat (i, "name %s", &host_if_name))
15522         vec_add1 (host_if_name, 0);
15523       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15524         random_hw_addr = 0;
15525       else
15526         break;
15527     }
15528
15529   if (!vec_len (host_if_name))
15530     {
15531       errmsg ("host-interface name must be specified");
15532       return -99;
15533     }
15534
15535   if (vec_len (host_if_name) > 64)
15536     {
15537       errmsg ("host-interface name too long");
15538       return -99;
15539     }
15540
15541   M (AF_PACKET_CREATE, mp);
15542
15543   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15544   clib_memcpy (mp->hw_addr, hw_addr, 6);
15545   mp->use_random_hw_addr = random_hw_addr;
15546   vec_free (host_if_name);
15547
15548   S (mp);
15549
15550   /* *INDENT-OFF* */
15551   W2 (ret,
15552       ({
15553         if (ret == 0)
15554           fprintf (vam->ofp ? vam->ofp : stderr,
15555                    " new sw_if_index = %d\n", vam->sw_if_index);
15556       }));
15557   /* *INDENT-ON* */
15558   return ret;
15559 }
15560
15561 static int
15562 api_af_packet_delete (vat_main_t * vam)
15563 {
15564   unformat_input_t *i = vam->input;
15565   vl_api_af_packet_delete_t *mp;
15566   u8 *host_if_name = 0;
15567   int ret;
15568
15569   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15570     {
15571       if (unformat (i, "name %s", &host_if_name))
15572         vec_add1 (host_if_name, 0);
15573       else
15574         break;
15575     }
15576
15577   if (!vec_len (host_if_name))
15578     {
15579       errmsg ("host-interface name must be specified");
15580       return -99;
15581     }
15582
15583   if (vec_len (host_if_name) > 64)
15584     {
15585       errmsg ("host-interface name too long");
15586       return -99;
15587     }
15588
15589   M (AF_PACKET_DELETE, mp);
15590
15591   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15592   vec_free (host_if_name);
15593
15594   S (mp);
15595   W (ret);
15596   return ret;
15597 }
15598
15599 static int
15600 api_policer_add_del (vat_main_t * vam)
15601 {
15602   unformat_input_t *i = vam->input;
15603   vl_api_policer_add_del_t *mp;
15604   u8 is_add = 1;
15605   u8 *name = 0;
15606   u32 cir = 0;
15607   u32 eir = 0;
15608   u64 cb = 0;
15609   u64 eb = 0;
15610   u8 rate_type = 0;
15611   u8 round_type = 0;
15612   u8 type = 0;
15613   u8 color_aware = 0;
15614   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
15615   int ret;
15616
15617   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
15618   conform_action.dscp = 0;
15619   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
15620   exceed_action.dscp = 0;
15621   violate_action.action_type = SSE2_QOS_ACTION_DROP;
15622   violate_action.dscp = 0;
15623
15624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15625     {
15626       if (unformat (i, "del"))
15627         is_add = 0;
15628       else if (unformat (i, "name %s", &name))
15629         vec_add1 (name, 0);
15630       else if (unformat (i, "cir %u", &cir))
15631         ;
15632       else if (unformat (i, "eir %u", &eir))
15633         ;
15634       else if (unformat (i, "cb %u", &cb))
15635         ;
15636       else if (unformat (i, "eb %u", &eb))
15637         ;
15638       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
15639                          &rate_type))
15640         ;
15641       else if (unformat (i, "round_type %U", unformat_policer_round_type,
15642                          &round_type))
15643         ;
15644       else if (unformat (i, "type %U", unformat_policer_type, &type))
15645         ;
15646       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
15647                          &conform_action))
15648         ;
15649       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
15650                          &exceed_action))
15651         ;
15652       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
15653                          &violate_action))
15654         ;
15655       else if (unformat (i, "color-aware"))
15656         color_aware = 1;
15657       else
15658         break;
15659     }
15660
15661   if (!vec_len (name))
15662     {
15663       errmsg ("policer name must be specified");
15664       return -99;
15665     }
15666
15667   if (vec_len (name) > 64)
15668     {
15669       errmsg ("policer name too long");
15670       return -99;
15671     }
15672
15673   M (POLICER_ADD_DEL, mp);
15674
15675   clib_memcpy (mp->name, name, vec_len (name));
15676   vec_free (name);
15677   mp->is_add = is_add;
15678   mp->cir = cir;
15679   mp->eir = eir;
15680   mp->cb = cb;
15681   mp->eb = eb;
15682   mp->rate_type = rate_type;
15683   mp->round_type = round_type;
15684   mp->type = type;
15685   mp->conform_action_type = conform_action.action_type;
15686   mp->conform_dscp = conform_action.dscp;
15687   mp->exceed_action_type = exceed_action.action_type;
15688   mp->exceed_dscp = exceed_action.dscp;
15689   mp->violate_action_type = violate_action.action_type;
15690   mp->violate_dscp = violate_action.dscp;
15691   mp->color_aware = color_aware;
15692
15693   S (mp);
15694   W (ret);
15695   return ret;
15696 }
15697
15698 static int
15699 api_policer_dump (vat_main_t * vam)
15700 {
15701   unformat_input_t *i = vam->input;
15702   vl_api_policer_dump_t *mp;
15703   vl_api_control_ping_t *mp_ping;
15704   u8 *match_name = 0;
15705   u8 match_name_valid = 0;
15706   int ret;
15707
15708   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15709     {
15710       if (unformat (i, "name %s", &match_name))
15711         {
15712           vec_add1 (match_name, 0);
15713           match_name_valid = 1;
15714         }
15715       else
15716         break;
15717     }
15718
15719   M (POLICER_DUMP, mp);
15720   mp->match_name_valid = match_name_valid;
15721   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
15722   vec_free (match_name);
15723   /* send it... */
15724   S (mp);
15725
15726   /* Use a control ping for synchronization */
15727   M (CONTROL_PING, mp_ping);
15728   S (mp_ping);
15729
15730   /* Wait for a reply... */
15731   W (ret);
15732   return ret;
15733 }
15734
15735 static int
15736 api_policer_classify_set_interface (vat_main_t * vam)
15737 {
15738   unformat_input_t *i = vam->input;
15739   vl_api_policer_classify_set_interface_t *mp;
15740   u32 sw_if_index;
15741   int sw_if_index_set;
15742   u32 ip4_table_index = ~0;
15743   u32 ip6_table_index = ~0;
15744   u32 l2_table_index = ~0;
15745   u8 is_add = 1;
15746   int ret;
15747
15748   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15749     {
15750       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15751         sw_if_index_set = 1;
15752       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15753         sw_if_index_set = 1;
15754       else if (unformat (i, "del"))
15755         is_add = 0;
15756       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15757         ;
15758       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15759         ;
15760       else if (unformat (i, "l2-table %d", &l2_table_index))
15761         ;
15762       else
15763         {
15764           clib_warning ("parse error '%U'", format_unformat_error, i);
15765           return -99;
15766         }
15767     }
15768
15769   if (sw_if_index_set == 0)
15770     {
15771       errmsg ("missing interface name or sw_if_index");
15772       return -99;
15773     }
15774
15775   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
15776
15777   mp->sw_if_index = ntohl (sw_if_index);
15778   mp->ip4_table_index = ntohl (ip4_table_index);
15779   mp->ip6_table_index = ntohl (ip6_table_index);
15780   mp->l2_table_index = ntohl (l2_table_index);
15781   mp->is_add = is_add;
15782
15783   S (mp);
15784   W (ret);
15785   return ret;
15786 }
15787
15788 static int
15789 api_policer_classify_dump (vat_main_t * vam)
15790 {
15791   unformat_input_t *i = vam->input;
15792   vl_api_policer_classify_dump_t *mp;
15793   vl_api_control_ping_t *mp_ping;
15794   u8 type = POLICER_CLASSIFY_N_TABLES;
15795   int ret;
15796
15797   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
15798     ;
15799   else
15800     {
15801       errmsg ("classify table type must be specified");
15802       return -99;
15803     }
15804
15805   if (!vam->json_output)
15806     {
15807       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
15808     }
15809
15810   M (POLICER_CLASSIFY_DUMP, mp);
15811   mp->type = type;
15812   /* send it... */
15813   S (mp);
15814
15815   /* Use a control ping for synchronization */
15816   M (CONTROL_PING, mp_ping);
15817   S (mp_ping);
15818
15819   /* Wait for a reply... */
15820   W (ret);
15821   return ret;
15822 }
15823
15824 static int
15825 api_netmap_create (vat_main_t * vam)
15826 {
15827   unformat_input_t *i = vam->input;
15828   vl_api_netmap_create_t *mp;
15829   u8 *if_name = 0;
15830   u8 hw_addr[6];
15831   u8 random_hw_addr = 1;
15832   u8 is_pipe = 0;
15833   u8 is_master = 0;
15834   int ret;
15835
15836   memset (hw_addr, 0, sizeof (hw_addr));
15837
15838   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15839     {
15840       if (unformat (i, "name %s", &if_name))
15841         vec_add1 (if_name, 0);
15842       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15843         random_hw_addr = 0;
15844       else if (unformat (i, "pipe"))
15845         is_pipe = 1;
15846       else if (unformat (i, "master"))
15847         is_master = 1;
15848       else if (unformat (i, "slave"))
15849         is_master = 0;
15850       else
15851         break;
15852     }
15853
15854   if (!vec_len (if_name))
15855     {
15856       errmsg ("interface name must be specified");
15857       return -99;
15858     }
15859
15860   if (vec_len (if_name) > 64)
15861     {
15862       errmsg ("interface name too long");
15863       return -99;
15864     }
15865
15866   M (NETMAP_CREATE, mp);
15867
15868   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15869   clib_memcpy (mp->hw_addr, hw_addr, 6);
15870   mp->use_random_hw_addr = random_hw_addr;
15871   mp->is_pipe = is_pipe;
15872   mp->is_master = is_master;
15873   vec_free (if_name);
15874
15875   S (mp);
15876   W (ret);
15877   return ret;
15878 }
15879
15880 static int
15881 api_netmap_delete (vat_main_t * vam)
15882 {
15883   unformat_input_t *i = vam->input;
15884   vl_api_netmap_delete_t *mp;
15885   u8 *if_name = 0;
15886   int ret;
15887
15888   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15889     {
15890       if (unformat (i, "name %s", &if_name))
15891         vec_add1 (if_name, 0);
15892       else
15893         break;
15894     }
15895
15896   if (!vec_len (if_name))
15897     {
15898       errmsg ("interface name must be specified");
15899       return -99;
15900     }
15901
15902   if (vec_len (if_name) > 64)
15903     {
15904       errmsg ("interface name too long");
15905       return -99;
15906     }
15907
15908   M (NETMAP_DELETE, mp);
15909
15910   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15911   vec_free (if_name);
15912
15913   S (mp);
15914   W (ret);
15915   return ret;
15916 }
15917
15918 static void vl_api_mpls_tunnel_details_t_handler
15919   (vl_api_mpls_tunnel_details_t * mp)
15920 {
15921   vat_main_t *vam = &vat_main;
15922   i32 len = mp->mt_next_hop_n_labels;
15923   i32 i;
15924
15925   print (vam->ofp, "[%d]: via %U %d labels ",
15926          mp->tunnel_index,
15927          format_ip4_address, mp->mt_next_hop,
15928          ntohl (mp->mt_next_hop_sw_if_index));
15929   for (i = 0; i < len; i++)
15930     {
15931       print (vam->ofp, "%u ", ntohl (mp->mt_next_hop_out_labels[i]));
15932     }
15933   print (vam->ofp, "");
15934 }
15935
15936 static void vl_api_mpls_tunnel_details_t_handler_json
15937   (vl_api_mpls_tunnel_details_t * mp)
15938 {
15939   vat_main_t *vam = &vat_main;
15940   vat_json_node_t *node = NULL;
15941   struct in_addr ip4;
15942   i32 i;
15943   i32 len = mp->mt_next_hop_n_labels;
15944
15945   if (VAT_JSON_ARRAY != vam->json_tree.type)
15946     {
15947       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15948       vat_json_init_array (&vam->json_tree);
15949     }
15950   node = vat_json_array_add (&vam->json_tree);
15951
15952   vat_json_init_object (node);
15953   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
15954   clib_memcpy (&ip4, &(mp->mt_next_hop), sizeof (ip4));
15955   vat_json_object_add_ip4 (node, "next_hop", ip4);
15956   vat_json_object_add_uint (node, "next_hop_sw_if_index",
15957                             ntohl (mp->mt_next_hop_sw_if_index));
15958   vat_json_object_add_uint (node, "l2_only", ntohl (mp->mt_l2_only));
15959   vat_json_object_add_uint (node, "label_count", len);
15960   for (i = 0; i < len; i++)
15961     {
15962       vat_json_object_add_uint (node, "label",
15963                                 ntohl (mp->mt_next_hop_out_labels[i]));
15964     }
15965 }
15966
15967 static int
15968 api_mpls_tunnel_dump (vat_main_t * vam)
15969 {
15970   vl_api_mpls_tunnel_dump_t *mp;
15971   vl_api_control_ping_t *mp_ping;
15972   i32 index = -1;
15973   int ret;
15974
15975   /* Parse args required to build the message */
15976   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
15977     {
15978       if (!unformat (vam->input, "tunnel_index %d", &index))
15979         {
15980           index = -1;
15981           break;
15982         }
15983     }
15984
15985   print (vam->ofp, "  tunnel_index %d", index);
15986
15987   M (MPLS_TUNNEL_DUMP, mp);
15988   mp->tunnel_index = htonl (index);
15989   S (mp);
15990
15991   /* Use a control ping for synchronization */
15992   M (CONTROL_PING, mp_ping);
15993   S (mp_ping);
15994
15995   W (ret);
15996   return ret;
15997 }
15998
15999 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
16000 #define vl_api_mpls_fib_details_t_print vl_noop_handler
16001
16002 static void
16003 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
16004 {
16005   vat_main_t *vam = &vat_main;
16006   int count = ntohl (mp->count);
16007   vl_api_fib_path2_t *fp;
16008   int i;
16009
16010   print (vam->ofp,
16011          "table-id %d, label %u, ess_bit %u",
16012          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
16013   fp = mp->path;
16014   for (i = 0; i < count; i++)
16015     {
16016       if (fp->afi == IP46_TYPE_IP6)
16017         print (vam->ofp,
16018                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16019                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16020                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16021                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16022                format_ip6_address, fp->next_hop);
16023       else if (fp->afi == IP46_TYPE_IP4)
16024         print (vam->ofp,
16025                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16026                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16027                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16028                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16029                format_ip4_address, fp->next_hop);
16030       fp++;
16031     }
16032 }
16033
16034 static void vl_api_mpls_fib_details_t_handler_json
16035   (vl_api_mpls_fib_details_t * mp)
16036 {
16037   vat_main_t *vam = &vat_main;
16038   int count = ntohl (mp->count);
16039   vat_json_node_t *node = NULL;
16040   struct in_addr ip4;
16041   struct in6_addr ip6;
16042   vl_api_fib_path2_t *fp;
16043   int i;
16044
16045   if (VAT_JSON_ARRAY != vam->json_tree.type)
16046     {
16047       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16048       vat_json_init_array (&vam->json_tree);
16049     }
16050   node = vat_json_array_add (&vam->json_tree);
16051
16052   vat_json_init_object (node);
16053   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16054   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
16055   vat_json_object_add_uint (node, "label", ntohl (mp->label));
16056   vat_json_object_add_uint (node, "path_count", count);
16057   fp = mp->path;
16058   for (i = 0; i < count; i++)
16059     {
16060       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16061       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16062       vat_json_object_add_uint (node, "is_local", fp->is_local);
16063       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16064       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16065       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16066       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16067       if (fp->afi == IP46_TYPE_IP4)
16068         {
16069           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16070           vat_json_object_add_ip4 (node, "next_hop", ip4);
16071         }
16072       else if (fp->afi == IP46_TYPE_IP6)
16073         {
16074           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16075           vat_json_object_add_ip6 (node, "next_hop", ip6);
16076         }
16077     }
16078 }
16079
16080 static int
16081 api_mpls_fib_dump (vat_main_t * vam)
16082 {
16083   vl_api_mpls_fib_dump_t *mp;
16084   vl_api_control_ping_t *mp_ping;
16085   int ret;
16086
16087   M (MPLS_FIB_DUMP, mp);
16088   S (mp);
16089
16090   /* Use a control ping for synchronization */
16091   M (CONTROL_PING, mp_ping);
16092   S (mp_ping);
16093
16094   W (ret);
16095   return ret;
16096 }
16097
16098 #define vl_api_ip_fib_details_t_endian vl_noop_handler
16099 #define vl_api_ip_fib_details_t_print vl_noop_handler
16100
16101 static void
16102 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
16103 {
16104   vat_main_t *vam = &vat_main;
16105   int count = ntohl (mp->count);
16106   vl_api_fib_path_t *fp;
16107   int i;
16108
16109   print (vam->ofp,
16110          "table-id %d, prefix %U/%d",
16111          ntohl (mp->table_id), format_ip4_address, mp->address,
16112          mp->address_length);
16113   fp = mp->path;
16114   for (i = 0; i < count; i++)
16115     {
16116       if (fp->afi == IP46_TYPE_IP6)
16117         print (vam->ofp,
16118                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16119                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16120                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16121                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16122                format_ip6_address, fp->next_hop);
16123       else if (fp->afi == IP46_TYPE_IP4)
16124         print (vam->ofp,
16125                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16126                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16127                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16128                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16129                format_ip4_address, fp->next_hop);
16130       fp++;
16131     }
16132 }
16133
16134 static void vl_api_ip_fib_details_t_handler_json
16135   (vl_api_ip_fib_details_t * mp)
16136 {
16137   vat_main_t *vam = &vat_main;
16138   int count = ntohl (mp->count);
16139   vat_json_node_t *node = NULL;
16140   struct in_addr ip4;
16141   struct in6_addr ip6;
16142   vl_api_fib_path_t *fp;
16143   int i;
16144
16145   if (VAT_JSON_ARRAY != vam->json_tree.type)
16146     {
16147       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16148       vat_json_init_array (&vam->json_tree);
16149     }
16150   node = vat_json_array_add (&vam->json_tree);
16151
16152   vat_json_init_object (node);
16153   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16154   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
16155   vat_json_object_add_ip4 (node, "prefix", ip4);
16156   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16157   vat_json_object_add_uint (node, "path_count", count);
16158   fp = mp->path;
16159   for (i = 0; i < count; i++)
16160     {
16161       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16162       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16163       vat_json_object_add_uint (node, "is_local", fp->is_local);
16164       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16165       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16166       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16167       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16168       if (fp->afi == IP46_TYPE_IP4)
16169         {
16170           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16171           vat_json_object_add_ip4 (node, "next_hop", ip4);
16172         }
16173       else if (fp->afi == IP46_TYPE_IP6)
16174         {
16175           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16176           vat_json_object_add_ip6 (node, "next_hop", ip6);
16177         }
16178     }
16179 }
16180
16181 static int
16182 api_ip_fib_dump (vat_main_t * vam)
16183 {
16184   vl_api_ip_fib_dump_t *mp;
16185   vl_api_control_ping_t *mp_ping;
16186   int ret;
16187
16188   M (IP_FIB_DUMP, mp);
16189   S (mp);
16190
16191   /* Use a control ping for synchronization */
16192   M (CONTROL_PING, mp_ping);
16193   S (mp_ping);
16194
16195   W (ret);
16196   return ret;
16197 }
16198
16199 static int
16200 api_ip_mfib_dump (vat_main_t * vam)
16201 {
16202   vl_api_ip_mfib_dump_t *mp;
16203   vl_api_control_ping_t *mp_ping;
16204   int ret;
16205
16206   M (IP_MFIB_DUMP, mp);
16207   S (mp);
16208
16209   /* Use a control ping for synchronization */
16210   M (CONTROL_PING, mp_ping);
16211   S (mp_ping);
16212
16213   W (ret);
16214   return ret;
16215 }
16216
16217 static void vl_api_ip_neighbor_details_t_handler
16218   (vl_api_ip_neighbor_details_t * mp)
16219 {
16220   vat_main_t *vam = &vat_main;
16221
16222   print (vam->ofp, "%c %U %U",
16223          (mp->is_static) ? 'S' : 'D',
16224          format_ethernet_address, &mp->mac_address,
16225          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
16226          &mp->ip_address);
16227 }
16228
16229 static void vl_api_ip_neighbor_details_t_handler_json
16230   (vl_api_ip_neighbor_details_t * mp)
16231 {
16232
16233   vat_main_t *vam = &vat_main;
16234   vat_json_node_t *node;
16235   struct in_addr ip4;
16236   struct in6_addr ip6;
16237
16238   if (VAT_JSON_ARRAY != vam->json_tree.type)
16239     {
16240       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16241       vat_json_init_array (&vam->json_tree);
16242     }
16243   node = vat_json_array_add (&vam->json_tree);
16244
16245   vat_json_init_object (node);
16246   vat_json_object_add_string_copy (node, "flag",
16247                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
16248                                    "dynamic");
16249
16250   vat_json_object_add_string_copy (node, "link_layer",
16251                                    format (0, "%U", format_ethernet_address,
16252                                            &mp->mac_address));
16253
16254   if (mp->is_ipv6)
16255     {
16256       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
16257       vat_json_object_add_ip6 (node, "ip_address", ip6);
16258     }
16259   else
16260     {
16261       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
16262       vat_json_object_add_ip4 (node, "ip_address", ip4);
16263     }
16264 }
16265
16266 static int
16267 api_ip_neighbor_dump (vat_main_t * vam)
16268 {
16269   unformat_input_t *i = vam->input;
16270   vl_api_ip_neighbor_dump_t *mp;
16271   vl_api_control_ping_t *mp_ping;
16272   u8 is_ipv6 = 0;
16273   u32 sw_if_index = ~0;
16274   int ret;
16275
16276   /* Parse args required to build the message */
16277   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16278     {
16279       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16280         ;
16281       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16282         ;
16283       else if (unformat (i, "ip6"))
16284         is_ipv6 = 1;
16285       else
16286         break;
16287     }
16288
16289   if (sw_if_index == ~0)
16290     {
16291       errmsg ("missing interface name or sw_if_index");
16292       return -99;
16293     }
16294
16295   M (IP_NEIGHBOR_DUMP, mp);
16296   mp->is_ipv6 = (u8) is_ipv6;
16297   mp->sw_if_index = ntohl (sw_if_index);
16298   S (mp);
16299
16300   /* Use a control ping for synchronization */
16301   M (CONTROL_PING, mp_ping);
16302   S (mp_ping);
16303
16304   W (ret);
16305   return ret;
16306 }
16307
16308 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
16309 #define vl_api_ip6_fib_details_t_print vl_noop_handler
16310
16311 static void
16312 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
16313 {
16314   vat_main_t *vam = &vat_main;
16315   int count = ntohl (mp->count);
16316   vl_api_fib_path_t *fp;
16317   int i;
16318
16319   print (vam->ofp,
16320          "table-id %d, prefix %U/%d",
16321          ntohl (mp->table_id), format_ip6_address, mp->address,
16322          mp->address_length);
16323   fp = mp->path;
16324   for (i = 0; i < count; i++)
16325     {
16326       if (fp->afi == IP46_TYPE_IP6)
16327         print (vam->ofp,
16328                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16329                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16330                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16331                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16332                format_ip6_address, fp->next_hop);
16333       else if (fp->afi == IP46_TYPE_IP4)
16334         print (vam->ofp,
16335                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16336                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16337                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16338                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16339                format_ip4_address, fp->next_hop);
16340       fp++;
16341     }
16342 }
16343
16344 static void vl_api_ip6_fib_details_t_handler_json
16345   (vl_api_ip6_fib_details_t * mp)
16346 {
16347   vat_main_t *vam = &vat_main;
16348   int count = ntohl (mp->count);
16349   vat_json_node_t *node = NULL;
16350   struct in_addr ip4;
16351   struct in6_addr ip6;
16352   vl_api_fib_path_t *fp;
16353   int i;
16354
16355   if (VAT_JSON_ARRAY != vam->json_tree.type)
16356     {
16357       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16358       vat_json_init_array (&vam->json_tree);
16359     }
16360   node = vat_json_array_add (&vam->json_tree);
16361
16362   vat_json_init_object (node);
16363   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16364   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
16365   vat_json_object_add_ip6 (node, "prefix", ip6);
16366   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16367   vat_json_object_add_uint (node, "path_count", count);
16368   fp = mp->path;
16369   for (i = 0; i < count; i++)
16370     {
16371       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16372       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16373       vat_json_object_add_uint (node, "is_local", fp->is_local);
16374       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16375       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16376       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16377       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16378       if (fp->afi == IP46_TYPE_IP4)
16379         {
16380           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16381           vat_json_object_add_ip4 (node, "next_hop", ip4);
16382         }
16383       else if (fp->afi == IP46_TYPE_IP6)
16384         {
16385           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16386           vat_json_object_add_ip6 (node, "next_hop", ip6);
16387         }
16388     }
16389 }
16390
16391 static int
16392 api_ip6_fib_dump (vat_main_t * vam)
16393 {
16394   vl_api_ip6_fib_dump_t *mp;
16395   vl_api_control_ping_t *mp_ping;
16396   int ret;
16397
16398   M (IP6_FIB_DUMP, mp);
16399   S (mp);
16400
16401   /* Use a control ping for synchronization */
16402   M (CONTROL_PING, mp_ping);
16403   S (mp_ping);
16404
16405   W (ret);
16406   return ret;
16407 }
16408
16409 static int
16410 api_ip6_mfib_dump (vat_main_t * vam)
16411 {
16412   vl_api_ip6_mfib_dump_t *mp;
16413   vl_api_control_ping_t *mp_ping;
16414   int ret;
16415
16416   M (IP6_MFIB_DUMP, mp);
16417   S (mp);
16418
16419   /* Use a control ping for synchronization */
16420   M (CONTROL_PING, mp_ping);
16421   S (mp_ping);
16422
16423   W (ret);
16424   return ret;
16425 }
16426
16427 int
16428 api_classify_table_ids (vat_main_t * vam)
16429 {
16430   vl_api_classify_table_ids_t *mp;
16431   int ret;
16432
16433   /* Construct the API message */
16434   M (CLASSIFY_TABLE_IDS, mp);
16435   mp->context = 0;
16436
16437   S (mp);
16438   W (ret);
16439   return ret;
16440 }
16441
16442 int
16443 api_classify_table_by_interface (vat_main_t * vam)
16444 {
16445   unformat_input_t *input = vam->input;
16446   vl_api_classify_table_by_interface_t *mp;
16447
16448   u32 sw_if_index = ~0;
16449   int ret;
16450   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16451     {
16452       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16453         ;
16454       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16455         ;
16456       else
16457         break;
16458     }
16459   if (sw_if_index == ~0)
16460     {
16461       errmsg ("missing interface name or sw_if_index");
16462       return -99;
16463     }
16464
16465   /* Construct the API message */
16466   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
16467   mp->context = 0;
16468   mp->sw_if_index = ntohl (sw_if_index);
16469
16470   S (mp);
16471   W (ret);
16472   return ret;
16473 }
16474
16475 int
16476 api_classify_table_info (vat_main_t * vam)
16477 {
16478   unformat_input_t *input = vam->input;
16479   vl_api_classify_table_info_t *mp;
16480
16481   u32 table_id = ~0;
16482   int ret;
16483   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16484     {
16485       if (unformat (input, "table_id %d", &table_id))
16486         ;
16487       else
16488         break;
16489     }
16490   if (table_id == ~0)
16491     {
16492       errmsg ("missing table id");
16493       return -99;
16494     }
16495
16496   /* Construct the API message */
16497   M (CLASSIFY_TABLE_INFO, mp);
16498   mp->context = 0;
16499   mp->table_id = ntohl (table_id);
16500
16501   S (mp);
16502   W (ret);
16503   return ret;
16504 }
16505
16506 int
16507 api_classify_session_dump (vat_main_t * vam)
16508 {
16509   unformat_input_t *input = vam->input;
16510   vl_api_classify_session_dump_t *mp;
16511   vl_api_control_ping_t *mp_ping;
16512
16513   u32 table_id = ~0;
16514   int ret;
16515   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16516     {
16517       if (unformat (input, "table_id %d", &table_id))
16518         ;
16519       else
16520         break;
16521     }
16522   if (table_id == ~0)
16523     {
16524       errmsg ("missing table id");
16525       return -99;
16526     }
16527
16528   /* Construct the API message */
16529   M (CLASSIFY_SESSION_DUMP, mp);
16530   mp->context = 0;
16531   mp->table_id = ntohl (table_id);
16532   S (mp);
16533
16534   /* Use a control ping for synchronization */
16535   M (CONTROL_PING, mp_ping);
16536   S (mp_ping);
16537
16538   W (ret);
16539   return ret;
16540 }
16541
16542 static void
16543 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
16544 {
16545   vat_main_t *vam = &vat_main;
16546
16547   print (vam->ofp, "collector_address %U, collector_port %d, "
16548          "src_address %U, vrf_id %d, path_mtu %u, "
16549          "template_interval %u, udp_checksum %d",
16550          format_ip4_address, mp->collector_address,
16551          ntohs (mp->collector_port),
16552          format_ip4_address, mp->src_address,
16553          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
16554          ntohl (mp->template_interval), mp->udp_checksum);
16555
16556   vam->retval = 0;
16557   vam->result_ready = 1;
16558 }
16559
16560 static void
16561   vl_api_ipfix_exporter_details_t_handler_json
16562   (vl_api_ipfix_exporter_details_t * mp)
16563 {
16564   vat_main_t *vam = &vat_main;
16565   vat_json_node_t node;
16566   struct in_addr collector_address;
16567   struct in_addr src_address;
16568
16569   vat_json_init_object (&node);
16570   clib_memcpy (&collector_address, &mp->collector_address,
16571                sizeof (collector_address));
16572   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
16573   vat_json_object_add_uint (&node, "collector_port",
16574                             ntohs (mp->collector_port));
16575   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
16576   vat_json_object_add_ip4 (&node, "src_address", src_address);
16577   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
16578   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
16579   vat_json_object_add_uint (&node, "template_interval",
16580                             ntohl (mp->template_interval));
16581   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
16582
16583   vat_json_print (vam->ofp, &node);
16584   vat_json_free (&node);
16585   vam->retval = 0;
16586   vam->result_ready = 1;
16587 }
16588
16589 int
16590 api_ipfix_exporter_dump (vat_main_t * vam)
16591 {
16592   vl_api_ipfix_exporter_dump_t *mp;
16593   int ret;
16594
16595   /* Construct the API message */
16596   M (IPFIX_EXPORTER_DUMP, mp);
16597   mp->context = 0;
16598
16599   S (mp);
16600   W (ret);
16601   return ret;
16602 }
16603
16604 static int
16605 api_ipfix_classify_stream_dump (vat_main_t * vam)
16606 {
16607   vl_api_ipfix_classify_stream_dump_t *mp;
16608   int ret;
16609
16610   /* Construct the API message */
16611   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
16612   mp->context = 0;
16613
16614   S (mp);
16615   W (ret);
16616   return ret;
16617   /* NOTREACHED */
16618   return 0;
16619 }
16620
16621 static void
16622   vl_api_ipfix_classify_stream_details_t_handler
16623   (vl_api_ipfix_classify_stream_details_t * mp)
16624 {
16625   vat_main_t *vam = &vat_main;
16626   print (vam->ofp, "domain_id %d, src_port %d",
16627          ntohl (mp->domain_id), ntohs (mp->src_port));
16628   vam->retval = 0;
16629   vam->result_ready = 1;
16630 }
16631
16632 static void
16633   vl_api_ipfix_classify_stream_details_t_handler_json
16634   (vl_api_ipfix_classify_stream_details_t * mp)
16635 {
16636   vat_main_t *vam = &vat_main;
16637   vat_json_node_t node;
16638
16639   vat_json_init_object (&node);
16640   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
16641   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
16642
16643   vat_json_print (vam->ofp, &node);
16644   vat_json_free (&node);
16645   vam->retval = 0;
16646   vam->result_ready = 1;
16647 }
16648
16649 static int
16650 api_ipfix_classify_table_dump (vat_main_t * vam)
16651 {
16652   vl_api_ipfix_classify_table_dump_t *mp;
16653   vl_api_control_ping_t *mp_ping;
16654   int ret;
16655
16656   if (!vam->json_output)
16657     {
16658       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
16659              "transport_protocol");
16660     }
16661
16662   /* Construct the API message */
16663   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
16664
16665   /* send it... */
16666   S (mp);
16667
16668   /* Use a control ping for synchronization */
16669   M (CONTROL_PING, mp_ping);
16670   S (mp_ping);
16671
16672   W (ret);
16673   return ret;
16674 }
16675
16676 static void
16677   vl_api_ipfix_classify_table_details_t_handler
16678   (vl_api_ipfix_classify_table_details_t * mp)
16679 {
16680   vat_main_t *vam = &vat_main;
16681   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
16682          mp->transport_protocol);
16683 }
16684
16685 static void
16686   vl_api_ipfix_classify_table_details_t_handler_json
16687   (vl_api_ipfix_classify_table_details_t * mp)
16688 {
16689   vat_json_node_t *node = NULL;
16690   vat_main_t *vam = &vat_main;
16691
16692   if (VAT_JSON_ARRAY != vam->json_tree.type)
16693     {
16694       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16695       vat_json_init_array (&vam->json_tree);
16696     }
16697
16698   node = vat_json_array_add (&vam->json_tree);
16699   vat_json_init_object (node);
16700
16701   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
16702   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
16703   vat_json_object_add_uint (node, "transport_protocol",
16704                             mp->transport_protocol);
16705 }
16706
16707 static int
16708 api_sw_interface_span_enable_disable (vat_main_t * vam)
16709 {
16710   unformat_input_t *i = vam->input;
16711   vl_api_sw_interface_span_enable_disable_t *mp;
16712   u32 src_sw_if_index = ~0;
16713   u32 dst_sw_if_index = ~0;
16714   u8 state = 3;
16715   int ret;
16716
16717   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16718     {
16719       if (unformat
16720           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
16721         ;
16722       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
16723         ;
16724       else
16725         if (unformat
16726             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
16727         ;
16728       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
16729         ;
16730       else if (unformat (i, "disable"))
16731         state = 0;
16732       else if (unformat (i, "rx"))
16733         state = 1;
16734       else if (unformat (i, "tx"))
16735         state = 2;
16736       else if (unformat (i, "both"))
16737         state = 3;
16738       else
16739         break;
16740     }
16741
16742   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
16743
16744   mp->sw_if_index_from = htonl (src_sw_if_index);
16745   mp->sw_if_index_to = htonl (dst_sw_if_index);
16746   mp->state = state;
16747
16748   S (mp);
16749   W (ret);
16750   return ret;
16751 }
16752
16753 static void
16754 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
16755                                             * mp)
16756 {
16757   vat_main_t *vam = &vat_main;
16758   u8 *sw_if_from_name = 0;
16759   u8 *sw_if_to_name = 0;
16760   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16761   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16762   char *states[] = { "none", "rx", "tx", "both" };
16763   hash_pair_t *p;
16764
16765   /* *INDENT-OFF* */
16766   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16767   ({
16768     if ((u32) p->value[0] == sw_if_index_from)
16769       {
16770         sw_if_from_name = (u8 *)(p->key);
16771         if (sw_if_to_name)
16772           break;
16773       }
16774     if ((u32) p->value[0] == sw_if_index_to)
16775       {
16776         sw_if_to_name = (u8 *)(p->key);
16777         if (sw_if_from_name)
16778           break;
16779       }
16780   }));
16781   /* *INDENT-ON* */
16782   print (vam->ofp, "%20s => %20s (%s)",
16783          sw_if_from_name, sw_if_to_name, states[mp->state]);
16784 }
16785
16786 static void
16787   vl_api_sw_interface_span_details_t_handler_json
16788   (vl_api_sw_interface_span_details_t * mp)
16789 {
16790   vat_main_t *vam = &vat_main;
16791   vat_json_node_t *node = NULL;
16792   u8 *sw_if_from_name = 0;
16793   u8 *sw_if_to_name = 0;
16794   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16795   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16796   hash_pair_t *p;
16797
16798   /* *INDENT-OFF* */
16799   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16800   ({
16801     if ((u32) p->value[0] == sw_if_index_from)
16802       {
16803         sw_if_from_name = (u8 *)(p->key);
16804         if (sw_if_to_name)
16805           break;
16806       }
16807     if ((u32) p->value[0] == sw_if_index_to)
16808       {
16809         sw_if_to_name = (u8 *)(p->key);
16810         if (sw_if_from_name)
16811           break;
16812       }
16813   }));
16814   /* *INDENT-ON* */
16815
16816   if (VAT_JSON_ARRAY != vam->json_tree.type)
16817     {
16818       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16819       vat_json_init_array (&vam->json_tree);
16820     }
16821   node = vat_json_array_add (&vam->json_tree);
16822
16823   vat_json_init_object (node);
16824   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
16825   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
16826   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
16827   if (0 != sw_if_to_name)
16828     {
16829       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
16830     }
16831   vat_json_object_add_uint (node, "state", mp->state);
16832 }
16833
16834 static int
16835 api_sw_interface_span_dump (vat_main_t * vam)
16836 {
16837   vl_api_sw_interface_span_dump_t *mp;
16838   vl_api_control_ping_t *mp_ping;
16839   int ret;
16840
16841   M (SW_INTERFACE_SPAN_DUMP, mp);
16842   S (mp);
16843
16844   /* Use a control ping for synchronization */
16845   M (CONTROL_PING, mp_ping);
16846   S (mp_ping);
16847
16848   W (ret);
16849   return ret;
16850 }
16851
16852 int
16853 api_pg_create_interface (vat_main_t * vam)
16854 {
16855   unformat_input_t *input = vam->input;
16856   vl_api_pg_create_interface_t *mp;
16857
16858   u32 if_id = ~0;
16859   int ret;
16860   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16861     {
16862       if (unformat (input, "if_id %d", &if_id))
16863         ;
16864       else
16865         break;
16866     }
16867   if (if_id == ~0)
16868     {
16869       errmsg ("missing pg interface index");
16870       return -99;
16871     }
16872
16873   /* Construct the API message */
16874   M (PG_CREATE_INTERFACE, mp);
16875   mp->context = 0;
16876   mp->interface_id = ntohl (if_id);
16877
16878   S (mp);
16879   W (ret);
16880   return ret;
16881 }
16882
16883 int
16884 api_pg_capture (vat_main_t * vam)
16885 {
16886   unformat_input_t *input = vam->input;
16887   vl_api_pg_capture_t *mp;
16888
16889   u32 if_id = ~0;
16890   u8 enable = 1;
16891   u32 count = 1;
16892   u8 pcap_file_set = 0;
16893   u8 *pcap_file = 0;
16894   int ret;
16895   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16896     {
16897       if (unformat (input, "if_id %d", &if_id))
16898         ;
16899       else if (unformat (input, "pcap %s", &pcap_file))
16900         pcap_file_set = 1;
16901       else if (unformat (input, "count %d", &count))
16902         ;
16903       else if (unformat (input, "disable"))
16904         enable = 0;
16905       else
16906         break;
16907     }
16908   if (if_id == ~0)
16909     {
16910       errmsg ("missing pg interface index");
16911       return -99;
16912     }
16913   if (pcap_file_set > 0)
16914     {
16915       if (vec_len (pcap_file) > 255)
16916         {
16917           errmsg ("pcap file name is too long");
16918           return -99;
16919         }
16920     }
16921
16922   u32 name_len = vec_len (pcap_file);
16923   /* Construct the API message */
16924   M (PG_CAPTURE, mp);
16925   mp->context = 0;
16926   mp->interface_id = ntohl (if_id);
16927   mp->is_enabled = enable;
16928   mp->count = ntohl (count);
16929   mp->pcap_name_length = ntohl (name_len);
16930   if (pcap_file_set != 0)
16931     {
16932       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
16933     }
16934   vec_free (pcap_file);
16935
16936   S (mp);
16937   W (ret);
16938   return ret;
16939 }
16940
16941 int
16942 api_pg_enable_disable (vat_main_t * vam)
16943 {
16944   unformat_input_t *input = vam->input;
16945   vl_api_pg_enable_disable_t *mp;
16946
16947   u8 enable = 1;
16948   u8 stream_name_set = 0;
16949   u8 *stream_name = 0;
16950   int ret;
16951   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16952     {
16953       if (unformat (input, "stream %s", &stream_name))
16954         stream_name_set = 1;
16955       else if (unformat (input, "disable"))
16956         enable = 0;
16957       else
16958         break;
16959     }
16960
16961   if (stream_name_set > 0)
16962     {
16963       if (vec_len (stream_name) > 255)
16964         {
16965           errmsg ("stream name too long");
16966           return -99;
16967         }
16968     }
16969
16970   u32 name_len = vec_len (stream_name);
16971   /* Construct the API message */
16972   M (PG_ENABLE_DISABLE, mp);
16973   mp->context = 0;
16974   mp->is_enabled = enable;
16975   if (stream_name_set != 0)
16976     {
16977       mp->stream_name_length = ntohl (name_len);
16978       clib_memcpy (mp->stream_name, stream_name, name_len);
16979     }
16980   vec_free (stream_name);
16981
16982   S (mp);
16983   W (ret);
16984   return ret;
16985 }
16986
16987 int
16988 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
16989 {
16990   unformat_input_t *input = vam->input;
16991   vl_api_ip_source_and_port_range_check_add_del_t *mp;
16992
16993   u16 *low_ports = 0;
16994   u16 *high_ports = 0;
16995   u16 this_low;
16996   u16 this_hi;
16997   ip4_address_t ip4_addr;
16998   ip6_address_t ip6_addr;
16999   u32 length;
17000   u32 tmp, tmp2;
17001   u8 prefix_set = 0;
17002   u32 vrf_id = ~0;
17003   u8 is_add = 1;
17004   u8 is_ipv6 = 0;
17005   int ret;
17006
17007   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17008     {
17009       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
17010         {
17011           prefix_set = 1;
17012         }
17013       else
17014         if (unformat
17015             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
17016         {
17017           prefix_set = 1;
17018           is_ipv6 = 1;
17019         }
17020       else if (unformat (input, "vrf %d", &vrf_id))
17021         ;
17022       else if (unformat (input, "del"))
17023         is_add = 0;
17024       else if (unformat (input, "port %d", &tmp))
17025         {
17026           if (tmp == 0 || tmp > 65535)
17027             {
17028               errmsg ("port %d out of range", tmp);
17029               return -99;
17030             }
17031           this_low = tmp;
17032           this_hi = this_low + 1;
17033           vec_add1 (low_ports, this_low);
17034           vec_add1 (high_ports, this_hi);
17035         }
17036       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
17037         {
17038           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
17039             {
17040               errmsg ("incorrect range parameters");
17041               return -99;
17042             }
17043           this_low = tmp;
17044           /* Note: in debug CLI +1 is added to high before
17045              passing to real fn that does "the work"
17046              (ip_source_and_port_range_check_add_del).
17047              This fn is a wrapper around the binary API fn a
17048              control plane will call, which expects this increment
17049              to have occurred. Hence letting the binary API control
17050              plane fn do the increment for consistency between VAT
17051              and other control planes.
17052            */
17053           this_hi = tmp2;
17054           vec_add1 (low_ports, this_low);
17055           vec_add1 (high_ports, this_hi);
17056         }
17057       else
17058         break;
17059     }
17060
17061   if (prefix_set == 0)
17062     {
17063       errmsg ("<address>/<mask> not specified");
17064       return -99;
17065     }
17066
17067   if (vrf_id == ~0)
17068     {
17069       errmsg ("VRF ID required, not specified");
17070       return -99;
17071     }
17072
17073   if (vrf_id == 0)
17074     {
17075       errmsg
17076         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17077       return -99;
17078     }
17079
17080   if (vec_len (low_ports) == 0)
17081     {
17082       errmsg ("At least one port or port range required");
17083       return -99;
17084     }
17085
17086   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
17087
17088   mp->is_add = is_add;
17089
17090   if (is_ipv6)
17091     {
17092       mp->is_ipv6 = 1;
17093       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
17094     }
17095   else
17096     {
17097       mp->is_ipv6 = 0;
17098       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
17099     }
17100
17101   mp->mask_length = length;
17102   mp->number_of_ranges = vec_len (low_ports);
17103
17104   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
17105   vec_free (low_ports);
17106
17107   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
17108   vec_free (high_ports);
17109
17110   mp->vrf_id = ntohl (vrf_id);
17111
17112   S (mp);
17113   W (ret);
17114   return ret;
17115 }
17116
17117 int
17118 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
17119 {
17120   unformat_input_t *input = vam->input;
17121   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
17122   u32 sw_if_index = ~0;
17123   int vrf_set = 0;
17124   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
17125   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
17126   u8 is_add = 1;
17127   int ret;
17128
17129   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17130     {
17131       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17132         ;
17133       else if (unformat (input, "sw_if_index %d", &sw_if_index))
17134         ;
17135       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
17136         vrf_set = 1;
17137       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
17138         vrf_set = 1;
17139       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
17140         vrf_set = 1;
17141       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
17142         vrf_set = 1;
17143       else if (unformat (input, "del"))
17144         is_add = 0;
17145       else
17146         break;
17147     }
17148
17149   if (sw_if_index == ~0)
17150     {
17151       errmsg ("Interface required but not specified");
17152       return -99;
17153     }
17154
17155   if (vrf_set == 0)
17156     {
17157       errmsg ("VRF ID required but not specified");
17158       return -99;
17159     }
17160
17161   if (tcp_out_vrf_id == 0
17162       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
17163     {
17164       errmsg
17165         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17166       return -99;
17167     }
17168
17169   /* Construct the API message */
17170   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
17171
17172   mp->sw_if_index = ntohl (sw_if_index);
17173   mp->is_add = is_add;
17174   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
17175   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
17176   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
17177   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
17178
17179   /* send it... */
17180   S (mp);
17181
17182   /* Wait for a reply... */
17183   W (ret);
17184   return ret;
17185 }
17186
17187 static int
17188 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
17189 {
17190   unformat_input_t *i = vam->input;
17191   vl_api_ipsec_gre_add_del_tunnel_t *mp;
17192   u32 local_sa_id = 0;
17193   u32 remote_sa_id = 0;
17194   ip4_address_t src_address;
17195   ip4_address_t dst_address;
17196   u8 is_add = 1;
17197   int ret;
17198
17199   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17200     {
17201       if (unformat (i, "local_sa %d", &local_sa_id))
17202         ;
17203       else if (unformat (i, "remote_sa %d", &remote_sa_id))
17204         ;
17205       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
17206         ;
17207       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
17208         ;
17209       else if (unformat (i, "del"))
17210         is_add = 0;
17211       else
17212         {
17213           clib_warning ("parse error '%U'", format_unformat_error, i);
17214           return -99;
17215         }
17216     }
17217
17218   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
17219
17220   mp->local_sa_id = ntohl (local_sa_id);
17221   mp->remote_sa_id = ntohl (remote_sa_id);
17222   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
17223   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
17224   mp->is_add = is_add;
17225
17226   S (mp);
17227   W (ret);
17228   return ret;
17229 }
17230
17231 static int
17232 api_punt (vat_main_t * vam)
17233 {
17234   unformat_input_t *i = vam->input;
17235   vl_api_punt_t *mp;
17236   u32 ipv = ~0;
17237   u32 protocol = ~0;
17238   u32 port = ~0;
17239   int is_add = 1;
17240   int ret;
17241
17242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17243     {
17244       if (unformat (i, "ip %d", &ipv))
17245         ;
17246       else if (unformat (i, "protocol %d", &protocol))
17247         ;
17248       else if (unformat (i, "port %d", &port))
17249         ;
17250       else if (unformat (i, "del"))
17251         is_add = 0;
17252       else
17253         {
17254           clib_warning ("parse error '%U'", format_unformat_error, i);
17255           return -99;
17256         }
17257     }
17258
17259   M (PUNT, mp);
17260
17261   mp->is_add = (u8) is_add;
17262   mp->ipv = (u8) ipv;
17263   mp->l4_protocol = (u8) protocol;
17264   mp->l4_port = htons ((u16) port);
17265
17266   S (mp);
17267   W (ret);
17268   return ret;
17269 }
17270
17271 static void vl_api_ipsec_gre_tunnel_details_t_handler
17272   (vl_api_ipsec_gre_tunnel_details_t * mp)
17273 {
17274   vat_main_t *vam = &vat_main;
17275
17276   print (vam->ofp, "%11d%15U%15U%14d%14d",
17277          ntohl (mp->sw_if_index),
17278          format_ip4_address, &mp->src_address,
17279          format_ip4_address, &mp->dst_address,
17280          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
17281 }
17282
17283 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
17284   (vl_api_ipsec_gre_tunnel_details_t * mp)
17285 {
17286   vat_main_t *vam = &vat_main;
17287   vat_json_node_t *node = NULL;
17288   struct in_addr ip4;
17289
17290   if (VAT_JSON_ARRAY != vam->json_tree.type)
17291     {
17292       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17293       vat_json_init_array (&vam->json_tree);
17294     }
17295   node = vat_json_array_add (&vam->json_tree);
17296
17297   vat_json_init_object (node);
17298   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17299   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
17300   vat_json_object_add_ip4 (node, "src_address", ip4);
17301   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
17302   vat_json_object_add_ip4 (node, "dst_address", ip4);
17303   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
17304   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
17305 }
17306
17307 static int
17308 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
17309 {
17310   unformat_input_t *i = vam->input;
17311   vl_api_ipsec_gre_tunnel_dump_t *mp;
17312   vl_api_control_ping_t *mp_ping;
17313   u32 sw_if_index;
17314   u8 sw_if_index_set = 0;
17315   int ret;
17316
17317   /* Parse args required to build the message */
17318   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17319     {
17320       if (unformat (i, "sw_if_index %d", &sw_if_index))
17321         sw_if_index_set = 1;
17322       else
17323         break;
17324     }
17325
17326   if (sw_if_index_set == 0)
17327     {
17328       sw_if_index = ~0;
17329     }
17330
17331   if (!vam->json_output)
17332     {
17333       print (vam->ofp, "%11s%15s%15s%14s%14s",
17334              "sw_if_index", "src_address", "dst_address",
17335              "local_sa_id", "remote_sa_id");
17336     }
17337
17338   /* Get list of gre-tunnel interfaces */
17339   M (IPSEC_GRE_TUNNEL_DUMP, mp);
17340
17341   mp->sw_if_index = htonl (sw_if_index);
17342
17343   S (mp);
17344
17345   /* Use a control ping for synchronization */
17346   M (CONTROL_PING, mp_ping);
17347   S (mp_ping);
17348
17349   W (ret);
17350   return ret;
17351 }
17352
17353 static int
17354 api_delete_subif (vat_main_t * vam)
17355 {
17356   unformat_input_t *i = vam->input;
17357   vl_api_delete_subif_t *mp;
17358   u32 sw_if_index = ~0;
17359   int ret;
17360
17361   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17362     {
17363       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17364         ;
17365       if (unformat (i, "sw_if_index %d", &sw_if_index))
17366         ;
17367       else
17368         break;
17369     }
17370
17371   if (sw_if_index == ~0)
17372     {
17373       errmsg ("missing sw_if_index");
17374       return -99;
17375     }
17376
17377   /* Construct the API message */
17378   M (DELETE_SUBIF, mp);
17379   mp->sw_if_index = ntohl (sw_if_index);
17380
17381   S (mp);
17382   W (ret);
17383   return ret;
17384 }
17385
17386 #define foreach_pbb_vtr_op      \
17387 _("disable",  L2_VTR_DISABLED)  \
17388 _("pop",  L2_VTR_POP_2)         \
17389 _("push",  L2_VTR_PUSH_2)
17390
17391 static int
17392 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
17393 {
17394   unformat_input_t *i = vam->input;
17395   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
17396   u32 sw_if_index = ~0, vtr_op = ~0;
17397   u16 outer_tag = ~0;
17398   u8 dmac[6], smac[6];
17399   u8 dmac_set = 0, smac_set = 0;
17400   u16 vlanid = 0;
17401   u32 sid = ~0;
17402   u32 tmp;
17403   int ret;
17404
17405   /* Shut up coverity */
17406   memset (dmac, 0, sizeof (dmac));
17407   memset (smac, 0, sizeof (smac));
17408
17409   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17410     {
17411       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17412         ;
17413       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17414         ;
17415       else if (unformat (i, "vtr_op %d", &vtr_op))
17416         ;
17417 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
17418       foreach_pbb_vtr_op
17419 #undef _
17420         else if (unformat (i, "translate_pbb_stag"))
17421         {
17422           if (unformat (i, "%d", &tmp))
17423             {
17424               vtr_op = L2_VTR_TRANSLATE_2_1;
17425               outer_tag = tmp;
17426             }
17427           else
17428             {
17429               errmsg
17430                 ("translate_pbb_stag operation requires outer tag definition");
17431               return -99;
17432             }
17433         }
17434       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
17435         dmac_set++;
17436       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
17437         smac_set++;
17438       else if (unformat (i, "sid %d", &sid))
17439         ;
17440       else if (unformat (i, "vlanid %d", &tmp))
17441         vlanid = tmp;
17442       else
17443         {
17444           clib_warning ("parse error '%U'", format_unformat_error, i);
17445           return -99;
17446         }
17447     }
17448
17449   if ((sw_if_index == ~0) || (vtr_op == ~0))
17450     {
17451       errmsg ("missing sw_if_index or vtr operation");
17452       return -99;
17453     }
17454   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
17455       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
17456     {
17457       errmsg
17458         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
17459       return -99;
17460     }
17461
17462   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
17463   mp->sw_if_index = ntohl (sw_if_index);
17464   mp->vtr_op = ntohl (vtr_op);
17465   mp->outer_tag = ntohs (outer_tag);
17466   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
17467   clib_memcpy (mp->b_smac, smac, sizeof (smac));
17468   mp->b_vlanid = ntohs (vlanid);
17469   mp->i_sid = ntohl (sid);
17470
17471   S (mp);
17472   W (ret);
17473   return ret;
17474 }
17475
17476 static int
17477 api_flow_classify_set_interface (vat_main_t * vam)
17478 {
17479   unformat_input_t *i = vam->input;
17480   vl_api_flow_classify_set_interface_t *mp;
17481   u32 sw_if_index;
17482   int sw_if_index_set;
17483   u32 ip4_table_index = ~0;
17484   u32 ip6_table_index = ~0;
17485   u8 is_add = 1;
17486   int ret;
17487
17488   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17489     {
17490       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17491         sw_if_index_set = 1;
17492       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17493         sw_if_index_set = 1;
17494       else if (unformat (i, "del"))
17495         is_add = 0;
17496       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17497         ;
17498       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17499         ;
17500       else
17501         {
17502           clib_warning ("parse error '%U'", format_unformat_error, i);
17503           return -99;
17504         }
17505     }
17506
17507   if (sw_if_index_set == 0)
17508     {
17509       errmsg ("missing interface name or sw_if_index");
17510       return -99;
17511     }
17512
17513   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
17514
17515   mp->sw_if_index = ntohl (sw_if_index);
17516   mp->ip4_table_index = ntohl (ip4_table_index);
17517   mp->ip6_table_index = ntohl (ip6_table_index);
17518   mp->is_add = is_add;
17519
17520   S (mp);
17521   W (ret);
17522   return ret;
17523 }
17524
17525 static int
17526 api_flow_classify_dump (vat_main_t * vam)
17527 {
17528   unformat_input_t *i = vam->input;
17529   vl_api_flow_classify_dump_t *mp;
17530   vl_api_control_ping_t *mp_ping;
17531   u8 type = FLOW_CLASSIFY_N_TABLES;
17532   int ret;
17533
17534   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
17535     ;
17536   else
17537     {
17538       errmsg ("classify table type must be specified");
17539       return -99;
17540     }
17541
17542   if (!vam->json_output)
17543     {
17544       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17545     }
17546
17547   M (FLOW_CLASSIFY_DUMP, mp);
17548   mp->type = type;
17549   /* send it... */
17550   S (mp);
17551
17552   /* Use a control ping for synchronization */
17553   M (CONTROL_PING, mp_ping);
17554   S (mp_ping);
17555
17556   /* Wait for a reply... */
17557   W (ret);
17558   return ret;
17559 }
17560
17561 static int
17562 api_feature_enable_disable (vat_main_t * vam)
17563 {
17564   unformat_input_t *i = vam->input;
17565   vl_api_feature_enable_disable_t *mp;
17566   u8 *arc_name = 0;
17567   u8 *feature_name = 0;
17568   u32 sw_if_index = ~0;
17569   u8 enable = 1;
17570   int ret;
17571
17572   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17573     {
17574       if (unformat (i, "arc_name %s", &arc_name))
17575         ;
17576       else if (unformat (i, "feature_name %s", &feature_name))
17577         ;
17578       else
17579         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17580         ;
17581       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17582         ;
17583       else if (unformat (i, "disable"))
17584         enable = 0;
17585       else
17586         break;
17587     }
17588
17589   if (arc_name == 0)
17590     {
17591       errmsg ("missing arc name");
17592       return -99;
17593     }
17594   if (vec_len (arc_name) > 63)
17595     {
17596       errmsg ("arc name too long");
17597     }
17598
17599   if (feature_name == 0)
17600     {
17601       errmsg ("missing feature name");
17602       return -99;
17603     }
17604   if (vec_len (feature_name) > 63)
17605     {
17606       errmsg ("feature name too long");
17607     }
17608
17609   if (sw_if_index == ~0)
17610     {
17611       errmsg ("missing interface name or sw_if_index");
17612       return -99;
17613     }
17614
17615   /* Construct the API message */
17616   M (FEATURE_ENABLE_DISABLE, mp);
17617   mp->sw_if_index = ntohl (sw_if_index);
17618   mp->enable = enable;
17619   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
17620   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
17621   vec_free (arc_name);
17622   vec_free (feature_name);
17623
17624   S (mp);
17625   W (ret);
17626   return ret;
17627 }
17628
17629 static int
17630 api_sw_interface_tag_add_del (vat_main_t * vam)
17631 {
17632   unformat_input_t *i = vam->input;
17633   vl_api_sw_interface_tag_add_del_t *mp;
17634   u32 sw_if_index = ~0;
17635   u8 *tag = 0;
17636   u8 enable = 1;
17637   int ret;
17638
17639   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17640     {
17641       if (unformat (i, "tag %s", &tag))
17642         ;
17643       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17644         ;
17645       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17646         ;
17647       else if (unformat (i, "del"))
17648         enable = 0;
17649       else
17650         break;
17651     }
17652
17653   if (sw_if_index == ~0)
17654     {
17655       errmsg ("missing interface name or sw_if_index");
17656       return -99;
17657     }
17658
17659   if (enable && (tag == 0))
17660     {
17661       errmsg ("no tag specified");
17662       return -99;
17663     }
17664
17665   /* Construct the API message */
17666   M (SW_INTERFACE_TAG_ADD_DEL, mp);
17667   mp->sw_if_index = ntohl (sw_if_index);
17668   mp->is_add = enable;
17669   if (enable)
17670     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
17671   vec_free (tag);
17672
17673   S (mp);
17674   W (ret);
17675   return ret;
17676 }
17677
17678 static void vl_api_l2_xconnect_details_t_handler
17679   (vl_api_l2_xconnect_details_t * mp)
17680 {
17681   vat_main_t *vam = &vat_main;
17682
17683   print (vam->ofp, "%15d%15d",
17684          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
17685 }
17686
17687 static void vl_api_l2_xconnect_details_t_handler_json
17688   (vl_api_l2_xconnect_details_t * mp)
17689 {
17690   vat_main_t *vam = &vat_main;
17691   vat_json_node_t *node = NULL;
17692
17693   if (VAT_JSON_ARRAY != vam->json_tree.type)
17694     {
17695       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17696       vat_json_init_array (&vam->json_tree);
17697     }
17698   node = vat_json_array_add (&vam->json_tree);
17699
17700   vat_json_init_object (node);
17701   vat_json_object_add_uint (node, "rx_sw_if_index",
17702                             ntohl (mp->rx_sw_if_index));
17703   vat_json_object_add_uint (node, "tx_sw_if_index",
17704                             ntohl (mp->tx_sw_if_index));
17705 }
17706
17707 static int
17708 api_l2_xconnect_dump (vat_main_t * vam)
17709 {
17710   vl_api_l2_xconnect_dump_t *mp;
17711   vl_api_control_ping_t *mp_ping;
17712   int ret;
17713
17714   if (!vam->json_output)
17715     {
17716       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
17717     }
17718
17719   M (L2_XCONNECT_DUMP, mp);
17720
17721   S (mp);
17722
17723   /* Use a control ping for synchronization */
17724   M (CONTROL_PING, mp_ping);
17725   S (mp_ping);
17726
17727   W (ret);
17728   return ret;
17729 }
17730
17731 static int
17732 api_sw_interface_set_mtu (vat_main_t * vam)
17733 {
17734   unformat_input_t *i = vam->input;
17735   vl_api_sw_interface_set_mtu_t *mp;
17736   u32 sw_if_index = ~0;
17737   u32 mtu = 0;
17738   int ret;
17739
17740   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17741     {
17742       if (unformat (i, "mtu %d", &mtu))
17743         ;
17744       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17745         ;
17746       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17747         ;
17748       else
17749         break;
17750     }
17751
17752   if (sw_if_index == ~0)
17753     {
17754       errmsg ("missing interface name or sw_if_index");
17755       return -99;
17756     }
17757
17758   if (mtu == 0)
17759     {
17760       errmsg ("no mtu specified");
17761       return -99;
17762     }
17763
17764   /* Construct the API message */
17765   M (SW_INTERFACE_SET_MTU, mp);
17766   mp->sw_if_index = ntohl (sw_if_index);
17767   mp->mtu = ntohs ((u16) mtu);
17768
17769   S (mp);
17770   W (ret);
17771   return ret;
17772 }
17773
17774
17775 static int
17776 q_or_quit (vat_main_t * vam)
17777 {
17778 #if VPP_API_TEST_BUILTIN == 0
17779   longjmp (vam->jump_buf, 1);
17780 #endif
17781   return 0;                     /* not so much */
17782 }
17783
17784 static int
17785 q (vat_main_t * vam)
17786 {
17787   return q_or_quit (vam);
17788 }
17789
17790 static int
17791 quit (vat_main_t * vam)
17792 {
17793   return q_or_quit (vam);
17794 }
17795
17796 static int
17797 comment (vat_main_t * vam)
17798 {
17799   return 0;
17800 }
17801
17802 static int
17803 cmd_cmp (void *a1, void *a2)
17804 {
17805   u8 **c1 = a1;
17806   u8 **c2 = a2;
17807
17808   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
17809 }
17810
17811 static int
17812 help (vat_main_t * vam)
17813 {
17814   u8 **cmds = 0;
17815   u8 *name = 0;
17816   hash_pair_t *p;
17817   unformat_input_t *i = vam->input;
17818   int j;
17819
17820   if (unformat (i, "%s", &name))
17821     {
17822       uword *hs;
17823
17824       vec_add1 (name, 0);
17825
17826       hs = hash_get_mem (vam->help_by_name, name);
17827       if (hs)
17828         print (vam->ofp, "usage: %s %s", name, hs[0]);
17829       else
17830         print (vam->ofp, "No such msg / command '%s'", name);
17831       vec_free (name);
17832       return 0;
17833     }
17834
17835   print (vam->ofp, "Help is available for the following:");
17836
17837     /* *INDENT-OFF* */
17838     hash_foreach_pair (p, vam->function_by_name,
17839     ({
17840       vec_add1 (cmds, (u8 *)(p->key));
17841     }));
17842     /* *INDENT-ON* */
17843
17844   vec_sort_with_function (cmds, cmd_cmp);
17845
17846   for (j = 0; j < vec_len (cmds); j++)
17847     print (vam->ofp, "%s", cmds[j]);
17848
17849   vec_free (cmds);
17850   return 0;
17851 }
17852
17853 static int
17854 set (vat_main_t * vam)
17855 {
17856   u8 *name = 0, *value = 0;
17857   unformat_input_t *i = vam->input;
17858
17859   if (unformat (i, "%s", &name))
17860     {
17861       /* The input buffer is a vector, not a string. */
17862       value = vec_dup (i->buffer);
17863       vec_delete (value, i->index, 0);
17864       /* Almost certainly has a trailing newline */
17865       if (value[vec_len (value) - 1] == '\n')
17866         value[vec_len (value) - 1] = 0;
17867       /* Make sure it's a proper string, one way or the other */
17868       vec_add1 (value, 0);
17869       (void) clib_macro_set_value (&vam->macro_main,
17870                                    (char *) name, (char *) value);
17871     }
17872   else
17873     errmsg ("usage: set <name> <value>");
17874
17875   vec_free (name);
17876   vec_free (value);
17877   return 0;
17878 }
17879
17880 static int
17881 unset (vat_main_t * vam)
17882 {
17883   u8 *name = 0;
17884
17885   if (unformat (vam->input, "%s", &name))
17886     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
17887       errmsg ("unset: %s wasn't set", name);
17888   vec_free (name);
17889   return 0;
17890 }
17891
17892 typedef struct
17893 {
17894   u8 *name;
17895   u8 *value;
17896 } macro_sort_t;
17897
17898
17899 static int
17900 macro_sort_cmp (void *a1, void *a2)
17901 {
17902   macro_sort_t *s1 = a1;
17903   macro_sort_t *s2 = a2;
17904
17905   return strcmp ((char *) (s1->name), (char *) (s2->name));
17906 }
17907
17908 static int
17909 dump_macro_table (vat_main_t * vam)
17910 {
17911   macro_sort_t *sort_me = 0, *sm;
17912   int i;
17913   hash_pair_t *p;
17914
17915     /* *INDENT-OFF* */
17916     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
17917     ({
17918       vec_add2 (sort_me, sm, 1);
17919       sm->name = (u8 *)(p->key);
17920       sm->value = (u8 *) (p->value[0]);
17921     }));
17922     /* *INDENT-ON* */
17923
17924   vec_sort_with_function (sort_me, macro_sort_cmp);
17925
17926   if (vec_len (sort_me))
17927     print (vam->ofp, "%-15s%s", "Name", "Value");
17928   else
17929     print (vam->ofp, "The macro table is empty...");
17930
17931   for (i = 0; i < vec_len (sort_me); i++)
17932     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
17933   return 0;
17934 }
17935
17936 static int
17937 dump_node_table (vat_main_t * vam)
17938 {
17939   int i, j;
17940   vlib_node_t *node, *next_node;
17941
17942   if (vec_len (vam->graph_nodes) == 0)
17943     {
17944       print (vam->ofp, "Node table empty, issue get_node_graph...");
17945       return 0;
17946     }
17947
17948   for (i = 0; i < vec_len (vam->graph_nodes); i++)
17949     {
17950       node = vam->graph_nodes[i];
17951       print (vam->ofp, "[%d] %s", i, node->name);
17952       for (j = 0; j < vec_len (node->next_nodes); j++)
17953         {
17954           if (node->next_nodes[j] != ~0)
17955             {
17956               next_node = vam->graph_nodes[node->next_nodes[j]];
17957               print (vam->ofp, "  [%d] %s", j, next_node->name);
17958             }
17959         }
17960     }
17961   return 0;
17962 }
17963
17964 static int
17965 value_sort_cmp (void *a1, void *a2)
17966 {
17967   name_sort_t *n1 = a1;
17968   name_sort_t *n2 = a2;
17969
17970   if (n1->value < n2->value)
17971     return -1;
17972   if (n1->value > n2->value)
17973     return 1;
17974   return 0;
17975 }
17976
17977
17978 static int
17979 dump_msg_api_table (vat_main_t * vam)
17980 {
17981   api_main_t *am = &api_main;
17982   name_sort_t *nses = 0, *ns;
17983   hash_pair_t *hp;
17984   int i;
17985
17986   /* *INDENT-OFF* */
17987   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
17988   ({
17989     vec_add2 (nses, ns, 1);
17990     ns->name = (u8 *)(hp->key);
17991     ns->value = (u32) hp->value[0];
17992   }));
17993   /* *INDENT-ON* */
17994
17995   vec_sort_with_function (nses, value_sort_cmp);
17996
17997   for (i = 0; i < vec_len (nses); i++)
17998     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
17999   vec_free (nses);
18000   return 0;
18001 }
18002
18003 static int
18004 get_msg_id (vat_main_t * vam)
18005 {
18006   u8 *name_and_crc;
18007   u32 message_index;
18008
18009   if (unformat (vam->input, "%s", &name_and_crc))
18010     {
18011       message_index = vl_api_get_msg_index (name_and_crc);
18012       if (message_index == ~0)
18013         {
18014           print (vam->ofp, " '%s' not found", name_and_crc);
18015           return 0;
18016         }
18017       print (vam->ofp, " '%s' has message index %d",
18018              name_and_crc, message_index);
18019       return 0;
18020     }
18021   errmsg ("name_and_crc required...");
18022   return 0;
18023 }
18024
18025 static int
18026 search_node_table (vat_main_t * vam)
18027 {
18028   unformat_input_t *line_input = vam->input;
18029   u8 *node_to_find;
18030   int j;
18031   vlib_node_t *node, *next_node;
18032   uword *p;
18033
18034   if (vam->graph_node_index_by_name == 0)
18035     {
18036       print (vam->ofp, "Node table empty, issue get_node_graph...");
18037       return 0;
18038     }
18039
18040   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
18041     {
18042       if (unformat (line_input, "%s", &node_to_find))
18043         {
18044           vec_add1 (node_to_find, 0);
18045           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
18046           if (p == 0)
18047             {
18048               print (vam->ofp, "%s not found...", node_to_find);
18049               goto out;
18050             }
18051           node = vam->graph_nodes[p[0]];
18052           print (vam->ofp, "[%d] %s", p[0], node->name);
18053           for (j = 0; j < vec_len (node->next_nodes); j++)
18054             {
18055               if (node->next_nodes[j] != ~0)
18056                 {
18057                   next_node = vam->graph_nodes[node->next_nodes[j]];
18058                   print (vam->ofp, "  [%d] %s", j, next_node->name);
18059                 }
18060             }
18061         }
18062
18063       else
18064         {
18065           clib_warning ("parse error '%U'", format_unformat_error,
18066                         line_input);
18067           return -99;
18068         }
18069
18070     out:
18071       vec_free (node_to_find);
18072
18073     }
18074
18075   return 0;
18076 }
18077
18078
18079 static int
18080 script (vat_main_t * vam)
18081 {
18082 #if (VPP_API_TEST_BUILTIN==0)
18083   u8 *s = 0;
18084   char *save_current_file;
18085   unformat_input_t save_input;
18086   jmp_buf save_jump_buf;
18087   u32 save_line_number;
18088
18089   FILE *new_fp, *save_ifp;
18090
18091   if (unformat (vam->input, "%s", &s))
18092     {
18093       new_fp = fopen ((char *) s, "r");
18094       if (new_fp == 0)
18095         {
18096           errmsg ("Couldn't open script file %s", s);
18097           vec_free (s);
18098           return -99;
18099         }
18100     }
18101   else
18102     {
18103       errmsg ("Missing script name");
18104       return -99;
18105     }
18106
18107   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
18108   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
18109   save_ifp = vam->ifp;
18110   save_line_number = vam->input_line_number;
18111   save_current_file = (char *) vam->current_file;
18112
18113   vam->input_line_number = 0;
18114   vam->ifp = new_fp;
18115   vam->current_file = s;
18116   do_one_file (vam);
18117
18118   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
18119   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
18120   vam->ifp = save_ifp;
18121   vam->input_line_number = save_line_number;
18122   vam->current_file = (u8 *) save_current_file;
18123   vec_free (s);
18124
18125   return 0;
18126 #else
18127   clib_warning ("use the exec command...");
18128   return -99;
18129 #endif
18130 }
18131
18132 static int
18133 echo (vat_main_t * vam)
18134 {
18135   print (vam->ofp, "%v", vam->input->buffer);
18136   return 0;
18137 }
18138
18139 /* List of API message constructors, CLI names map to api_xxx */
18140 #define foreach_vpe_api_msg                                             \
18141 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
18142 _(sw_interface_dump,"")                                                 \
18143 _(sw_interface_set_flags,                                               \
18144   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
18145 _(sw_interface_add_del_address,                                         \
18146   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
18147 _(sw_interface_set_table,                                               \
18148   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
18149 _(sw_interface_set_mpls_enable,                                         \
18150   "<intfc> | sw_if_index [disable | dis]")                              \
18151 _(sw_interface_set_vpath,                                               \
18152   "<intfc> | sw_if_index <id> enable | disable")                        \
18153 _(sw_interface_set_vxlan_bypass,                                        \
18154   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
18155 _(sw_interface_set_l2_xconnect,                                         \
18156   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18157   "enable | disable")                                                   \
18158 _(sw_interface_set_l2_bridge,                                           \
18159   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"               \
18160   "[shg <split-horizon-group>] [bvi]\n"                                 \
18161   "enable | disable")                                                   \
18162 _(bridge_domain_add_del,                                                \
18163   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n") \
18164 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
18165 _(l2fib_add_del,                                                        \
18166   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
18167 _(l2_flags,                                                             \
18168   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
18169 _(bridge_flags,                                                         \
18170   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
18171 _(tap_connect,                                                          \
18172   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
18173 _(tap_modify,                                                           \
18174   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
18175 _(tap_delete,                                                           \
18176   "<vpp-if-name> | sw_if_index <id>")                                   \
18177 _(sw_interface_tap_dump, "")                                            \
18178 _(ip_add_del_route,                                                     \
18179   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
18180   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
18181   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
18182   "[multipath] [count <n>]")                                            \
18183 _(ip_mroute_add_del,                                                    \
18184   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
18185   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
18186 _(mpls_route_add_del,                                                   \
18187   "<label> <eos> via <addr> [table-id <n>]\n"                           \
18188   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
18189   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
18190   "[multipath] [count <n>]")                                            \
18191 _(mpls_ip_bind_unbind,                                                  \
18192   "<label> <addr/len>")                                                 \
18193 _(mpls_tunnel_add_del,                                                  \
18194   " via <addr> [table-id <n>]\n"                                        \
18195   "sw_if_index <id>] [l2]  [del]")                                      \
18196 _(proxy_arp_add_del,                                                    \
18197   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
18198 _(proxy_arp_intfc_enable_disable,                                       \
18199   "<intfc> | sw_if_index <id> enable | disable")                        \
18200 _(sw_interface_set_unnumbered,                                          \
18201   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
18202 _(ip_neighbor_add_del,                                                  \
18203   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
18204   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
18205 _(reset_vrf, "vrf <id> [ipv6]")                                         \
18206 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
18207 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
18208   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
18209   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
18210   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
18211 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
18212 _(reset_fib, "vrf <n> [ipv6]")                                          \
18213 _(dhcp_proxy_config,                                                    \
18214   "svr <v46-address> src <v46-address>\n"                               \
18215    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
18216 _(dhcp_proxy_set_vss,                                                   \
18217   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
18218 _(dhcp_proxy_dump, "ip6")                                               \
18219 _(dhcp_client_config,                                                   \
18220   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
18221 _(set_ip_flow_hash,                                                     \
18222   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
18223 _(sw_interface_ip6_enable_disable,                                      \
18224   "<intfc> | sw_if_index <id> enable | disable")                        \
18225 _(sw_interface_ip6_set_link_local_address,                              \
18226   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
18227 _(ip6nd_proxy_add_del,                                                  \
18228   "<intfc> | sw_if_index <id> <ip6-address>")                           \
18229 _(ip6nd_proxy_dump, "")                                                 \
18230 _(sw_interface_ip6nd_ra_prefix,                                         \
18231   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
18232   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
18233   "[nolink] [isno]")                                                    \
18234 _(sw_interface_ip6nd_ra_config,                                         \
18235   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
18236   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
18237   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
18238 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
18239 _(l2_patch_add_del,                                                     \
18240   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18241   "enable | disable")                                                   \
18242 _(sr_localsid_add_del,                                                  \
18243   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
18244   "fib-table <num> (end.psp) sw_if_index <num>")                        \
18245 _(classify_add_del_table,                                               \
18246   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
18247   " [del] [del-chain] mask <mask-value>\n"                              \
18248   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
18249   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
18250 _(classify_add_del_session,                                             \
18251   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
18252   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
18253   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
18254   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
18255 _(classify_set_interface_ip_table,                                      \
18256   "<intfc> | sw_if_index <nn> table <nn>")                              \
18257 _(classify_set_interface_l2_tables,                                     \
18258   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18259   "  [other-table <nn>]")                                               \
18260 _(get_node_index, "node <node-name")                                    \
18261 _(add_node_next, "node <node-name> next <next-node-name>")              \
18262 _(l2tpv3_create_tunnel,                                                 \
18263   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
18264   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
18265   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
18266 _(l2tpv3_set_tunnel_cookies,                                            \
18267   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
18268   "[new_remote_cookie <nn>]\n")                                         \
18269 _(l2tpv3_interface_enable_disable,                                      \
18270   "<intfc> | sw_if_index <nn> enable | disable")                        \
18271 _(l2tpv3_set_lookup_key,                                                \
18272   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
18273 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
18274 _(vxlan_add_del_tunnel,                                                 \
18275   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
18276   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
18277   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
18278 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
18279 _(gre_add_del_tunnel,                                                   \
18280   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
18281 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
18282 _(l2_fib_clear_table, "")                                               \
18283 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
18284 _(l2_interface_vlan_tag_rewrite,                                        \
18285   "<intfc> | sw_if_index <nn> \n"                                       \
18286   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
18287   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
18288 _(create_vhost_user_if,                                                 \
18289         "socket <filename> [server] [renumber <dev_instance>] "         \
18290         "[mac <mac_address>]")                                          \
18291 _(modify_vhost_user_if,                                                 \
18292         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
18293         "[server] [renumber <dev_instance>]")                           \
18294 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
18295 _(sw_interface_vhost_user_dump, "")                                     \
18296 _(show_version, "")                                                     \
18297 _(vxlan_gpe_add_del_tunnel,                                             \
18298   "local <addr> remote <addr> vni <nn>\n"                               \
18299     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
18300   "[next-ethernet] [next-nsh]\n")                                       \
18301 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
18302 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
18303 _(interface_name_renumber,                                              \
18304   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
18305 _(input_acl_set_interface,                                              \
18306   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18307   "  [l2-table <nn>] [del]")                                            \
18308 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
18309 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
18310 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
18311 _(ip_dump, "ipv4 | ipv6")                                               \
18312 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
18313 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
18314   "  spid_id <n> ")                                                     \
18315 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
18316   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
18317   "  integ_alg <alg> integ_key <hex>")                                  \
18318 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
18319   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
18320   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
18321   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
18322 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
18323 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
18324 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
18325   "(auth_data 0x<data> | auth_data <data>)")                            \
18326 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
18327   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
18328 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
18329   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
18330   "(local|remote)")                                                     \
18331 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
18332 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
18333 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18334 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18335 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
18336 _(ikev2_initiate_sa_init, "<profile_name>")                             \
18337 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
18338 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
18339 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
18340 _(delete_loopback,"sw_if_index <nn>")                                   \
18341 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
18342 _(map_add_domain,                                                       \
18343   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
18344   "ip6-src <ip6addr> "                                                  \
18345   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
18346 _(map_del_domain, "index <n>")                                          \
18347 _(map_add_del_rule,                                                     \
18348   "index <n> psid <n> dst <ip6addr> [del]")                             \
18349 _(map_domain_dump, "")                                                  \
18350 _(map_rule_dump, "index <map-domain>")                                  \
18351 _(want_interface_events,  "enable|disable")                             \
18352 _(want_stats,"enable|disable")                                          \
18353 _(get_first_msg_id, "client <name>")                                    \
18354 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
18355 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
18356   "fib-id <nn> [ip4][ip6][default]")                                    \
18357 _(get_node_graph, " ")                                                  \
18358 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
18359 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
18360 _(ioam_disable, "")                                                     \
18361 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
18362                             " sw_if_index <sw_if_index> p <priority> "  \
18363                             "w <weight>] [del]")                        \
18364 _(one_add_del_locator, "locator-set <locator_name> "                    \
18365                         "iface <intf> | sw_if_index <sw_if_index> "     \
18366                         "p <priority> w <weight> [del]")                \
18367 _(one_add_del_local_eid,"vni <vni> eid "                                \
18368                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
18369                          "locator-set <locator_name> [del]"             \
18370                          "[key-id sha1|sha256 secret-key <secret-key>]")\
18371 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
18372 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
18373 _(one_enable_disable, "enable|disable")                                 \
18374 _(one_map_register_enable_disable, "enable|disable")                    \
18375 _(one_rloc_probe_enable_disable, "enable|disable")                      \
18376 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
18377                                "[seid <seid>] "                         \
18378                                "rloc <locator> p <prio> "               \
18379                                "w <weight> [rloc <loc> ... ] "          \
18380                                "action <action> [del-all]")             \
18381 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
18382                           "<local-eid>")                                \
18383 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
18384 _(one_use_petr, "ip-address> | disable")                                \
18385 _(one_map_request_mode, "src-dst|dst-only")                             \
18386 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
18387 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
18388 _(one_locator_set_dump, "[local | remote]")                             \
18389 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
18390 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
18391                        "[local] | [remote]")                            \
18392 _(one_eid_table_vni_dump, "")                                           \
18393 _(one_eid_table_map_dump, "l2|l3")                                      \
18394 _(one_map_resolver_dump, "")                                            \
18395 _(one_map_server_dump, "")                                              \
18396 _(one_adjacencies_get, "vni <vni>")                                     \
18397 _(show_one_rloc_probe_state, "")                                        \
18398 _(show_one_map_register_state, "")                                      \
18399 _(show_one_status, "")                                                  \
18400 _(one_get_map_request_itr_rlocs, "")                                    \
18401 _(show_one_pitr, "")                                                    \
18402 _(show_one_use_petr, "")                                                \
18403 _(show_one_map_request_mode, "")                                        \
18404 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
18405                             " sw_if_index <sw_if_index> p <priority> "  \
18406                             "w <weight>] [del]")                        \
18407 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
18408                         "iface <intf> | sw_if_index <sw_if_index> "     \
18409                         "p <priority> w <weight> [del]")                \
18410 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
18411                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
18412                          "locator-set <locator_name> [del]"             \
18413                          "[key-id sha1|sha256 secret-key <secret-key>]") \
18414 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
18415 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
18416 _(lisp_enable_disable, "enable|disable")                                \
18417 _(lisp_map_register_enable_disable, "enable|disable")                   \
18418 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
18419 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
18420                                "[seid <seid>] "                         \
18421                                "rloc <locator> p <prio> "               \
18422                                "w <weight> [rloc <loc> ... ] "          \
18423                                "action <action> [del-all]")             \
18424 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
18425                           "<local-eid>")                                \
18426 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
18427 _(lisp_use_petr, "<ip-address> | disable")                              \
18428 _(lisp_map_request_mode, "src-dst|dst-only")                            \
18429 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
18430 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
18431 _(lisp_locator_set_dump, "[local | remote]")                            \
18432 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
18433 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
18434                        "[local] | [remote]")                            \
18435 _(lisp_eid_table_vni_dump, "")                                          \
18436 _(lisp_eid_table_map_dump, "l2|l3")                                     \
18437 _(lisp_map_resolver_dump, "")                                           \
18438 _(lisp_map_server_dump, "")                                             \
18439 _(lisp_adjacencies_get, "vni <vni>")                                    \
18440 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
18441 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
18442 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
18443 _(gpe_get_encap_mode, "")                                               \
18444 _(lisp_gpe_add_del_iface, "up|down")                                    \
18445 _(lisp_gpe_enable_disable, "enable|disable")                            \
18446 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
18447   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
18448 _(show_lisp_rloc_probe_state, "")                                       \
18449 _(show_lisp_map_register_state, "")                                     \
18450 _(show_lisp_status, "")                                                 \
18451 _(lisp_get_map_request_itr_rlocs, "")                                   \
18452 _(show_lisp_pitr, "")                                                   \
18453 _(show_lisp_use_petr, "")                                               \
18454 _(show_lisp_map_request_mode, "")                                       \
18455 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
18456 _(af_packet_delete, "name <host interface name>")                       \
18457 _(policer_add_del, "name <policer name> <params> [del]")                \
18458 _(policer_dump, "[name <policer name>]")                                \
18459 _(policer_classify_set_interface,                                       \
18460   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18461   "  [l2-table <nn>] [del]")                                            \
18462 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
18463 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
18464     "[master|slave]")                                                   \
18465 _(netmap_delete, "name <interface name>")                               \
18466 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
18467 _(mpls_fib_dump, "")                                                    \
18468 _(classify_table_ids, "")                                               \
18469 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
18470 _(classify_table_info, "table_id <nn>")                                 \
18471 _(classify_session_dump, "table_id <nn>")                               \
18472 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
18473     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
18474     "[template_interval <nn>] [udp_checksum]")                          \
18475 _(ipfix_exporter_dump, "")                                              \
18476 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
18477 _(ipfix_classify_stream_dump, "")                                       \
18478 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
18479 _(ipfix_classify_table_dump, "")                                        \
18480 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
18481 _(sw_interface_span_dump, "")                                           \
18482 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
18483 _(pg_create_interface, "if_id <nn>")                                    \
18484 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
18485 _(pg_enable_disable, "[stream <id>] disable")                           \
18486 _(ip_source_and_port_range_check_add_del,                               \
18487   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
18488 _(ip_source_and_port_range_check_interface_add_del,                     \
18489   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
18490   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
18491 _(ipsec_gre_add_del_tunnel,                                             \
18492   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
18493 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
18494 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
18495 _(l2_interface_pbb_tag_rewrite,                                         \
18496   "<intfc> | sw_if_index <nn> \n"                                       \
18497   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
18498   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
18499 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
18500 _(flow_classify_set_interface,                                          \
18501   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
18502 _(flow_classify_dump, "type [ip4|ip6]")                                 \
18503 _(ip_fib_dump, "")                                                      \
18504 _(ip_mfib_dump, "")                                                     \
18505 _(ip6_fib_dump, "")                                                     \
18506 _(ip6_mfib_dump, "")                                                    \
18507 _(feature_enable_disable, "arc_name <arc_name> "                        \
18508   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
18509 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
18510 "[disable]")                                                            \
18511 _(l2_xconnect_dump, "")                                                 \
18512 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
18513 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
18514 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
18515
18516 /* List of command functions, CLI names map directly to functions */
18517 #define foreach_cli_function                                    \
18518 _(comment, "usage: comment <ignore-rest-of-line>")              \
18519 _(dump_interface_table, "usage: dump_interface_table")          \
18520 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
18521 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
18522 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
18523 _(dump_stats_table, "usage: dump_stats_table")                  \
18524 _(dump_macro_table, "usage: dump_macro_table ")                 \
18525 _(dump_node_table, "usage: dump_node_table")                    \
18526 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
18527 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
18528 _(echo, "usage: echo <message>")                                \
18529 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
18530 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
18531 _(help, "usage: help")                                          \
18532 _(q, "usage: quit")                                             \
18533 _(quit, "usage: quit")                                          \
18534 _(search_node_table, "usage: search_node_table <name>...")      \
18535 _(set, "usage: set <variable-name> <value>")                    \
18536 _(script, "usage: script <file-name>")                          \
18537 _(unset, "usage: unset <variable-name>")
18538
18539 #define _(N,n)                                  \
18540     static void vl_api_##n##_t_handler_uni      \
18541     (vl_api_##n##_t * mp)                       \
18542     {                                           \
18543         vat_main_t * vam = &vat_main;           \
18544         if (vam->json_output) {                 \
18545             vl_api_##n##_t_handler_json(mp);    \
18546         } else {                                \
18547             vl_api_##n##_t_handler(mp);         \
18548         }                                       \
18549     }
18550 foreach_vpe_api_reply_msg;
18551 #if VPP_API_TEST_BUILTIN == 0
18552 foreach_standalone_reply_msg;
18553 #endif
18554 #undef _
18555
18556 void
18557 vat_api_hookup (vat_main_t * vam)
18558 {
18559 #define _(N,n)                                                  \
18560     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
18561                            vl_api_##n##_t_handler_uni,          \
18562                            vl_noop_handler,                     \
18563                            vl_api_##n##_t_endian,               \
18564                            vl_api_##n##_t_print,                \
18565                            sizeof(vl_api_##n##_t), 1);
18566   foreach_vpe_api_reply_msg;
18567 #if VPP_API_TEST_BUILTIN == 0
18568   foreach_standalone_reply_msg;
18569 #endif
18570 #undef _
18571
18572 #if (VPP_API_TEST_BUILTIN==0)
18573   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
18574
18575   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
18576
18577   vam->function_by_name = hash_create_string (0, sizeof (uword));
18578
18579   vam->help_by_name = hash_create_string (0, sizeof (uword));
18580 #endif
18581
18582   /* API messages we can send */
18583 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
18584   foreach_vpe_api_msg;
18585 #undef _
18586
18587   /* Help strings */
18588 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18589   foreach_vpe_api_msg;
18590 #undef _
18591
18592   /* CLI functions */
18593 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
18594   foreach_cli_function;
18595 #undef _
18596
18597   /* Help strings */
18598 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18599   foreach_cli_function;
18600 #undef _
18601 }
18602
18603 #if VPP_API_TEST_BUILTIN
18604 static clib_error_t *
18605 vat_api_hookup_shim (vlib_main_t * vm)
18606 {
18607   vat_api_hookup (&vat_main);
18608   return 0;
18609 }
18610
18611 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
18612 #endif
18613
18614 /*
18615  * fd.io coding-style-patch-verification: ON
18616  *
18617  * Local Variables:
18618  * eval: (c-set-style "gnu")
18619  * End:
18620  */