Fix remaining 32-bit compile issues
[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 #define VHOST_USER_POLLING_MODE   0
407 #define VHOST_USER_INTERRUPT_MODE 1
408 #define VHOST_USER_ADAPTIVE_MODE  2
409
410 static u8 *
411 api_format_vhost_user_operation_mode (u8 * s, va_list * va)
412 {
413   int operation_mode = va_arg (*va, int);
414
415   switch (operation_mode)
416     {
417     case VHOST_USER_POLLING_MODE:
418       s = format (s, "%-9s", "polling");
419       break;
420     case VHOST_USER_INTERRUPT_MODE:
421       s = format (s, "%-9s", "interrupt");
422       break;
423     default:
424       s = format (s, "%-9s", "invalid");
425     }
426   return s;
427 }
428
429 static uword
430 api_unformat_vhost_user_operation_mode (unformat_input_t * input,
431                                         va_list * args)
432 {
433   u8 *operation_mode = va_arg (*args, u8 *);
434   uword rc = 1;
435
436   if (unformat (input, "interrupt"))
437     *operation_mode = VHOST_USER_INTERRUPT_MODE;
438   else if (unformat (input, "polling"))
439     *operation_mode = VHOST_USER_POLLING_MODE;
440   else
441     rc = 0;
442
443   return rc;
444 }
445
446 static uword
447 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
448 {
449   u8 *r = va_arg (*args, u8 *);
450
451   if (unformat (input, "kbps"))
452     *r = SSE2_QOS_RATE_KBPS;
453   else if (unformat (input, "pps"))
454     *r = SSE2_QOS_RATE_PPS;
455   else
456     return 0;
457   return 1;
458 }
459
460 static uword
461 unformat_policer_round_type (unformat_input_t * input, va_list * args)
462 {
463   u8 *r = va_arg (*args, u8 *);
464
465   if (unformat (input, "closest"))
466     *r = SSE2_QOS_ROUND_TO_CLOSEST;
467   else if (unformat (input, "up"))
468     *r = SSE2_QOS_ROUND_TO_UP;
469   else if (unformat (input, "down"))
470     *r = SSE2_QOS_ROUND_TO_DOWN;
471   else
472     return 0;
473   return 1;
474 }
475
476 static uword
477 unformat_policer_type (unformat_input_t * input, va_list * args)
478 {
479   u8 *r = va_arg (*args, u8 *);
480
481   if (unformat (input, "1r2c"))
482     *r = SSE2_QOS_POLICER_TYPE_1R2C;
483   else if (unformat (input, "1r3c"))
484     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
485   else if (unformat (input, "2r3c-2698"))
486     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
487   else if (unformat (input, "2r3c-4115"))
488     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
489   else if (unformat (input, "2r3c-mef5cf1"))
490     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
491   else
492     return 0;
493   return 1;
494 }
495
496 static uword
497 unformat_dscp (unformat_input_t * input, va_list * va)
498 {
499   u8 *r = va_arg (*va, u8 *);
500
501   if (0);
502 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
503   foreach_vnet_dscp
504 #undef _
505     else
506     return 0;
507   return 1;
508 }
509
510 static uword
511 unformat_policer_action_type (unformat_input_t * input, va_list * va)
512 {
513   sse2_qos_pol_action_params_st *a
514     = va_arg (*va, sse2_qos_pol_action_params_st *);
515
516   if (unformat (input, "drop"))
517     a->action_type = SSE2_QOS_ACTION_DROP;
518   else if (unformat (input, "transmit"))
519     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
520   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
521     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
522   else
523     return 0;
524   return 1;
525 }
526
527 static uword
528 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
529 {
530   u32 *r = va_arg (*va, u32 *);
531   u32 tid;
532
533   if (unformat (input, "ip4"))
534     tid = POLICER_CLASSIFY_TABLE_IP4;
535   else if (unformat (input, "ip6"))
536     tid = POLICER_CLASSIFY_TABLE_IP6;
537   else if (unformat (input, "l2"))
538     tid = POLICER_CLASSIFY_TABLE_L2;
539   else
540     return 0;
541
542   *r = tid;
543   return 1;
544 }
545
546 static uword
547 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
548 {
549   u32 *r = va_arg (*va, u32 *);
550   u32 tid;
551
552   if (unformat (input, "ip4"))
553     tid = FLOW_CLASSIFY_TABLE_IP4;
554   else if (unformat (input, "ip6"))
555     tid = FLOW_CLASSIFY_TABLE_IP6;
556   else
557     return 0;
558
559   *r = tid;
560   return 1;
561 }
562
563 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
564 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
565 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
566 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
567
568 #if (VPP_API_TEST_BUILTIN==0)
569 uword
570 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
571 {
572   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
573   mfib_itf_attribute_t attr;
574
575   old = *iflags;
576   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
577   {
578     if (unformat (input, mfib_itf_flag_long_names[attr]))
579       *iflags |= (1 << attr);
580   }
581   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
582   {
583     if (unformat (input, mfib_itf_flag_names[attr]))
584       *iflags |= (1 << attr);
585   }
586
587   return (old == *iflags ? 0 : 1);
588 }
589
590 uword
591 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
592 {
593   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
594   mfib_entry_attribute_t attr;
595
596   old = *eflags;
597   FOR_EACH_MFIB_ATTRIBUTE (attr)
598   {
599     if (unformat (input, mfib_flag_long_names[attr]))
600       *eflags |= (1 << attr);
601   }
602   FOR_EACH_MFIB_ATTRIBUTE (attr)
603   {
604     if (unformat (input, mfib_flag_names[attr]))
605       *eflags |= (1 << attr);
606   }
607
608   return (old == *eflags ? 0 : 1);
609 }
610
611 u8 *
612 format_ip4_address (u8 * s, va_list * args)
613 {
614   u8 *a = va_arg (*args, u8 *);
615   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
616 }
617
618 u8 *
619 format_ip6_address (u8 * s, va_list * args)
620 {
621   ip6_address_t *a = va_arg (*args, ip6_address_t *);
622   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
623
624   i_max_n_zero = ARRAY_LEN (a->as_u16);
625   max_n_zeros = 0;
626   i_first_zero = i_max_n_zero;
627   n_zeros = 0;
628   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
629     {
630       u32 is_zero = a->as_u16[i] == 0;
631       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
632         {
633           i_first_zero = i;
634           n_zeros = 0;
635         }
636       n_zeros += is_zero;
637       if ((!is_zero && n_zeros > max_n_zeros)
638           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
639         {
640           i_max_n_zero = i_first_zero;
641           max_n_zeros = n_zeros;
642           i_first_zero = ARRAY_LEN (a->as_u16);
643           n_zeros = 0;
644         }
645     }
646
647   last_double_colon = 0;
648   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
649     {
650       if (i == i_max_n_zero && max_n_zeros > 1)
651         {
652           s = format (s, "::");
653           i += max_n_zeros - 1;
654           last_double_colon = 1;
655         }
656       else
657         {
658           s = format (s, "%s%x",
659                       (last_double_colon || i == 0) ? "" : ":",
660                       clib_net_to_host_u16 (a->as_u16[i]));
661           last_double_colon = 0;
662         }
663     }
664
665   return s;
666 }
667
668 /* Format an IP46 address. */
669 u8 *
670 format_ip46_address (u8 * s, va_list * args)
671 {
672   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
673   ip46_type_t type = va_arg (*args, ip46_type_t);
674   int is_ip4 = 1;
675
676   switch (type)
677     {
678     case IP46_TYPE_ANY:
679       is_ip4 = ip46_address_is_ip4 (ip46);
680       break;
681     case IP46_TYPE_IP4:
682       is_ip4 = 1;
683       break;
684     case IP46_TYPE_IP6:
685       is_ip4 = 0;
686       break;
687     }
688
689   return is_ip4 ?
690     format (s, "%U", format_ip4_address, &ip46->ip4) :
691     format (s, "%U", format_ip6_address, &ip46->ip6);
692 }
693
694 u8 *
695 format_ethernet_address (u8 * s, va_list * args)
696 {
697   u8 *a = va_arg (*args, u8 *);
698
699   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
700                  a[0], a[1], a[2], a[3], a[4], a[5]);
701 }
702 #endif
703
704 static void
705 increment_v4_address (ip4_address_t * a)
706 {
707   u32 v;
708
709   v = ntohl (a->as_u32) + 1;
710   a->as_u32 = ntohl (v);
711 }
712
713 static void
714 increment_v6_address (ip6_address_t * a)
715 {
716   u64 v0, v1;
717
718   v0 = clib_net_to_host_u64 (a->as_u64[0]);
719   v1 = clib_net_to_host_u64 (a->as_u64[1]);
720
721   v1 += 1;
722   if (v1 == 0)
723     v0 += 1;
724   a->as_u64[0] = clib_net_to_host_u64 (v0);
725   a->as_u64[1] = clib_net_to_host_u64 (v1);
726 }
727
728 static void
729 increment_mac_address (u64 * mac)
730 {
731   u64 tmp = *mac;
732
733   tmp = clib_net_to_host_u64 (tmp);
734   tmp += 1 << 16;               /* skip unused (least significant) octets */
735   tmp = clib_host_to_net_u64 (tmp);
736   *mac = tmp;
737 }
738
739 static void vl_api_create_loopback_reply_t_handler
740   (vl_api_create_loopback_reply_t * mp)
741 {
742   vat_main_t *vam = &vat_main;
743   i32 retval = ntohl (mp->retval);
744
745   vam->retval = retval;
746   vam->regenerate_interface_table = 1;
747   vam->sw_if_index = ntohl (mp->sw_if_index);
748   vam->result_ready = 1;
749 }
750
751 static void vl_api_create_loopback_reply_t_handler_json
752   (vl_api_create_loopback_reply_t * mp)
753 {
754   vat_main_t *vam = &vat_main;
755   vat_json_node_t node;
756
757   vat_json_init_object (&node);
758   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
759   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
760
761   vat_json_print (vam->ofp, &node);
762   vat_json_free (&node);
763   vam->retval = ntohl (mp->retval);
764   vam->result_ready = 1;
765 }
766
767 static void vl_api_create_loopback_instance_reply_t_handler
768   (vl_api_create_loopback_instance_reply_t * mp)
769 {
770   vat_main_t *vam = &vat_main;
771   i32 retval = ntohl (mp->retval);
772
773   vam->retval = retval;
774   vam->regenerate_interface_table = 1;
775   vam->sw_if_index = ntohl (mp->sw_if_index);
776   vam->result_ready = 1;
777 }
778
779 static void vl_api_create_loopback_instance_reply_t_handler_json
780   (vl_api_create_loopback_instance_reply_t * mp)
781 {
782   vat_main_t *vam = &vat_main;
783   vat_json_node_t node;
784
785   vat_json_init_object (&node);
786   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
787   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
788
789   vat_json_print (vam->ofp, &node);
790   vat_json_free (&node);
791   vam->retval = ntohl (mp->retval);
792   vam->result_ready = 1;
793 }
794
795 static void vl_api_af_packet_create_reply_t_handler
796   (vl_api_af_packet_create_reply_t * mp)
797 {
798   vat_main_t *vam = &vat_main;
799   i32 retval = ntohl (mp->retval);
800
801   vam->retval = retval;
802   vam->regenerate_interface_table = 1;
803   vam->sw_if_index = ntohl (mp->sw_if_index);
804   vam->result_ready = 1;
805 }
806
807 static void vl_api_af_packet_create_reply_t_handler_json
808   (vl_api_af_packet_create_reply_t * mp)
809 {
810   vat_main_t *vam = &vat_main;
811   vat_json_node_t node;
812
813   vat_json_init_object (&node);
814   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
815   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
816
817   vat_json_print (vam->ofp, &node);
818   vat_json_free (&node);
819
820   vam->retval = ntohl (mp->retval);
821   vam->result_ready = 1;
822 }
823
824 static void vl_api_create_vlan_subif_reply_t_handler
825   (vl_api_create_vlan_subif_reply_t * mp)
826 {
827   vat_main_t *vam = &vat_main;
828   i32 retval = ntohl (mp->retval);
829
830   vam->retval = retval;
831   vam->regenerate_interface_table = 1;
832   vam->sw_if_index = ntohl (mp->sw_if_index);
833   vam->result_ready = 1;
834 }
835
836 static void vl_api_create_vlan_subif_reply_t_handler_json
837   (vl_api_create_vlan_subif_reply_t * mp)
838 {
839   vat_main_t *vam = &vat_main;
840   vat_json_node_t node;
841
842   vat_json_init_object (&node);
843   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
844   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
845
846   vat_json_print (vam->ofp, &node);
847   vat_json_free (&node);
848
849   vam->retval = ntohl (mp->retval);
850   vam->result_ready = 1;
851 }
852
853 static void vl_api_create_subif_reply_t_handler
854   (vl_api_create_subif_reply_t * mp)
855 {
856   vat_main_t *vam = &vat_main;
857   i32 retval = ntohl (mp->retval);
858
859   vam->retval = retval;
860   vam->regenerate_interface_table = 1;
861   vam->sw_if_index = ntohl (mp->sw_if_index);
862   vam->result_ready = 1;
863 }
864
865 static void vl_api_create_subif_reply_t_handler_json
866   (vl_api_create_subif_reply_t * mp)
867 {
868   vat_main_t *vam = &vat_main;
869   vat_json_node_t node;
870
871   vat_json_init_object (&node);
872   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
873   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
874
875   vat_json_print (vam->ofp, &node);
876   vat_json_free (&node);
877
878   vam->retval = ntohl (mp->retval);
879   vam->result_ready = 1;
880 }
881
882 static void vl_api_interface_name_renumber_reply_t_handler
883   (vl_api_interface_name_renumber_reply_t * mp)
884 {
885   vat_main_t *vam = &vat_main;
886   i32 retval = ntohl (mp->retval);
887
888   vam->retval = retval;
889   vam->regenerate_interface_table = 1;
890   vam->result_ready = 1;
891 }
892
893 static void vl_api_interface_name_renumber_reply_t_handler_json
894   (vl_api_interface_name_renumber_reply_t * mp)
895 {
896   vat_main_t *vam = &vat_main;
897   vat_json_node_t node;
898
899   vat_json_init_object (&node);
900   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
901
902   vat_json_print (vam->ofp, &node);
903   vat_json_free (&node);
904
905   vam->retval = ntohl (mp->retval);
906   vam->result_ready = 1;
907 }
908
909 /*
910  * Special-case: build the interface table, maintain
911  * the next loopback sw_if_index vbl.
912  */
913 static void vl_api_sw_interface_details_t_handler
914   (vl_api_sw_interface_details_t * mp)
915 {
916   vat_main_t *vam = &vat_main;
917   u8 *s = format (0, "%s%c", mp->interface_name, 0);
918
919   hash_set_mem (vam->sw_if_index_by_interface_name, s,
920                 ntohl (mp->sw_if_index));
921
922   /* In sub interface case, fill the sub interface table entry */
923   if (mp->sw_if_index != mp->sup_sw_if_index)
924     {
925       sw_interface_subif_t *sub = NULL;
926
927       vec_add2 (vam->sw_if_subif_table, sub, 1);
928
929       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
930       strncpy ((char *) sub->interface_name, (char *) s,
931                vec_len (sub->interface_name));
932       sub->sw_if_index = ntohl (mp->sw_if_index);
933       sub->sub_id = ntohl (mp->sub_id);
934
935       sub->sub_dot1ad = mp->sub_dot1ad;
936       sub->sub_number_of_tags = mp->sub_number_of_tags;
937       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
938       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
939       sub->sub_exact_match = mp->sub_exact_match;
940       sub->sub_default = mp->sub_default;
941       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
942       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
943
944       /* vlan tag rewrite */
945       sub->vtr_op = ntohl (mp->vtr_op);
946       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
947       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
948       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
949     }
950 }
951
952 static void vl_api_sw_interface_details_t_handler_json
953   (vl_api_sw_interface_details_t * mp)
954 {
955   vat_main_t *vam = &vat_main;
956   vat_json_node_t *node = NULL;
957
958   if (VAT_JSON_ARRAY != vam->json_tree.type)
959     {
960       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
961       vat_json_init_array (&vam->json_tree);
962     }
963   node = vat_json_array_add (&vam->json_tree);
964
965   vat_json_init_object (node);
966   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
967   vat_json_object_add_uint (node, "sup_sw_if_index",
968                             ntohl (mp->sup_sw_if_index));
969   vat_json_object_add_uint (node, "l2_address_length",
970                             ntohl (mp->l2_address_length));
971   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
972                              sizeof (mp->l2_address));
973   vat_json_object_add_string_copy (node, "interface_name",
974                                    mp->interface_name);
975   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
976   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
977   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
978   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
979   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
980   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
981   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
982   vat_json_object_add_uint (node, "sub_number_of_tags",
983                             mp->sub_number_of_tags);
984   vat_json_object_add_uint (node, "sub_outer_vlan_id",
985                             ntohs (mp->sub_outer_vlan_id));
986   vat_json_object_add_uint (node, "sub_inner_vlan_id",
987                             ntohs (mp->sub_inner_vlan_id));
988   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
989   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
990   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
991                             mp->sub_outer_vlan_id_any);
992   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
993                             mp->sub_inner_vlan_id_any);
994   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
995   vat_json_object_add_uint (node, "vtr_push_dot1q",
996                             ntohl (mp->vtr_push_dot1q));
997   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
998   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
999   if (mp->sub_dot1ah)
1000     {
1001       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1002                                        format (0, "%U",
1003                                                format_ethernet_address,
1004                                                &mp->b_dmac));
1005       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1006                                        format (0, "%U",
1007                                                format_ethernet_address,
1008                                                &mp->b_smac));
1009       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1010       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1011     }
1012 }
1013
1014 #if VPP_API_TEST_BUILTIN == 0
1015 static void vl_api_sw_interface_set_flags_t_handler
1016   (vl_api_sw_interface_set_flags_t * mp)
1017 {
1018   vat_main_t *vam = &vat_main;
1019   if (vam->interface_event_display)
1020     errmsg ("interface flags: sw_if_index %d %s %s",
1021             ntohl (mp->sw_if_index),
1022             mp->admin_up_down ? "admin-up" : "admin-down",
1023             mp->link_up_down ? "link-up" : "link-down");
1024 }
1025 #endif
1026
1027 static void vl_api_sw_interface_set_flags_t_handler_json
1028   (vl_api_sw_interface_set_flags_t * mp)
1029 {
1030   /* JSON output not supported */
1031 }
1032
1033 static void
1034 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1035 {
1036   vat_main_t *vam = &vat_main;
1037   i32 retval = ntohl (mp->retval);
1038
1039   vam->retval = retval;
1040   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1041   vam->result_ready = 1;
1042 }
1043
1044 static void
1045 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1046 {
1047   vat_main_t *vam = &vat_main;
1048   vat_json_node_t node;
1049   api_main_t *am = &api_main;
1050   void *oldheap;
1051   u8 *reply;
1052
1053   vat_json_init_object (&node);
1054   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1055   vat_json_object_add_uint (&node, "reply_in_shmem",
1056                             ntohl (mp->reply_in_shmem));
1057   /* Toss the shared-memory original... */
1058   pthread_mutex_lock (&am->vlib_rp->mutex);
1059   oldheap = svm_push_data_heap (am->vlib_rp);
1060
1061   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1062   vec_free (reply);
1063
1064   svm_pop_heap (oldheap);
1065   pthread_mutex_unlock (&am->vlib_rp->mutex);
1066
1067   vat_json_print (vam->ofp, &node);
1068   vat_json_free (&node);
1069
1070   vam->retval = ntohl (mp->retval);
1071   vam->result_ready = 1;
1072 }
1073
1074 static void
1075 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1076 {
1077   vat_main_t *vam = &vat_main;
1078   i32 retval = ntohl (mp->retval);
1079
1080   vam->retval = retval;
1081   vam->cmd_reply = mp->reply;
1082   vam->result_ready = 1;
1083 }
1084
1085 static void
1086 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1087 {
1088   vat_main_t *vam = &vat_main;
1089   vat_json_node_t node;
1090
1091   vat_json_init_object (&node);
1092   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1093   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1094
1095   vat_json_print (vam->ofp, &node);
1096   vat_json_free (&node);
1097
1098   vam->retval = ntohl (mp->retval);
1099   vam->result_ready = 1;
1100 }
1101
1102 static void vl_api_classify_add_del_table_reply_t_handler
1103   (vl_api_classify_add_del_table_reply_t * mp)
1104 {
1105   vat_main_t *vam = &vat_main;
1106   i32 retval = ntohl (mp->retval);
1107   if (vam->async_mode)
1108     {
1109       vam->async_errors += (retval < 0);
1110     }
1111   else
1112     {
1113       vam->retval = retval;
1114       if (retval == 0 &&
1115           ((mp->new_table_index != 0xFFFFFFFF) ||
1116            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1117            (mp->match_n_vectors != 0xFFFFFFFF)))
1118         /*
1119          * Note: this is just barely thread-safe, depends on
1120          * the main thread spinning waiting for an answer...
1121          */
1122         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1123                 ntohl (mp->new_table_index),
1124                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1125       vam->result_ready = 1;
1126     }
1127 }
1128
1129 static void vl_api_classify_add_del_table_reply_t_handler_json
1130   (vl_api_classify_add_del_table_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, "new_table_index",
1138                             ntohl (mp->new_table_index));
1139   vat_json_object_add_uint (&node, "skip_n_vectors",
1140                             ntohl (mp->skip_n_vectors));
1141   vat_json_object_add_uint (&node, "match_n_vectors",
1142                             ntohl (mp->match_n_vectors));
1143
1144   vat_json_print (vam->ofp, &node);
1145   vat_json_free (&node);
1146
1147   vam->retval = ntohl (mp->retval);
1148   vam->result_ready = 1;
1149 }
1150
1151 static void vl_api_get_node_index_reply_t_handler
1152   (vl_api_get_node_index_reply_t * mp)
1153 {
1154   vat_main_t *vam = &vat_main;
1155   i32 retval = ntohl (mp->retval);
1156   if (vam->async_mode)
1157     {
1158       vam->async_errors += (retval < 0);
1159     }
1160   else
1161     {
1162       vam->retval = retval;
1163       if (retval == 0)
1164         errmsg ("node index %d", ntohl (mp->node_index));
1165       vam->result_ready = 1;
1166     }
1167 }
1168
1169 static void vl_api_get_node_index_reply_t_handler_json
1170   (vl_api_get_node_index_reply_t * mp)
1171 {
1172   vat_main_t *vam = &vat_main;
1173   vat_json_node_t node;
1174
1175   vat_json_init_object (&node);
1176   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1177   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1178
1179   vat_json_print (vam->ofp, &node);
1180   vat_json_free (&node);
1181
1182   vam->retval = ntohl (mp->retval);
1183   vam->result_ready = 1;
1184 }
1185
1186 static void vl_api_get_next_index_reply_t_handler
1187   (vl_api_get_next_index_reply_t * mp)
1188 {
1189   vat_main_t *vam = &vat_main;
1190   i32 retval = ntohl (mp->retval);
1191   if (vam->async_mode)
1192     {
1193       vam->async_errors += (retval < 0);
1194     }
1195   else
1196     {
1197       vam->retval = retval;
1198       if (retval == 0)
1199         errmsg ("next node index %d", ntohl (mp->next_index));
1200       vam->result_ready = 1;
1201     }
1202 }
1203
1204 static void vl_api_get_next_index_reply_t_handler_json
1205   (vl_api_get_next_index_reply_t * mp)
1206 {
1207   vat_main_t *vam = &vat_main;
1208   vat_json_node_t node;
1209
1210   vat_json_init_object (&node);
1211   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1212   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1213
1214   vat_json_print (vam->ofp, &node);
1215   vat_json_free (&node);
1216
1217   vam->retval = ntohl (mp->retval);
1218   vam->result_ready = 1;
1219 }
1220
1221 static void vl_api_add_node_next_reply_t_handler
1222   (vl_api_add_node_next_reply_t * mp)
1223 {
1224   vat_main_t *vam = &vat_main;
1225   i32 retval = ntohl (mp->retval);
1226   if (vam->async_mode)
1227     {
1228       vam->async_errors += (retval < 0);
1229     }
1230   else
1231     {
1232       vam->retval = retval;
1233       if (retval == 0)
1234         errmsg ("next index %d", ntohl (mp->next_index));
1235       vam->result_ready = 1;
1236     }
1237 }
1238
1239 static void vl_api_add_node_next_reply_t_handler_json
1240   (vl_api_add_node_next_reply_t * mp)
1241 {
1242   vat_main_t *vam = &vat_main;
1243   vat_json_node_t node;
1244
1245   vat_json_init_object (&node);
1246   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1247   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1248
1249   vat_json_print (vam->ofp, &node);
1250   vat_json_free (&node);
1251
1252   vam->retval = ntohl (mp->retval);
1253   vam->result_ready = 1;
1254 }
1255
1256 static void vl_api_show_version_reply_t_handler
1257   (vl_api_show_version_reply_t * mp)
1258 {
1259   vat_main_t *vam = &vat_main;
1260   i32 retval = ntohl (mp->retval);
1261
1262   if (retval >= 0)
1263     {
1264       errmsg ("        program: %s", mp->program);
1265       errmsg ("        version: %s", mp->version);
1266       errmsg ("     build date: %s", mp->build_date);
1267       errmsg ("build directory: %s", mp->build_directory);
1268     }
1269   vam->retval = retval;
1270   vam->result_ready = 1;
1271 }
1272
1273 static void vl_api_show_version_reply_t_handler_json
1274   (vl_api_show_version_reply_t * mp)
1275 {
1276   vat_main_t *vam = &vat_main;
1277   vat_json_node_t node;
1278
1279   vat_json_init_object (&node);
1280   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1281   vat_json_object_add_string_copy (&node, "program", mp->program);
1282   vat_json_object_add_string_copy (&node, "version", mp->version);
1283   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1284   vat_json_object_add_string_copy (&node, "build_directory",
1285                                    mp->build_directory);
1286
1287   vat_json_print (vam->ofp, &node);
1288   vat_json_free (&node);
1289
1290   vam->retval = ntohl (mp->retval);
1291   vam->result_ready = 1;
1292 }
1293
1294 static void
1295 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1296 {
1297   u32 sw_if_index = ntohl (mp->sw_if_index);
1298   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1299           mp->mac_ip ? "mac/ip binding" : "address resolution",
1300           ntohl (mp->pid), format_ip4_address, &mp->address,
1301           format_ethernet_address, mp->new_mac, sw_if_index);
1302 }
1303
1304 static void
1305 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1306 {
1307   /* JSON output not supported */
1308 }
1309
1310 static void
1311 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1312 {
1313   u32 sw_if_index = ntohl (mp->sw_if_index);
1314   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1315           mp->mac_ip ? "mac/ip binding" : "address resolution",
1316           ntohl (mp->pid), format_ip6_address, mp->address,
1317           format_ethernet_address, mp->new_mac, sw_if_index);
1318 }
1319
1320 static void
1321 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1322 {
1323   /* JSON output not supported */
1324 }
1325
1326 /*
1327  * Special-case: build the bridge domain table, maintain
1328  * the next bd id vbl.
1329  */
1330 static void vl_api_bridge_domain_details_t_handler
1331   (vl_api_bridge_domain_details_t * mp)
1332 {
1333   vat_main_t *vam = &vat_main;
1334   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1335
1336   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1337          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1338
1339   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1340          ntohl (mp->bd_id), mp->learn, mp->forward,
1341          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1342
1343   if (n_sw_ifs)
1344     print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG", "Interface Name");
1345 }
1346
1347 static void vl_api_bridge_domain_details_t_handler_json
1348   (vl_api_bridge_domain_details_t * mp)
1349 {
1350   vat_main_t *vam = &vat_main;
1351   vat_json_node_t *node, *array = NULL;
1352
1353   if (VAT_JSON_ARRAY != vam->json_tree.type)
1354     {
1355       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1356       vat_json_init_array (&vam->json_tree);
1357     }
1358   node = vat_json_array_add (&vam->json_tree);
1359
1360   vat_json_init_object (node);
1361   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1362   vat_json_object_add_uint (node, "flood", mp->flood);
1363   vat_json_object_add_uint (node, "forward", mp->forward);
1364   vat_json_object_add_uint (node, "learn", mp->learn);
1365   vat_json_object_add_uint (node, "bvi_sw_if_index",
1366                             ntohl (mp->bvi_sw_if_index));
1367   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1368   array = vat_json_object_add (node, "sw_if");
1369   vat_json_init_array (array);
1370 }
1371
1372 /*
1373  * Special-case: build the bridge domain sw if table.
1374  */
1375 static void vl_api_bridge_domain_sw_if_details_t_handler
1376   (vl_api_bridge_domain_sw_if_details_t * mp)
1377 {
1378   vat_main_t *vam = &vat_main;
1379   hash_pair_t *p;
1380   u8 *sw_if_name = 0;
1381   u32 sw_if_index;
1382
1383   sw_if_index = ntohl (mp->sw_if_index);
1384   /* *INDENT-OFF* */
1385   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1386   ({
1387     if ((u32) p->value[0] == sw_if_index)
1388       {
1389         sw_if_name = (u8 *)(p->key);
1390         break;
1391       }
1392   }));
1393   /* *INDENT-ON* */
1394
1395   print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1396          mp->shg, sw_if_name ? (char *) sw_if_name :
1397          "sw_if_index not found!");
1398 }
1399
1400 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1401   (vl_api_bridge_domain_sw_if_details_t * mp)
1402 {
1403   vat_main_t *vam = &vat_main;
1404   vat_json_node_t *node = NULL;
1405   uword last_index = 0;
1406
1407   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1408   ASSERT (vec_len (vam->json_tree.array) >= 1);
1409   last_index = vec_len (vam->json_tree.array) - 1;
1410   node = &vam->json_tree.array[last_index];
1411   node = vat_json_object_get_element (node, "sw_if");
1412   ASSERT (NULL != node);
1413   node = vat_json_array_add (node);
1414
1415   vat_json_init_object (node);
1416   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1417   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1418   vat_json_object_add_uint (node, "shg", mp->shg);
1419 }
1420
1421 static void vl_api_control_ping_reply_t_handler
1422   (vl_api_control_ping_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_control_ping_reply_t_handler_json
1438   (vl_api_control_ping_reply_t * mp)
1439 {
1440   vat_main_t *vam = &vat_main;
1441   i32 retval = ntohl (mp->retval);
1442
1443   if (VAT_JSON_NONE != vam->json_tree.type)
1444     {
1445       vat_json_print (vam->ofp, &vam->json_tree);
1446       vat_json_free (&vam->json_tree);
1447       vam->json_tree.type = VAT_JSON_NONE;
1448     }
1449   else
1450     {
1451       /* just print [] */
1452       vat_json_init_array (&vam->json_tree);
1453       vat_json_print (vam->ofp, &vam->json_tree);
1454       vam->json_tree.type = VAT_JSON_NONE;
1455     }
1456
1457   vam->retval = retval;
1458   vam->result_ready = 1;
1459 }
1460
1461 static void
1462   vl_api_bridge_domain_set_mac_age_reply_t_handler
1463   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1464 {
1465   vat_main_t *vam = &vat_main;
1466   i32 retval = ntohl (mp->retval);
1467   if (vam->async_mode)
1468     {
1469       vam->async_errors += (retval < 0);
1470     }
1471   else
1472     {
1473       vam->retval = retval;
1474       vam->result_ready = 1;
1475     }
1476 }
1477
1478 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1479   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1480 {
1481   vat_main_t *vam = &vat_main;
1482   vat_json_node_t node;
1483
1484   vat_json_init_object (&node);
1485   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1486
1487   vat_json_print (vam->ofp, &node);
1488   vat_json_free (&node);
1489
1490   vam->retval = ntohl (mp->retval);
1491   vam->result_ready = 1;
1492 }
1493
1494 static void
1495 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1496 {
1497   vat_main_t *vam = &vat_main;
1498   i32 retval = ntohl (mp->retval);
1499   if (vam->async_mode)
1500     {
1501       vam->async_errors += (retval < 0);
1502     }
1503   else
1504     {
1505       vam->retval = retval;
1506       vam->result_ready = 1;
1507     }
1508 }
1509
1510 static void vl_api_l2_flags_reply_t_handler_json
1511   (vl_api_l2_flags_reply_t * mp)
1512 {
1513   vat_main_t *vam = &vat_main;
1514   vat_json_node_t node;
1515
1516   vat_json_init_object (&node);
1517   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1518   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1519                             ntohl (mp->resulting_feature_bitmap));
1520
1521   vat_json_print (vam->ofp, &node);
1522   vat_json_free (&node);
1523
1524   vam->retval = ntohl (mp->retval);
1525   vam->result_ready = 1;
1526 }
1527
1528 static void vl_api_bridge_flags_reply_t_handler
1529   (vl_api_bridge_flags_reply_t * mp)
1530 {
1531   vat_main_t *vam = &vat_main;
1532   i32 retval = ntohl (mp->retval);
1533   if (vam->async_mode)
1534     {
1535       vam->async_errors += (retval < 0);
1536     }
1537   else
1538     {
1539       vam->retval = retval;
1540       vam->result_ready = 1;
1541     }
1542 }
1543
1544 static void vl_api_bridge_flags_reply_t_handler_json
1545   (vl_api_bridge_flags_reply_t * mp)
1546 {
1547   vat_main_t *vam = &vat_main;
1548   vat_json_node_t node;
1549
1550   vat_json_init_object (&node);
1551   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1552   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1553                             ntohl (mp->resulting_feature_bitmap));
1554
1555   vat_json_print (vam->ofp, &node);
1556   vat_json_free (&node);
1557
1558   vam->retval = ntohl (mp->retval);
1559   vam->result_ready = 1;
1560 }
1561
1562 static void vl_api_tap_connect_reply_t_handler
1563   (vl_api_tap_connect_reply_t * mp)
1564 {
1565   vat_main_t *vam = &vat_main;
1566   i32 retval = ntohl (mp->retval);
1567   if (vam->async_mode)
1568     {
1569       vam->async_errors += (retval < 0);
1570     }
1571   else
1572     {
1573       vam->retval = retval;
1574       vam->sw_if_index = ntohl (mp->sw_if_index);
1575       vam->result_ready = 1;
1576     }
1577
1578 }
1579
1580 static void vl_api_tap_connect_reply_t_handler_json
1581   (vl_api_tap_connect_reply_t * mp)
1582 {
1583   vat_main_t *vam = &vat_main;
1584   vat_json_node_t node;
1585
1586   vat_json_init_object (&node);
1587   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1588   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1589
1590   vat_json_print (vam->ofp, &node);
1591   vat_json_free (&node);
1592
1593   vam->retval = ntohl (mp->retval);
1594   vam->result_ready = 1;
1595
1596 }
1597
1598 static void
1599 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1600 {
1601   vat_main_t *vam = &vat_main;
1602   i32 retval = ntohl (mp->retval);
1603   if (vam->async_mode)
1604     {
1605       vam->async_errors += (retval < 0);
1606     }
1607   else
1608     {
1609       vam->retval = retval;
1610       vam->sw_if_index = ntohl (mp->sw_if_index);
1611       vam->result_ready = 1;
1612     }
1613 }
1614
1615 static void vl_api_tap_modify_reply_t_handler_json
1616   (vl_api_tap_modify_reply_t * mp)
1617 {
1618   vat_main_t *vam = &vat_main;
1619   vat_json_node_t node;
1620
1621   vat_json_init_object (&node);
1622   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1623   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1624
1625   vat_json_print (vam->ofp, &node);
1626   vat_json_free (&node);
1627
1628   vam->retval = ntohl (mp->retval);
1629   vam->result_ready = 1;
1630 }
1631
1632 static void
1633 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1634 {
1635   vat_main_t *vam = &vat_main;
1636   i32 retval = ntohl (mp->retval);
1637   if (vam->async_mode)
1638     {
1639       vam->async_errors += (retval < 0);
1640     }
1641   else
1642     {
1643       vam->retval = retval;
1644       vam->result_ready = 1;
1645     }
1646 }
1647
1648 static void vl_api_tap_delete_reply_t_handler_json
1649   (vl_api_tap_delete_reply_t * mp)
1650 {
1651   vat_main_t *vam = &vat_main;
1652   vat_json_node_t node;
1653
1654   vat_json_init_object (&node);
1655   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1656
1657   vat_json_print (vam->ofp, &node);
1658   vat_json_free (&node);
1659
1660   vam->retval = ntohl (mp->retval);
1661   vam->result_ready = 1;
1662 }
1663
1664 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1665   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1666 {
1667   vat_main_t *vam = &vat_main;
1668   i32 retval = ntohl (mp->retval);
1669   if (vam->async_mode)
1670     {
1671       vam->async_errors += (retval < 0);
1672     }
1673   else
1674     {
1675       vam->retval = retval;
1676       vam->result_ready = 1;
1677     }
1678 }
1679
1680 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1681   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1682 {
1683   vat_main_t *vam = &vat_main;
1684   vat_json_node_t node;
1685
1686   vat_json_init_object (&node);
1687   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1688   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1689                             ntohl (mp->sw_if_index));
1690
1691   vat_json_print (vam->ofp, &node);
1692   vat_json_free (&node);
1693
1694   vam->retval = ntohl (mp->retval);
1695   vam->result_ready = 1;
1696 }
1697
1698 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1699   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1700 {
1701   vat_main_t *vam = &vat_main;
1702   i32 retval = ntohl (mp->retval);
1703   if (vam->async_mode)
1704     {
1705       vam->async_errors += (retval < 0);
1706     }
1707   else
1708     {
1709       vam->retval = retval;
1710       vam->sw_if_index = ntohl (mp->sw_if_index);
1711       vam->result_ready = 1;
1712     }
1713 }
1714
1715 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1716   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1717 {
1718   vat_main_t *vam = &vat_main;
1719   vat_json_node_t node;
1720
1721   vat_json_init_object (&node);
1722   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1723   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1724
1725   vat_json_print (vam->ofp, &node);
1726   vat_json_free (&node);
1727
1728   vam->retval = ntohl (mp->retval);
1729   vam->result_ready = 1;
1730 }
1731
1732
1733 static void vl_api_one_add_del_locator_set_reply_t_handler
1734   (vl_api_one_add_del_locator_set_reply_t * mp)
1735 {
1736   vat_main_t *vam = &vat_main;
1737   i32 retval = ntohl (mp->retval);
1738   if (vam->async_mode)
1739     {
1740       vam->async_errors += (retval < 0);
1741     }
1742   else
1743     {
1744       vam->retval = retval;
1745       vam->result_ready = 1;
1746     }
1747 }
1748
1749 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1750   (vl_api_one_add_del_locator_set_reply_t * mp)
1751 {
1752   vat_main_t *vam = &vat_main;
1753   vat_json_node_t node;
1754
1755   vat_json_init_object (&node);
1756   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1757   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1758
1759   vat_json_print (vam->ofp, &node);
1760   vat_json_free (&node);
1761
1762   vam->retval = ntohl (mp->retval);
1763   vam->result_ready = 1;
1764 }
1765
1766 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1767   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1768 {
1769   vat_main_t *vam = &vat_main;
1770   i32 retval = ntohl (mp->retval);
1771   if (vam->async_mode)
1772     {
1773       vam->async_errors += (retval < 0);
1774     }
1775   else
1776     {
1777       vam->retval = retval;
1778       vam->sw_if_index = ntohl (mp->sw_if_index);
1779       vam->result_ready = 1;
1780     }
1781 }
1782
1783 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1784   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1785 {
1786   vat_main_t *vam = &vat_main;
1787   vat_json_node_t node;
1788
1789   vat_json_init_object (&node);
1790   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1791   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1792
1793   vat_json_print (vam->ofp, &node);
1794   vat_json_free (&node);
1795
1796   vam->retval = ntohl (mp->retval);
1797   vam->result_ready = 1;
1798 }
1799
1800 static void vl_api_gre_add_del_tunnel_reply_t_handler
1801   (vl_api_gre_add_del_tunnel_reply_t * mp)
1802 {
1803   vat_main_t *vam = &vat_main;
1804   i32 retval = ntohl (mp->retval);
1805   if (vam->async_mode)
1806     {
1807       vam->async_errors += (retval < 0);
1808     }
1809   else
1810     {
1811       vam->retval = retval;
1812       vam->sw_if_index = ntohl (mp->sw_if_index);
1813       vam->result_ready = 1;
1814     }
1815 }
1816
1817 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1818   (vl_api_gre_add_del_tunnel_reply_t * mp)
1819 {
1820   vat_main_t *vam = &vat_main;
1821   vat_json_node_t node;
1822
1823   vat_json_init_object (&node);
1824   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1825   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1826
1827   vat_json_print (vam->ofp, &node);
1828   vat_json_free (&node);
1829
1830   vam->retval = ntohl (mp->retval);
1831   vam->result_ready = 1;
1832 }
1833
1834 static void vl_api_create_vhost_user_if_reply_t_handler
1835   (vl_api_create_vhost_user_if_reply_t * mp)
1836 {
1837   vat_main_t *vam = &vat_main;
1838   i32 retval = ntohl (mp->retval);
1839   if (vam->async_mode)
1840     {
1841       vam->async_errors += (retval < 0);
1842     }
1843   else
1844     {
1845       vam->retval = retval;
1846       vam->sw_if_index = ntohl (mp->sw_if_index);
1847       vam->result_ready = 1;
1848     }
1849 }
1850
1851 static void vl_api_create_vhost_user_if_reply_t_handler_json
1852   (vl_api_create_vhost_user_if_reply_t * mp)
1853 {
1854   vat_main_t *vam = &vat_main;
1855   vat_json_node_t node;
1856
1857   vat_json_init_object (&node);
1858   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1859   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1860
1861   vat_json_print (vam->ofp, &node);
1862   vat_json_free (&node);
1863
1864   vam->retval = ntohl (mp->retval);
1865   vam->result_ready = 1;
1866 }
1867
1868 static void vl_api_ip_address_details_t_handler
1869   (vl_api_ip_address_details_t * mp)
1870 {
1871   vat_main_t *vam = &vat_main;
1872   static ip_address_details_t empty_ip_address_details = { {0} };
1873   ip_address_details_t *address = NULL;
1874   ip_details_t *current_ip_details = NULL;
1875   ip_details_t *details = NULL;
1876
1877   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1878
1879   if (!details || vam->current_sw_if_index >= vec_len (details)
1880       || !details[vam->current_sw_if_index].present)
1881     {
1882       errmsg ("ip address details arrived but not stored");
1883       errmsg ("ip_dump should be called first");
1884       return;
1885     }
1886
1887   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1888
1889 #define addresses (current_ip_details->addr)
1890
1891   vec_validate_init_empty (addresses, vec_len (addresses),
1892                            empty_ip_address_details);
1893
1894   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1895
1896   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1897   address->prefix_length = mp->prefix_length;
1898 #undef addresses
1899 }
1900
1901 static void vl_api_ip_address_details_t_handler_json
1902   (vl_api_ip_address_details_t * mp)
1903 {
1904   vat_main_t *vam = &vat_main;
1905   vat_json_node_t *node = NULL;
1906   struct in6_addr ip6;
1907   struct in_addr ip4;
1908
1909   if (VAT_JSON_ARRAY != vam->json_tree.type)
1910     {
1911       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1912       vat_json_init_array (&vam->json_tree);
1913     }
1914   node = vat_json_array_add (&vam->json_tree);
1915
1916   vat_json_init_object (node);
1917   if (vam->is_ipv6)
1918     {
1919       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1920       vat_json_object_add_ip6 (node, "ip", ip6);
1921     }
1922   else
1923     {
1924       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1925       vat_json_object_add_ip4 (node, "ip", ip4);
1926     }
1927   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1928 }
1929
1930 static void
1931 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1932 {
1933   vat_main_t *vam = &vat_main;
1934   static ip_details_t empty_ip_details = { 0 };
1935   ip_details_t *ip = NULL;
1936   u32 sw_if_index = ~0;
1937
1938   sw_if_index = ntohl (mp->sw_if_index);
1939
1940   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1941                            sw_if_index, empty_ip_details);
1942
1943   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1944                          sw_if_index);
1945
1946   ip->present = 1;
1947 }
1948
1949 static void
1950 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1951 {
1952   vat_main_t *vam = &vat_main;
1953
1954   if (VAT_JSON_ARRAY != vam->json_tree.type)
1955     {
1956       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1957       vat_json_init_array (&vam->json_tree);
1958     }
1959   vat_json_array_add_uint (&vam->json_tree,
1960                            clib_net_to_host_u32 (mp->sw_if_index));
1961 }
1962
1963 static void vl_api_map_domain_details_t_handler_json
1964   (vl_api_map_domain_details_t * mp)
1965 {
1966   vat_json_node_t *node = NULL;
1967   vat_main_t *vam = &vat_main;
1968   struct in6_addr ip6;
1969   struct in_addr ip4;
1970
1971   if (VAT_JSON_ARRAY != vam->json_tree.type)
1972     {
1973       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1974       vat_json_init_array (&vam->json_tree);
1975     }
1976
1977   node = vat_json_array_add (&vam->json_tree);
1978   vat_json_init_object (node);
1979
1980   vat_json_object_add_uint (node, "domain_index",
1981                             clib_net_to_host_u32 (mp->domain_index));
1982   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1983   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1984   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1985   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1986   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1987   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1988   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1989   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1990   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1991   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1992   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1993   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1994   vat_json_object_add_uint (node, "flags", mp->flags);
1995   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1996   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1997 }
1998
1999 static void vl_api_map_domain_details_t_handler
2000   (vl_api_map_domain_details_t * mp)
2001 {
2002   vat_main_t *vam = &vat_main;
2003
2004   if (mp->is_translation)
2005     {
2006       print (vam->ofp,
2007              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2008              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2009              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2010              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2011              clib_net_to_host_u32 (mp->domain_index));
2012     }
2013   else
2014     {
2015       print (vam->ofp,
2016              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2017              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2018              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2019              format_ip6_address, mp->ip6_src,
2020              clib_net_to_host_u32 (mp->domain_index));
2021     }
2022   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2023          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2024          mp->is_translation ? "map-t" : "");
2025 }
2026
2027 static void vl_api_map_rule_details_t_handler_json
2028   (vl_api_map_rule_details_t * mp)
2029 {
2030   struct in6_addr ip6;
2031   vat_json_node_t *node = NULL;
2032   vat_main_t *vam = &vat_main;
2033
2034   if (VAT_JSON_ARRAY != vam->json_tree.type)
2035     {
2036       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2037       vat_json_init_array (&vam->json_tree);
2038     }
2039
2040   node = vat_json_array_add (&vam->json_tree);
2041   vat_json_init_object (node);
2042
2043   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2044   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2045   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2046 }
2047
2048 static void
2049 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2050 {
2051   vat_main_t *vam = &vat_main;
2052   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2053          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2054 }
2055
2056 static void
2057 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2058 {
2059   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2060           "router_addr %U host_mac %U",
2061           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2062           format_ip4_address, &mp->host_address,
2063           format_ip4_address, &mp->router_address,
2064           format_ethernet_address, mp->host_mac);
2065 }
2066
2067 static void vl_api_dhcp_compl_event_t_handler_json
2068   (vl_api_dhcp_compl_event_t * mp)
2069 {
2070   /* JSON output not supported */
2071 }
2072
2073 static void
2074 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2075                               u32 counter)
2076 {
2077   vat_main_t *vam = &vat_main;
2078   static u64 default_counter = 0;
2079
2080   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2081                            NULL);
2082   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2083                            sw_if_index, default_counter);
2084   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2085 }
2086
2087 static void
2088 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2089                                 interface_counter_t counter)
2090 {
2091   vat_main_t *vam = &vat_main;
2092   static interface_counter_t default_counter = { 0, };
2093
2094   vec_validate_init_empty (vam->combined_interface_counters,
2095                            vnet_counter_type, NULL);
2096   vec_validate_init_empty (vam->combined_interface_counters
2097                            [vnet_counter_type], sw_if_index, default_counter);
2098   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2099 }
2100
2101 static void vl_api_vnet_interface_counters_t_handler
2102   (vl_api_vnet_interface_counters_t * mp)
2103 {
2104   /* not supported */
2105 }
2106
2107 static void vl_api_vnet_interface_counters_t_handler_json
2108   (vl_api_vnet_interface_counters_t * mp)
2109 {
2110   interface_counter_t counter;
2111   vlib_counter_t *v;
2112   u64 *v_packets;
2113   u64 packets;
2114   u32 count;
2115   u32 first_sw_if_index;
2116   int i;
2117
2118   count = ntohl (mp->count);
2119   first_sw_if_index = ntohl (mp->first_sw_if_index);
2120
2121   if (!mp->is_combined)
2122     {
2123       v_packets = (u64 *) & mp->data;
2124       for (i = 0; i < count; i++)
2125         {
2126           packets =
2127             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2128           set_simple_interface_counter (mp->vnet_counter_type,
2129                                         first_sw_if_index + i, packets);
2130           v_packets++;
2131         }
2132     }
2133   else
2134     {
2135       v = (vlib_counter_t *) & mp->data;
2136       for (i = 0; i < count; i++)
2137         {
2138           counter.packets =
2139             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2140           counter.bytes =
2141             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2142           set_combined_interface_counter (mp->vnet_counter_type,
2143                                           first_sw_if_index + i, counter);
2144           v++;
2145         }
2146     }
2147 }
2148
2149 static u32
2150 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2151 {
2152   vat_main_t *vam = &vat_main;
2153   u32 i;
2154
2155   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2156     {
2157       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2158         {
2159           return i;
2160         }
2161     }
2162   return ~0;
2163 }
2164
2165 static u32
2166 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2167 {
2168   vat_main_t *vam = &vat_main;
2169   u32 i;
2170
2171   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2172     {
2173       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2174         {
2175           return i;
2176         }
2177     }
2178   return ~0;
2179 }
2180
2181 static void vl_api_vnet_ip4_fib_counters_t_handler
2182   (vl_api_vnet_ip4_fib_counters_t * mp)
2183 {
2184   /* not supported */
2185 }
2186
2187 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2188   (vl_api_vnet_ip4_fib_counters_t * mp)
2189 {
2190   vat_main_t *vam = &vat_main;
2191   vl_api_ip4_fib_counter_t *v;
2192   ip4_fib_counter_t *counter;
2193   struct in_addr ip4;
2194   u32 vrf_id;
2195   u32 vrf_index;
2196   u32 count;
2197   int i;
2198
2199   vrf_id = ntohl (mp->vrf_id);
2200   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2201   if (~0 == vrf_index)
2202     {
2203       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2204       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2205       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2206       vec_validate (vam->ip4_fib_counters, vrf_index);
2207       vam->ip4_fib_counters[vrf_index] = NULL;
2208     }
2209
2210   vec_free (vam->ip4_fib_counters[vrf_index]);
2211   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2212   count = ntohl (mp->count);
2213   for (i = 0; i < count; i++)
2214     {
2215       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2216       counter = &vam->ip4_fib_counters[vrf_index][i];
2217       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2218       counter->address = ip4;
2219       counter->address_length = v->address_length;
2220       counter->packets = clib_net_to_host_u64 (v->packets);
2221       counter->bytes = clib_net_to_host_u64 (v->bytes);
2222       v++;
2223     }
2224 }
2225
2226 static void vl_api_vnet_ip4_nbr_counters_t_handler
2227   (vl_api_vnet_ip4_nbr_counters_t * mp)
2228 {
2229   /* not supported */
2230 }
2231
2232 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2233   (vl_api_vnet_ip4_nbr_counters_t * mp)
2234 {
2235   vat_main_t *vam = &vat_main;
2236   vl_api_ip4_nbr_counter_t *v;
2237   ip4_nbr_counter_t *counter;
2238   u32 sw_if_index;
2239   u32 count;
2240   int i;
2241
2242   sw_if_index = ntohl (mp->sw_if_index);
2243   count = ntohl (mp->count);
2244   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2245
2246   if (mp->begin)
2247     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2248
2249   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2250   for (i = 0; i < count; i++)
2251     {
2252       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2253       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2254       counter->address.s_addr = v->address;
2255       counter->packets = clib_net_to_host_u64 (v->packets);
2256       counter->bytes = clib_net_to_host_u64 (v->bytes);
2257       counter->linkt = v->link_type;
2258       v++;
2259     }
2260 }
2261
2262 static void vl_api_vnet_ip6_fib_counters_t_handler
2263   (vl_api_vnet_ip6_fib_counters_t * mp)
2264 {
2265   /* not supported */
2266 }
2267
2268 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2269   (vl_api_vnet_ip6_fib_counters_t * mp)
2270 {
2271   vat_main_t *vam = &vat_main;
2272   vl_api_ip6_fib_counter_t *v;
2273   ip6_fib_counter_t *counter;
2274   struct in6_addr ip6;
2275   u32 vrf_id;
2276   u32 vrf_index;
2277   u32 count;
2278   int i;
2279
2280   vrf_id = ntohl (mp->vrf_id);
2281   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2282   if (~0 == vrf_index)
2283     {
2284       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2285       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2286       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2287       vec_validate (vam->ip6_fib_counters, vrf_index);
2288       vam->ip6_fib_counters[vrf_index] = NULL;
2289     }
2290
2291   vec_free (vam->ip6_fib_counters[vrf_index]);
2292   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2293   count = ntohl (mp->count);
2294   for (i = 0; i < count; i++)
2295     {
2296       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2297       counter = &vam->ip6_fib_counters[vrf_index][i];
2298       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2299       counter->address = ip6;
2300       counter->address_length = v->address_length;
2301       counter->packets = clib_net_to_host_u64 (v->packets);
2302       counter->bytes = clib_net_to_host_u64 (v->bytes);
2303       v++;
2304     }
2305 }
2306
2307 static void vl_api_vnet_ip6_nbr_counters_t_handler
2308   (vl_api_vnet_ip6_nbr_counters_t * mp)
2309 {
2310   /* not supported */
2311 }
2312
2313 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2314   (vl_api_vnet_ip6_nbr_counters_t * mp)
2315 {
2316   vat_main_t *vam = &vat_main;
2317   vl_api_ip6_nbr_counter_t *v;
2318   ip6_nbr_counter_t *counter;
2319   struct in6_addr ip6;
2320   u32 sw_if_index;
2321   u32 count;
2322   int i;
2323
2324   sw_if_index = ntohl (mp->sw_if_index);
2325   count = ntohl (mp->count);
2326   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2327
2328   if (mp->begin)
2329     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2330
2331   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2332   for (i = 0; i < count; i++)
2333     {
2334       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2335       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2336       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2337       counter->address = ip6;
2338       counter->packets = clib_net_to_host_u64 (v->packets);
2339       counter->bytes = clib_net_to_host_u64 (v->bytes);
2340       v++;
2341     }
2342 }
2343
2344 static void vl_api_get_first_msg_id_reply_t_handler
2345   (vl_api_get_first_msg_id_reply_t * mp)
2346 {
2347   vat_main_t *vam = &vat_main;
2348   i32 retval = ntohl (mp->retval);
2349
2350   if (vam->async_mode)
2351     {
2352       vam->async_errors += (retval < 0);
2353     }
2354   else
2355     {
2356       vam->retval = retval;
2357       vam->result_ready = 1;
2358     }
2359   if (retval >= 0)
2360     {
2361       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2362     }
2363 }
2364
2365 static void vl_api_get_first_msg_id_reply_t_handler_json
2366   (vl_api_get_first_msg_id_reply_t * mp)
2367 {
2368   vat_main_t *vam = &vat_main;
2369   vat_json_node_t node;
2370
2371   vat_json_init_object (&node);
2372   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2373   vat_json_object_add_uint (&node, "first_msg_id",
2374                             (uint) ntohs (mp->first_msg_id));
2375
2376   vat_json_print (vam->ofp, &node);
2377   vat_json_free (&node);
2378
2379   vam->retval = ntohl (mp->retval);
2380   vam->result_ready = 1;
2381 }
2382
2383 static void vl_api_get_node_graph_reply_t_handler
2384   (vl_api_get_node_graph_reply_t * mp)
2385 {
2386   vat_main_t *vam = &vat_main;
2387   api_main_t *am = &api_main;
2388   i32 retval = ntohl (mp->retval);
2389   u8 *pvt_copy, *reply;
2390   void *oldheap;
2391   vlib_node_t *node;
2392   int i;
2393
2394   if (vam->async_mode)
2395     {
2396       vam->async_errors += (retval < 0);
2397     }
2398   else
2399     {
2400       vam->retval = retval;
2401       vam->result_ready = 1;
2402     }
2403
2404   /* "Should never happen..." */
2405   if (retval != 0)
2406     return;
2407
2408   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2409   pvt_copy = vec_dup (reply);
2410
2411   /* Toss the shared-memory original... */
2412   pthread_mutex_lock (&am->vlib_rp->mutex);
2413   oldheap = svm_push_data_heap (am->vlib_rp);
2414
2415   vec_free (reply);
2416
2417   svm_pop_heap (oldheap);
2418   pthread_mutex_unlock (&am->vlib_rp->mutex);
2419
2420   if (vam->graph_nodes)
2421     {
2422       hash_free (vam->graph_node_index_by_name);
2423
2424       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2425         {
2426           node = vam->graph_nodes[i];
2427           vec_free (node->name);
2428           vec_free (node->next_nodes);
2429           vec_free (node);
2430         }
2431       vec_free (vam->graph_nodes);
2432     }
2433
2434   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2435   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2436   vec_free (pvt_copy);
2437
2438   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2439     {
2440       node = vam->graph_nodes[i];
2441       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2442     }
2443 }
2444
2445 static void vl_api_get_node_graph_reply_t_handler_json
2446   (vl_api_get_node_graph_reply_t * mp)
2447 {
2448   vat_main_t *vam = &vat_main;
2449   api_main_t *am = &api_main;
2450   void *oldheap;
2451   vat_json_node_t node;
2452   u8 *reply;
2453
2454   /* $$$$ make this real? */
2455   vat_json_init_object (&node);
2456   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2457   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2458
2459   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2460
2461   /* Toss the shared-memory original... */
2462   pthread_mutex_lock (&am->vlib_rp->mutex);
2463   oldheap = svm_push_data_heap (am->vlib_rp);
2464
2465   vec_free (reply);
2466
2467   svm_pop_heap (oldheap);
2468   pthread_mutex_unlock (&am->vlib_rp->mutex);
2469
2470   vat_json_print (vam->ofp, &node);
2471   vat_json_free (&node);
2472
2473   vam->retval = ntohl (mp->retval);
2474   vam->result_ready = 1;
2475 }
2476
2477 static void
2478 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2479 {
2480   vat_main_t *vam = &vat_main;
2481   u8 *s = 0;
2482
2483   if (mp->local)
2484     {
2485       s = format (s, "%=16d%=16d%=16d",
2486                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2487     }
2488   else
2489     {
2490       s = format (s, "%=16U%=16d%=16d",
2491                   mp->is_ipv6 ? format_ip6_address :
2492                   format_ip4_address,
2493                   mp->ip_address, mp->priority, mp->weight);
2494     }
2495
2496   print (vam->ofp, "%v", s);
2497   vec_free (s);
2498 }
2499
2500 static void
2501 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2502 {
2503   vat_main_t *vam = &vat_main;
2504   vat_json_node_t *node = NULL;
2505   struct in6_addr ip6;
2506   struct in_addr ip4;
2507
2508   if (VAT_JSON_ARRAY != vam->json_tree.type)
2509     {
2510       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2511       vat_json_init_array (&vam->json_tree);
2512     }
2513   node = vat_json_array_add (&vam->json_tree);
2514   vat_json_init_object (node);
2515
2516   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2517   vat_json_object_add_uint (node, "priority", mp->priority);
2518   vat_json_object_add_uint (node, "weight", mp->weight);
2519
2520   if (mp->local)
2521     vat_json_object_add_uint (node, "sw_if_index",
2522                               clib_net_to_host_u32 (mp->sw_if_index));
2523   else
2524     {
2525       if (mp->is_ipv6)
2526         {
2527           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2528           vat_json_object_add_ip6 (node, "address", ip6);
2529         }
2530       else
2531         {
2532           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2533           vat_json_object_add_ip4 (node, "address", ip4);
2534         }
2535     }
2536 }
2537
2538 static void
2539 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2540                                           mp)
2541 {
2542   vat_main_t *vam = &vat_main;
2543   u8 *ls_name = 0;
2544
2545   ls_name = format (0, "%s", mp->ls_name);
2546
2547   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2548          ls_name);
2549   vec_free (ls_name);
2550 }
2551
2552 static void
2553   vl_api_one_locator_set_details_t_handler_json
2554   (vl_api_one_locator_set_details_t * mp)
2555 {
2556   vat_main_t *vam = &vat_main;
2557   vat_json_node_t *node = 0;
2558   u8 *ls_name = 0;
2559
2560   ls_name = format (0, "%s", mp->ls_name);
2561   vec_add1 (ls_name, 0);
2562
2563   if (VAT_JSON_ARRAY != vam->json_tree.type)
2564     {
2565       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2566       vat_json_init_array (&vam->json_tree);
2567     }
2568   node = vat_json_array_add (&vam->json_tree);
2569
2570   vat_json_init_object (node);
2571   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2572   vat_json_object_add_uint (node, "ls_index",
2573                             clib_net_to_host_u32 (mp->ls_index));
2574   vec_free (ls_name);
2575 }
2576
2577 static u8 *
2578 format_lisp_flat_eid (u8 * s, va_list * args)
2579 {
2580   u32 type = va_arg (*args, u32);
2581   u8 *eid = va_arg (*args, u8 *);
2582   u32 eid_len = va_arg (*args, u32);
2583
2584   switch (type)
2585     {
2586     case 0:
2587       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2588     case 1:
2589       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2590     case 2:
2591       return format (s, "%U", format_ethernet_address, eid);
2592     }
2593   return 0;
2594 }
2595
2596 static u8 *
2597 format_lisp_eid_vat (u8 * s, va_list * args)
2598 {
2599   u32 type = va_arg (*args, u32);
2600   u8 *eid = va_arg (*args, u8 *);
2601   u32 eid_len = va_arg (*args, u32);
2602   u8 *seid = va_arg (*args, u8 *);
2603   u32 seid_len = va_arg (*args, u32);
2604   u32 is_src_dst = va_arg (*args, u32);
2605
2606   if (is_src_dst)
2607     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2608
2609   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2610
2611   return s;
2612 }
2613
2614 static void
2615 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2616 {
2617   vat_main_t *vam = &vat_main;
2618   u8 *s = 0, *eid = 0;
2619
2620   if (~0 == mp->locator_set_index)
2621     s = format (0, "action: %d", mp->action);
2622   else
2623     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2624
2625   eid = format (0, "%U", format_lisp_eid_vat,
2626                 mp->eid_type,
2627                 mp->eid,
2628                 mp->eid_prefix_len,
2629                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2630   vec_add1 (eid, 0);
2631
2632   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2633          clib_net_to_host_u32 (mp->vni),
2634          eid,
2635          mp->is_local ? "local" : "remote",
2636          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2637          clib_net_to_host_u16 (mp->key_id), mp->key);
2638
2639   vec_free (s);
2640   vec_free (eid);
2641 }
2642
2643 static void
2644 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2645                                              * mp)
2646 {
2647   vat_main_t *vam = &vat_main;
2648   vat_json_node_t *node = 0;
2649   u8 *eid = 0;
2650
2651   if (VAT_JSON_ARRAY != vam->json_tree.type)
2652     {
2653       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2654       vat_json_init_array (&vam->json_tree);
2655     }
2656   node = vat_json_array_add (&vam->json_tree);
2657
2658   vat_json_init_object (node);
2659   if (~0 == mp->locator_set_index)
2660     vat_json_object_add_uint (node, "action", mp->action);
2661   else
2662     vat_json_object_add_uint (node, "locator_set_index",
2663                               clib_net_to_host_u32 (mp->locator_set_index));
2664
2665   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2666   eid = format (0, "%U", format_lisp_eid_vat,
2667                 mp->eid_type,
2668                 mp->eid,
2669                 mp->eid_prefix_len,
2670                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2671   vec_add1 (eid, 0);
2672   vat_json_object_add_string_copy (node, "eid", eid);
2673   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2674   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2675   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2676
2677   if (mp->key_id)
2678     {
2679       vat_json_object_add_uint (node, "key_id",
2680                                 clib_net_to_host_u16 (mp->key_id));
2681       vat_json_object_add_string_copy (node, "key", mp->key);
2682     }
2683   vec_free (eid);
2684 }
2685
2686 static void
2687 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
2688 {
2689   vat_main_t *vam = &vat_main;
2690   u8 *seid = 0, *deid = 0;
2691   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2692
2693   deid = format (0, "%U", format_lisp_eid_vat,
2694                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2695
2696   seid = format (0, "%U", format_lisp_eid_vat,
2697                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2698
2699   vec_add1 (deid, 0);
2700   vec_add1 (seid, 0);
2701
2702   if (mp->is_ip4)
2703     format_ip_address_fcn = format_ip4_address;
2704   else
2705     format_ip_address_fcn = format_ip6_address;
2706
2707
2708   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
2709          clib_net_to_host_u32 (mp->vni),
2710          seid, deid,
2711          format_ip_address_fcn, mp->lloc,
2712          format_ip_address_fcn, mp->rloc,
2713          clib_net_to_host_u32 (mp->pkt_count),
2714          clib_net_to_host_u32 (mp->bytes));
2715
2716   vec_free (deid);
2717   vec_free (seid);
2718 }
2719
2720 static void
2721 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
2722 {
2723   struct in6_addr ip6;
2724   struct in_addr ip4;
2725   vat_main_t *vam = &vat_main;
2726   vat_json_node_t *node = 0;
2727   u8 *deid = 0, *seid = 0;
2728
2729   if (VAT_JSON_ARRAY != vam->json_tree.type)
2730     {
2731       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2732       vat_json_init_array (&vam->json_tree);
2733     }
2734   node = vat_json_array_add (&vam->json_tree);
2735
2736   vat_json_init_object (node);
2737   deid = format (0, "%U", format_lisp_eid_vat,
2738                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2739
2740   seid = format (0, "%U", format_lisp_eid_vat,
2741                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2742
2743   vec_add1 (deid, 0);
2744   vec_add1 (seid, 0);
2745
2746   vat_json_object_add_string_copy (node, "seid", seid);
2747   vat_json_object_add_string_copy (node, "deid", deid);
2748   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2749
2750   if (mp->is_ip4)
2751     {
2752       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
2753       vat_json_object_add_ip4 (node, "lloc", ip4);
2754       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
2755       vat_json_object_add_ip4 (node, "rloc", ip4);
2756     }
2757   else
2758     {
2759       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
2760       vat_json_object_add_ip6 (node, "lloc", ip6);
2761       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
2762       vat_json_object_add_ip6 (node, "rloc", ip6);
2763     }
2764   vat_json_object_add_uint (node, "pkt_count",
2765                             clib_net_to_host_u32 (mp->pkt_count));
2766   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
2767
2768   vec_free (deid);
2769   vec_free (seid);
2770 }
2771
2772 static void
2773   vl_api_one_eid_table_map_details_t_handler
2774   (vl_api_one_eid_table_map_details_t * mp)
2775 {
2776   vat_main_t *vam = &vat_main;
2777
2778   u8 *line = format (0, "%=10d%=10d",
2779                      clib_net_to_host_u32 (mp->vni),
2780                      clib_net_to_host_u32 (mp->dp_table));
2781   print (vam->ofp, "%v", line);
2782   vec_free (line);
2783 }
2784
2785 static void
2786   vl_api_one_eid_table_map_details_t_handler_json
2787   (vl_api_one_eid_table_map_details_t * mp)
2788 {
2789   vat_main_t *vam = &vat_main;
2790   vat_json_node_t *node = NULL;
2791
2792   if (VAT_JSON_ARRAY != vam->json_tree.type)
2793     {
2794       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2795       vat_json_init_array (&vam->json_tree);
2796     }
2797   node = vat_json_array_add (&vam->json_tree);
2798   vat_json_init_object (node);
2799   vat_json_object_add_uint (node, "dp_table",
2800                             clib_net_to_host_u32 (mp->dp_table));
2801   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2802 }
2803
2804 static void
2805   vl_api_one_eid_table_vni_details_t_handler
2806   (vl_api_one_eid_table_vni_details_t * mp)
2807 {
2808   vat_main_t *vam = &vat_main;
2809
2810   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2811   print (vam->ofp, "%v", line);
2812   vec_free (line);
2813 }
2814
2815 static void
2816   vl_api_one_eid_table_vni_details_t_handler_json
2817   (vl_api_one_eid_table_vni_details_t * mp)
2818 {
2819   vat_main_t *vam = &vat_main;
2820   vat_json_node_t *node = NULL;
2821
2822   if (VAT_JSON_ARRAY != vam->json_tree.type)
2823     {
2824       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2825       vat_json_init_array (&vam->json_tree);
2826     }
2827   node = vat_json_array_add (&vam->json_tree);
2828   vat_json_init_object (node);
2829   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2830 }
2831
2832 static void
2833   vl_api_show_one_map_register_state_reply_t_handler
2834   (vl_api_show_one_map_register_state_reply_t * mp)
2835 {
2836   vat_main_t *vam = &vat_main;
2837   int retval = clib_net_to_host_u32 (mp->retval);
2838
2839   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2840
2841   vam->retval = retval;
2842   vam->result_ready = 1;
2843 }
2844
2845 static void
2846   vl_api_show_one_map_register_state_reply_t_handler_json
2847   (vl_api_show_one_map_register_state_reply_t * mp)
2848 {
2849   vat_main_t *vam = &vat_main;
2850   vat_json_node_t _node, *node = &_node;
2851   int retval = clib_net_to_host_u32 (mp->retval);
2852
2853   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2854
2855   vat_json_init_object (node);
2856   vat_json_object_add_string_copy (node, "state", s);
2857
2858   vat_json_print (vam->ofp, node);
2859   vat_json_free (node);
2860
2861   vam->retval = retval;
2862   vam->result_ready = 1;
2863   vec_free (s);
2864 }
2865
2866 static void
2867   vl_api_show_one_rloc_probe_state_reply_t_handler
2868   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2869 {
2870   vat_main_t *vam = &vat_main;
2871   int retval = clib_net_to_host_u32 (mp->retval);
2872
2873   if (retval)
2874     goto end;
2875
2876   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2877 end:
2878   vam->retval = retval;
2879   vam->result_ready = 1;
2880 }
2881
2882 static void
2883   vl_api_show_one_rloc_probe_state_reply_t_handler_json
2884   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2885 {
2886   vat_main_t *vam = &vat_main;
2887   vat_json_node_t _node, *node = &_node;
2888   int retval = clib_net_to_host_u32 (mp->retval);
2889
2890   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2891   vat_json_init_object (node);
2892   vat_json_object_add_string_copy (node, "state", s);
2893
2894   vat_json_print (vam->ofp, node);
2895   vat_json_free (node);
2896
2897   vam->retval = retval;
2898   vam->result_ready = 1;
2899   vec_free (s);
2900 }
2901
2902 static void
2903   vl_api_show_one_stats_enable_disable_reply_t_handler
2904   (vl_api_show_one_stats_enable_disable_reply_t * mp)
2905 {
2906   vat_main_t *vam = &vat_main;
2907   int retval = clib_net_to_host_u32 (mp->retval);
2908
2909   if (retval)
2910     goto end;
2911
2912   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
2913 end:
2914   vam->retval = retval;
2915   vam->result_ready = 1;
2916 }
2917
2918 static void
2919   vl_api_show_one_stats_enable_disable_reply_t_handler_json
2920   (vl_api_show_one_stats_enable_disable_reply_t * mp)
2921 {
2922   vat_main_t *vam = &vat_main;
2923   vat_json_node_t _node, *node = &_node;
2924   int retval = clib_net_to_host_u32 (mp->retval);
2925
2926   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
2927   vat_json_init_object (node);
2928   vat_json_object_add_string_copy (node, "state", s);
2929
2930   vat_json_print (vam->ofp, node);
2931   vat_json_free (node);
2932
2933   vam->retval = retval;
2934   vam->result_ready = 1;
2935   vec_free (s);
2936 }
2937
2938 static void
2939 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
2940 {
2941   e->dp_table = clib_net_to_host_u32 (e->dp_table);
2942   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
2943 }
2944
2945 static void
2946   gpe_fwd_entries_get_reply_t_net_to_host
2947   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2948 {
2949   u32 i;
2950
2951   mp->count = clib_net_to_host_u32 (mp->count);
2952   for (i = 0; i < mp->count; i++)
2953     {
2954       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
2955     }
2956 }
2957
2958 static u8 *
2959 format_gpe_encap_mode (u8 * s, va_list * args)
2960 {
2961   u32 mode = va_arg (*args, u32);
2962
2963   switch (mode)
2964     {
2965     case 0:
2966       return format (s, "lisp");
2967     case 1:
2968       return format (s, "vxlan");
2969     }
2970   return 0;
2971 }
2972
2973 static void
2974   vl_api_gpe_get_encap_mode_reply_t_handler
2975   (vl_api_gpe_get_encap_mode_reply_t * mp)
2976 {
2977   vat_main_t *vam = &vat_main;
2978
2979   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
2980   vam->retval = ntohl (mp->retval);
2981   vam->result_ready = 1;
2982 }
2983
2984 static void
2985   vl_api_gpe_get_encap_mode_reply_t_handler_json
2986   (vl_api_gpe_get_encap_mode_reply_t * mp)
2987 {
2988   vat_main_t *vam = &vat_main;
2989   vat_json_node_t node;
2990
2991   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
2992   vec_add1 (encap_mode, 0);
2993
2994   vat_json_init_object (&node);
2995   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
2996
2997   vec_free (encap_mode);
2998   vat_json_print (vam->ofp, &node);
2999   vat_json_free (&node);
3000
3001   vam->retval = ntohl (mp->retval);
3002   vam->result_ready = 1;
3003 }
3004
3005 static void
3006   vl_api_gpe_fwd_entry_path_details_t_handler
3007   (vl_api_gpe_fwd_entry_path_details_t * mp)
3008 {
3009   vat_main_t *vam = &vat_main;
3010   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3011
3012   if (mp->lcl_loc.is_ip4)
3013     format_ip_address_fcn = format_ip4_address;
3014   else
3015     format_ip_address_fcn = format_ip6_address;
3016
3017   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3018          format_ip_address_fcn, &mp->lcl_loc,
3019          format_ip_address_fcn, &mp->rmt_loc);
3020 }
3021
3022 static void
3023 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3024 {
3025   struct in6_addr ip6;
3026   struct in_addr ip4;
3027
3028   if (loc->is_ip4)
3029     {
3030       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3031       vat_json_object_add_ip4 (n, "address", ip4);
3032     }
3033   else
3034     {
3035       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3036       vat_json_object_add_ip6 (n, "address", ip6);
3037     }
3038   vat_json_object_add_uint (n, "weight", loc->weight);
3039 }
3040
3041 static void
3042   vl_api_gpe_fwd_entry_path_details_t_handler_json
3043   (vl_api_gpe_fwd_entry_path_details_t * mp)
3044 {
3045   vat_main_t *vam = &vat_main;
3046   vat_json_node_t *node = NULL;
3047   vat_json_node_t *loc_node;
3048
3049   if (VAT_JSON_ARRAY != vam->json_tree.type)
3050     {
3051       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3052       vat_json_init_array (&vam->json_tree);
3053     }
3054   node = vat_json_array_add (&vam->json_tree);
3055   vat_json_init_object (node);
3056
3057   loc_node = vat_json_object_add (node, "local_locator");
3058   vat_json_init_object (loc_node);
3059   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3060
3061   loc_node = vat_json_object_add (node, "remote_locator");
3062   vat_json_init_object (loc_node);
3063   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3064 }
3065
3066 static void
3067   vl_api_gpe_fwd_entries_get_reply_t_handler
3068   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3069 {
3070   vat_main_t *vam = &vat_main;
3071   u32 i;
3072   int retval = clib_net_to_host_u32 (mp->retval);
3073   vl_api_gpe_fwd_entry_t *e;
3074
3075   if (retval)
3076     goto end;
3077
3078   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3079
3080   for (i = 0; i < mp->count; i++)
3081     {
3082       e = &mp->entries[i];
3083       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3084              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3085              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3086     }
3087
3088 end:
3089   vam->retval = retval;
3090   vam->result_ready = 1;
3091 }
3092
3093 static void
3094   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3095   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3096 {
3097   u8 *s = 0;
3098   vat_main_t *vam = &vat_main;
3099   vat_json_node_t *e = 0, root;
3100   u32 i;
3101   int retval = clib_net_to_host_u32 (mp->retval);
3102   vl_api_gpe_fwd_entry_t *fwd;
3103
3104   if (retval)
3105     goto end;
3106
3107   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3108   vat_json_init_array (&root);
3109
3110   for (i = 0; i < mp->count; i++)
3111     {
3112       e = vat_json_array_add (&root);
3113       fwd = &mp->entries[i];
3114
3115       vat_json_init_object (e);
3116       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3117       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3118
3119       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3120                   fwd->leid_prefix_len);
3121       vec_add1 (s, 0);
3122       vat_json_object_add_string_copy (e, "leid", s);
3123       vec_free (s);
3124
3125       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3126                   fwd->reid_prefix_len);
3127       vec_add1 (s, 0);
3128       vat_json_object_add_string_copy (e, "reid", s);
3129       vec_free (s);
3130     }
3131
3132   vat_json_print (vam->ofp, &root);
3133   vat_json_free (&root);
3134
3135 end:
3136   vam->retval = retval;
3137   vam->result_ready = 1;
3138 }
3139
3140 static void
3141   vl_api_one_adjacencies_get_reply_t_handler
3142   (vl_api_one_adjacencies_get_reply_t * mp)
3143 {
3144   vat_main_t *vam = &vat_main;
3145   u32 i, n;
3146   int retval = clib_net_to_host_u32 (mp->retval);
3147   vl_api_one_adjacency_t *a;
3148
3149   if (retval)
3150     goto end;
3151
3152   n = clib_net_to_host_u32 (mp->count);
3153
3154   for (i = 0; i < n; i++)
3155     {
3156       a = &mp->adjacencies[i];
3157       print (vam->ofp, "%U %40U",
3158              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3159              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3160     }
3161
3162 end:
3163   vam->retval = retval;
3164   vam->result_ready = 1;
3165 }
3166
3167 static void
3168   vl_api_one_adjacencies_get_reply_t_handler_json
3169   (vl_api_one_adjacencies_get_reply_t * mp)
3170 {
3171   u8 *s = 0;
3172   vat_main_t *vam = &vat_main;
3173   vat_json_node_t *e = 0, root;
3174   u32 i, n;
3175   int retval = clib_net_to_host_u32 (mp->retval);
3176   vl_api_one_adjacency_t *a;
3177
3178   if (retval)
3179     goto end;
3180
3181   n = clib_net_to_host_u32 (mp->count);
3182   vat_json_init_array (&root);
3183
3184   for (i = 0; i < n; i++)
3185     {
3186       e = vat_json_array_add (&root);
3187       a = &mp->adjacencies[i];
3188
3189       vat_json_init_object (e);
3190       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3191                   a->leid_prefix_len);
3192       vec_add1 (s, 0);
3193       vat_json_object_add_string_copy (e, "leid", s);
3194       vec_free (s);
3195
3196       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3197                   a->reid_prefix_len);
3198       vec_add1 (s, 0);
3199       vat_json_object_add_string_copy (e, "reid", s);
3200       vec_free (s);
3201     }
3202
3203   vat_json_print (vam->ofp, &root);
3204   vat_json_free (&root);
3205
3206 end:
3207   vam->retval = retval;
3208   vam->result_ready = 1;
3209 }
3210
3211 static void
3212 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3213 {
3214   vat_main_t *vam = &vat_main;
3215
3216   print (vam->ofp, "%=20U",
3217          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3218          mp->ip_address);
3219 }
3220
3221 static void
3222   vl_api_one_map_server_details_t_handler_json
3223   (vl_api_one_map_server_details_t * mp)
3224 {
3225   vat_main_t *vam = &vat_main;
3226   vat_json_node_t *node = NULL;
3227   struct in6_addr ip6;
3228   struct in_addr ip4;
3229
3230   if (VAT_JSON_ARRAY != vam->json_tree.type)
3231     {
3232       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3233       vat_json_init_array (&vam->json_tree);
3234     }
3235   node = vat_json_array_add (&vam->json_tree);
3236
3237   vat_json_init_object (node);
3238   if (mp->is_ipv6)
3239     {
3240       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3241       vat_json_object_add_ip6 (node, "map-server", ip6);
3242     }
3243   else
3244     {
3245       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3246       vat_json_object_add_ip4 (node, "map-server", ip4);
3247     }
3248 }
3249
3250 static void
3251 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3252                                            * mp)
3253 {
3254   vat_main_t *vam = &vat_main;
3255
3256   print (vam->ofp, "%=20U",
3257          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3258          mp->ip_address);
3259 }
3260
3261 static void
3262   vl_api_one_map_resolver_details_t_handler_json
3263   (vl_api_one_map_resolver_details_t * mp)
3264 {
3265   vat_main_t *vam = &vat_main;
3266   vat_json_node_t *node = NULL;
3267   struct in6_addr ip6;
3268   struct in_addr ip4;
3269
3270   if (VAT_JSON_ARRAY != vam->json_tree.type)
3271     {
3272       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3273       vat_json_init_array (&vam->json_tree);
3274     }
3275   node = vat_json_array_add (&vam->json_tree);
3276
3277   vat_json_init_object (node);
3278   if (mp->is_ipv6)
3279     {
3280       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3281       vat_json_object_add_ip6 (node, "map resolver", ip6);
3282     }
3283   else
3284     {
3285       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3286       vat_json_object_add_ip4 (node, "map resolver", ip4);
3287     }
3288 }
3289
3290 static void
3291 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
3292 {
3293   vat_main_t *vam = &vat_main;
3294   i32 retval = ntohl (mp->retval);
3295
3296   if (0 <= retval)
3297     {
3298       print (vam->ofp, "feature: %s\ngpe: %s",
3299              mp->feature_status ? "enabled" : "disabled",
3300              mp->gpe_status ? "enabled" : "disabled");
3301     }
3302
3303   vam->retval = retval;
3304   vam->result_ready = 1;
3305 }
3306
3307 static void
3308   vl_api_show_one_status_reply_t_handler_json
3309   (vl_api_show_one_status_reply_t * mp)
3310 {
3311   vat_main_t *vam = &vat_main;
3312   vat_json_node_t node;
3313   u8 *gpe_status = NULL;
3314   u8 *feature_status = NULL;
3315
3316   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
3317   feature_status = format (0, "%s",
3318                            mp->feature_status ? "enabled" : "disabled");
3319   vec_add1 (gpe_status, 0);
3320   vec_add1 (feature_status, 0);
3321
3322   vat_json_init_object (&node);
3323   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
3324   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
3325
3326   vec_free (gpe_status);
3327   vec_free (feature_status);
3328
3329   vat_json_print (vam->ofp, &node);
3330   vat_json_free (&node);
3331
3332   vam->retval = ntohl (mp->retval);
3333   vam->result_ready = 1;
3334 }
3335
3336 static void
3337   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
3338   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3339 {
3340   vat_main_t *vam = &vat_main;
3341   i32 retval = ntohl (mp->retval);
3342
3343   if (retval >= 0)
3344     {
3345       print (vam->ofp, "%=20s", mp->locator_set_name);
3346     }
3347
3348   vam->retval = retval;
3349   vam->result_ready = 1;
3350 }
3351
3352 static void
3353   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
3354   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3355 {
3356   vat_main_t *vam = &vat_main;
3357   vat_json_node_t *node = NULL;
3358
3359   if (VAT_JSON_ARRAY != vam->json_tree.type)
3360     {
3361       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3362       vat_json_init_array (&vam->json_tree);
3363     }
3364   node = vat_json_array_add (&vam->json_tree);
3365
3366   vat_json_init_object (node);
3367   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
3368
3369   vat_json_print (vam->ofp, node);
3370   vat_json_free (node);
3371
3372   vam->retval = ntohl (mp->retval);
3373   vam->result_ready = 1;
3374 }
3375
3376 static u8 *
3377 format_lisp_map_request_mode (u8 * s, va_list * args)
3378 {
3379   u32 mode = va_arg (*args, u32);
3380
3381   switch (mode)
3382     {
3383     case 0:
3384       return format (0, "dst-only");
3385     case 1:
3386       return format (0, "src-dst");
3387     }
3388   return 0;
3389 }
3390
3391 static void
3392   vl_api_show_one_map_request_mode_reply_t_handler
3393   (vl_api_show_one_map_request_mode_reply_t * mp)
3394 {
3395   vat_main_t *vam = &vat_main;
3396   i32 retval = ntohl (mp->retval);
3397
3398   if (0 <= retval)
3399     {
3400       u32 mode = mp->mode;
3401       print (vam->ofp, "map_request_mode: %U",
3402              format_lisp_map_request_mode, mode);
3403     }
3404
3405   vam->retval = retval;
3406   vam->result_ready = 1;
3407 }
3408
3409 static void
3410   vl_api_show_one_map_request_mode_reply_t_handler_json
3411   (vl_api_show_one_map_request_mode_reply_t * mp)
3412 {
3413   vat_main_t *vam = &vat_main;
3414   vat_json_node_t node;
3415   u8 *s = 0;
3416   u32 mode;
3417
3418   mode = mp->mode;
3419   s = format (0, "%U", format_lisp_map_request_mode, mode);
3420   vec_add1 (s, 0);
3421
3422   vat_json_init_object (&node);
3423   vat_json_object_add_string_copy (&node, "map_request_mode", s);
3424   vat_json_print (vam->ofp, &node);
3425   vat_json_free (&node);
3426
3427   vec_free (s);
3428   vam->retval = ntohl (mp->retval);
3429   vam->result_ready = 1;
3430 }
3431
3432 static void
3433   vl_api_show_one_use_petr_reply_t_handler
3434   (vl_api_show_one_use_petr_reply_t * mp)
3435 {
3436   vat_main_t *vam = &vat_main;
3437   i32 retval = ntohl (mp->retval);
3438
3439   if (0 <= retval)
3440     {
3441       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
3442       if (mp->status)
3443         {
3444           print (vam->ofp, "Proxy-ETR address; %U",
3445                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
3446                  mp->address);
3447         }
3448     }
3449
3450   vam->retval = retval;
3451   vam->result_ready = 1;
3452 }
3453
3454 static void
3455   vl_api_show_one_use_petr_reply_t_handler_json
3456   (vl_api_show_one_use_petr_reply_t * mp)
3457 {
3458   vat_main_t *vam = &vat_main;
3459   vat_json_node_t node;
3460   u8 *status = 0;
3461   struct in_addr ip4;
3462   struct in6_addr ip6;
3463
3464   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3465   vec_add1 (status, 0);
3466
3467   vat_json_init_object (&node);
3468   vat_json_object_add_string_copy (&node, "status", status);
3469   if (mp->status)
3470     {
3471       if (mp->is_ip4)
3472         {
3473           clib_memcpy (&ip6, mp->address, sizeof (ip6));
3474           vat_json_object_add_ip6 (&node, "address", ip6);
3475         }
3476       else
3477         {
3478           clib_memcpy (&ip4, mp->address, sizeof (ip4));
3479           vat_json_object_add_ip4 (&node, "address", ip4);
3480         }
3481     }
3482
3483   vec_free (status);
3484
3485   vat_json_print (vam->ofp, &node);
3486   vat_json_free (&node);
3487
3488   vam->retval = ntohl (mp->retval);
3489   vam->result_ready = 1;
3490 }
3491
3492 static void
3493 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
3494 {
3495   vat_main_t *vam = &vat_main;
3496   i32 retval = ntohl (mp->retval);
3497
3498   if (0 <= retval)
3499     {
3500       print (vam->ofp, "%-20s%-16s",
3501              mp->status ? "enabled" : "disabled",
3502              mp->status ? (char *) mp->locator_set_name : "");
3503     }
3504
3505   vam->retval = retval;
3506   vam->result_ready = 1;
3507 }
3508
3509 static void
3510 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
3511 {
3512   vat_main_t *vam = &vat_main;
3513   vat_json_node_t node;
3514   u8 *status = 0;
3515
3516   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3517   vec_add1 (status, 0);
3518
3519   vat_json_init_object (&node);
3520   vat_json_object_add_string_copy (&node, "status", status);
3521   if (mp->status)
3522     {
3523       vat_json_object_add_string_copy (&node, "locator_set",
3524                                        mp->locator_set_name);
3525     }
3526
3527   vec_free (status);
3528
3529   vat_json_print (vam->ofp, &node);
3530   vat_json_free (&node);
3531
3532   vam->retval = ntohl (mp->retval);
3533   vam->result_ready = 1;
3534 }
3535
3536 static u8 *
3537 format_policer_type (u8 * s, va_list * va)
3538 {
3539   u32 i = va_arg (*va, u32);
3540
3541   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
3542     s = format (s, "1r2c");
3543   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
3544     s = format (s, "1r3c");
3545   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
3546     s = format (s, "2r3c-2698");
3547   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
3548     s = format (s, "2r3c-4115");
3549   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
3550     s = format (s, "2r3c-mef5cf1");
3551   else
3552     s = format (s, "ILLEGAL");
3553   return s;
3554 }
3555
3556 static u8 *
3557 format_policer_rate_type (u8 * s, va_list * va)
3558 {
3559   u32 i = va_arg (*va, u32);
3560
3561   if (i == SSE2_QOS_RATE_KBPS)
3562     s = format (s, "kbps");
3563   else if (i == SSE2_QOS_RATE_PPS)
3564     s = format (s, "pps");
3565   else
3566     s = format (s, "ILLEGAL");
3567   return s;
3568 }
3569
3570 static u8 *
3571 format_policer_round_type (u8 * s, va_list * va)
3572 {
3573   u32 i = va_arg (*va, u32);
3574
3575   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3576     s = format (s, "closest");
3577   else if (i == SSE2_QOS_ROUND_TO_UP)
3578     s = format (s, "up");
3579   else if (i == SSE2_QOS_ROUND_TO_DOWN)
3580     s = format (s, "down");
3581   else
3582     s = format (s, "ILLEGAL");
3583   return s;
3584 }
3585
3586 static u8 *
3587 format_policer_action_type (u8 * s, va_list * va)
3588 {
3589   u32 i = va_arg (*va, u32);
3590
3591   if (i == SSE2_QOS_ACTION_DROP)
3592     s = format (s, "drop");
3593   else if (i == SSE2_QOS_ACTION_TRANSMIT)
3594     s = format (s, "transmit");
3595   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3596     s = format (s, "mark-and-transmit");
3597   else
3598     s = format (s, "ILLEGAL");
3599   return s;
3600 }
3601
3602 static u8 *
3603 format_dscp (u8 * s, va_list * va)
3604 {
3605   u32 i = va_arg (*va, u32);
3606   char *t = 0;
3607
3608   switch (i)
3609     {
3610 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3611       foreach_vnet_dscp
3612 #undef _
3613     default:
3614       return format (s, "ILLEGAL");
3615     }
3616   s = format (s, "%s", t);
3617   return s;
3618 }
3619
3620 static void
3621 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3622 {
3623   vat_main_t *vam = &vat_main;
3624   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3625
3626   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3627     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3628   else
3629     conform_dscp_str = format (0, "");
3630
3631   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3632     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3633   else
3634     exceed_dscp_str = format (0, "");
3635
3636   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3637     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3638   else
3639     violate_dscp_str = format (0, "");
3640
3641   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3642          "rate type %U, round type %U, %s rate, %s color-aware, "
3643          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3644          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3645          "conform action %U%s, exceed action %U%s, violate action %U%s",
3646          mp->name,
3647          format_policer_type, mp->type,
3648          ntohl (mp->cir),
3649          ntohl (mp->eir),
3650          clib_net_to_host_u64 (mp->cb),
3651          clib_net_to_host_u64 (mp->eb),
3652          format_policer_rate_type, mp->rate_type,
3653          format_policer_round_type, mp->round_type,
3654          mp->single_rate ? "single" : "dual",
3655          mp->color_aware ? "is" : "not",
3656          ntohl (mp->cir_tokens_per_period),
3657          ntohl (mp->pir_tokens_per_period),
3658          ntohl (mp->scale),
3659          ntohl (mp->current_limit),
3660          ntohl (mp->current_bucket),
3661          ntohl (mp->extended_limit),
3662          ntohl (mp->extended_bucket),
3663          clib_net_to_host_u64 (mp->last_update_time),
3664          format_policer_action_type, mp->conform_action_type,
3665          conform_dscp_str,
3666          format_policer_action_type, mp->exceed_action_type,
3667          exceed_dscp_str,
3668          format_policer_action_type, mp->violate_action_type,
3669          violate_dscp_str);
3670
3671   vec_free (conform_dscp_str);
3672   vec_free (exceed_dscp_str);
3673   vec_free (violate_dscp_str);
3674 }
3675
3676 static void vl_api_policer_details_t_handler_json
3677   (vl_api_policer_details_t * mp)
3678 {
3679   vat_main_t *vam = &vat_main;
3680   vat_json_node_t *node;
3681   u8 *rate_type_str, *round_type_str, *type_str;
3682   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3683
3684   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3685   round_type_str =
3686     format (0, "%U", format_policer_round_type, mp->round_type);
3687   type_str = format (0, "%U", format_policer_type, mp->type);
3688   conform_action_str = format (0, "%U", format_policer_action_type,
3689                                mp->conform_action_type);
3690   exceed_action_str = format (0, "%U", format_policer_action_type,
3691                               mp->exceed_action_type);
3692   violate_action_str = format (0, "%U", format_policer_action_type,
3693                                mp->violate_action_type);
3694
3695   if (VAT_JSON_ARRAY != vam->json_tree.type)
3696     {
3697       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3698       vat_json_init_array (&vam->json_tree);
3699     }
3700   node = vat_json_array_add (&vam->json_tree);
3701
3702   vat_json_init_object (node);
3703   vat_json_object_add_string_copy (node, "name", mp->name);
3704   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3705   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3706   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
3707   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
3708   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3709   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3710   vat_json_object_add_string_copy (node, "type", type_str);
3711   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3712   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3713   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3714   vat_json_object_add_uint (node, "cir_tokens_per_period",
3715                             ntohl (mp->cir_tokens_per_period));
3716   vat_json_object_add_uint (node, "eir_tokens_per_period",
3717                             ntohl (mp->pir_tokens_per_period));
3718   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3719   vat_json_object_add_uint (node, "current_bucket",
3720                             ntohl (mp->current_bucket));
3721   vat_json_object_add_uint (node, "extended_limit",
3722                             ntohl (mp->extended_limit));
3723   vat_json_object_add_uint (node, "extended_bucket",
3724                             ntohl (mp->extended_bucket));
3725   vat_json_object_add_uint (node, "last_update_time",
3726                             ntohl (mp->last_update_time));
3727   vat_json_object_add_string_copy (node, "conform_action",
3728                                    conform_action_str);
3729   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3730     {
3731       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3732       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3733       vec_free (dscp_str);
3734     }
3735   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3736   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3737     {
3738       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3739       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3740       vec_free (dscp_str);
3741     }
3742   vat_json_object_add_string_copy (node, "violate_action",
3743                                    violate_action_str);
3744   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3745     {
3746       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3747       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3748       vec_free (dscp_str);
3749     }
3750
3751   vec_free (rate_type_str);
3752   vec_free (round_type_str);
3753   vec_free (type_str);
3754   vec_free (conform_action_str);
3755   vec_free (exceed_action_str);
3756   vec_free (violate_action_str);
3757 }
3758
3759 static void
3760 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3761                                            mp)
3762 {
3763   vat_main_t *vam = &vat_main;
3764   int i, count = ntohl (mp->count);
3765
3766   if (count > 0)
3767     print (vam->ofp, "classify table ids (%d) : ", count);
3768   for (i = 0; i < count; i++)
3769     {
3770       print (vam->ofp, "%d", ntohl (mp->ids[i]));
3771       print (vam->ofp, (i < count - 1) ? "," : "");
3772     }
3773   vam->retval = ntohl (mp->retval);
3774   vam->result_ready = 1;
3775 }
3776
3777 static void
3778   vl_api_classify_table_ids_reply_t_handler_json
3779   (vl_api_classify_table_ids_reply_t * mp)
3780 {
3781   vat_main_t *vam = &vat_main;
3782   int i, count = ntohl (mp->count);
3783
3784   if (count > 0)
3785     {
3786       vat_json_node_t node;
3787
3788       vat_json_init_object (&node);
3789       for (i = 0; i < count; i++)
3790         {
3791           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3792         }
3793       vat_json_print (vam->ofp, &node);
3794       vat_json_free (&node);
3795     }
3796   vam->retval = ntohl (mp->retval);
3797   vam->result_ready = 1;
3798 }
3799
3800 static void
3801   vl_api_classify_table_by_interface_reply_t_handler
3802   (vl_api_classify_table_by_interface_reply_t * mp)
3803 {
3804   vat_main_t *vam = &vat_main;
3805   u32 table_id;
3806
3807   table_id = ntohl (mp->l2_table_id);
3808   if (table_id != ~0)
3809     print (vam->ofp, "l2 table id : %d", table_id);
3810   else
3811     print (vam->ofp, "l2 table id : No input ACL tables configured");
3812   table_id = ntohl (mp->ip4_table_id);
3813   if (table_id != ~0)
3814     print (vam->ofp, "ip4 table id : %d", table_id);
3815   else
3816     print (vam->ofp, "ip4 table id : No input ACL tables configured");
3817   table_id = ntohl (mp->ip6_table_id);
3818   if (table_id != ~0)
3819     print (vam->ofp, "ip6 table id : %d", table_id);
3820   else
3821     print (vam->ofp, "ip6 table id : No input ACL tables configured");
3822   vam->retval = ntohl (mp->retval);
3823   vam->result_ready = 1;
3824 }
3825
3826 static void
3827   vl_api_classify_table_by_interface_reply_t_handler_json
3828   (vl_api_classify_table_by_interface_reply_t * mp)
3829 {
3830   vat_main_t *vam = &vat_main;
3831   vat_json_node_t node;
3832
3833   vat_json_init_object (&node);
3834
3835   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3836   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3837   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3838
3839   vat_json_print (vam->ofp, &node);
3840   vat_json_free (&node);
3841
3842   vam->retval = ntohl (mp->retval);
3843   vam->result_ready = 1;
3844 }
3845
3846 static void vl_api_policer_add_del_reply_t_handler
3847   (vl_api_policer_add_del_reply_t * mp)
3848 {
3849   vat_main_t *vam = &vat_main;
3850   i32 retval = ntohl (mp->retval);
3851   if (vam->async_mode)
3852     {
3853       vam->async_errors += (retval < 0);
3854     }
3855   else
3856     {
3857       vam->retval = retval;
3858       vam->result_ready = 1;
3859       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3860         /*
3861          * Note: this is just barely thread-safe, depends on
3862          * the main thread spinning waiting for an answer...
3863          */
3864         errmsg ("policer index %d", ntohl (mp->policer_index));
3865     }
3866 }
3867
3868 static void vl_api_policer_add_del_reply_t_handler_json
3869   (vl_api_policer_add_del_reply_t * mp)
3870 {
3871   vat_main_t *vam = &vat_main;
3872   vat_json_node_t node;
3873
3874   vat_json_init_object (&node);
3875   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3876   vat_json_object_add_uint (&node, "policer_index",
3877                             ntohl (mp->policer_index));
3878
3879   vat_json_print (vam->ofp, &node);
3880   vat_json_free (&node);
3881
3882   vam->retval = ntohl (mp->retval);
3883   vam->result_ready = 1;
3884 }
3885
3886 /* Format hex dump. */
3887 u8 *
3888 format_hex_bytes (u8 * s, va_list * va)
3889 {
3890   u8 *bytes = va_arg (*va, u8 *);
3891   int n_bytes = va_arg (*va, int);
3892   uword i;
3893
3894   /* Print short or long form depending on byte count. */
3895   uword short_form = n_bytes <= 32;
3896   uword indent = format_get_indent (s);
3897
3898   if (n_bytes == 0)
3899     return s;
3900
3901   for (i = 0; i < n_bytes; i++)
3902     {
3903       if (!short_form && (i % 32) == 0)
3904         s = format (s, "%08x: ", i);
3905       s = format (s, "%02x", bytes[i]);
3906       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3907         s = format (s, "\n%U", format_white_space, indent);
3908     }
3909
3910   return s;
3911 }
3912
3913 static void
3914 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3915                                             * mp)
3916 {
3917   vat_main_t *vam = &vat_main;
3918   i32 retval = ntohl (mp->retval);
3919   if (retval == 0)
3920     {
3921       print (vam->ofp, "classify table info :");
3922       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3923              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3924              ntohl (mp->miss_next_index));
3925       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3926              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3927              ntohl (mp->match_n_vectors));
3928       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3929              ntohl (mp->mask_length));
3930     }
3931   vam->retval = retval;
3932   vam->result_ready = 1;
3933 }
3934
3935 static void
3936   vl_api_classify_table_info_reply_t_handler_json
3937   (vl_api_classify_table_info_reply_t * mp)
3938 {
3939   vat_main_t *vam = &vat_main;
3940   vat_json_node_t node;
3941
3942   i32 retval = ntohl (mp->retval);
3943   if (retval == 0)
3944     {
3945       vat_json_init_object (&node);
3946
3947       vat_json_object_add_int (&node, "sessions",
3948                                ntohl (mp->active_sessions));
3949       vat_json_object_add_int (&node, "nexttbl",
3950                                ntohl (mp->next_table_index));
3951       vat_json_object_add_int (&node, "nextnode",
3952                                ntohl (mp->miss_next_index));
3953       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3954       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3955       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3956       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3957                       ntohl (mp->mask_length), 0);
3958       vat_json_object_add_string_copy (&node, "mask", s);
3959
3960       vat_json_print (vam->ofp, &node);
3961       vat_json_free (&node);
3962     }
3963   vam->retval = ntohl (mp->retval);
3964   vam->result_ready = 1;
3965 }
3966
3967 static void
3968 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3969                                            mp)
3970 {
3971   vat_main_t *vam = &vat_main;
3972
3973   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3974          ntohl (mp->hit_next_index), ntohl (mp->advance),
3975          ntohl (mp->opaque_index));
3976   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3977          ntohl (mp->match_length));
3978 }
3979
3980 static void
3981   vl_api_classify_session_details_t_handler_json
3982   (vl_api_classify_session_details_t * mp)
3983 {
3984   vat_main_t *vam = &vat_main;
3985   vat_json_node_t *node = NULL;
3986
3987   if (VAT_JSON_ARRAY != vam->json_tree.type)
3988     {
3989       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3990       vat_json_init_array (&vam->json_tree);
3991     }
3992   node = vat_json_array_add (&vam->json_tree);
3993
3994   vat_json_init_object (node);
3995   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3996   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3997   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3998   u8 *s =
3999     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4000             0);
4001   vat_json_object_add_string_copy (node, "match", s);
4002 }
4003
4004 static void vl_api_pg_create_interface_reply_t_handler
4005   (vl_api_pg_create_interface_reply_t * mp)
4006 {
4007   vat_main_t *vam = &vat_main;
4008
4009   vam->retval = ntohl (mp->retval);
4010   vam->result_ready = 1;
4011 }
4012
4013 static void vl_api_pg_create_interface_reply_t_handler_json
4014   (vl_api_pg_create_interface_reply_t * mp)
4015 {
4016   vat_main_t *vam = &vat_main;
4017   vat_json_node_t node;
4018
4019   i32 retval = ntohl (mp->retval);
4020   if (retval == 0)
4021     {
4022       vat_json_init_object (&node);
4023
4024       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4025
4026       vat_json_print (vam->ofp, &node);
4027       vat_json_free (&node);
4028     }
4029   vam->retval = ntohl (mp->retval);
4030   vam->result_ready = 1;
4031 }
4032
4033 static void vl_api_policer_classify_details_t_handler
4034   (vl_api_policer_classify_details_t * mp)
4035 {
4036   vat_main_t *vam = &vat_main;
4037
4038   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4039          ntohl (mp->table_index));
4040 }
4041
4042 static void vl_api_policer_classify_details_t_handler_json
4043   (vl_api_policer_classify_details_t * mp)
4044 {
4045   vat_main_t *vam = &vat_main;
4046   vat_json_node_t *node;
4047
4048   if (VAT_JSON_ARRAY != vam->json_tree.type)
4049     {
4050       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4051       vat_json_init_array (&vam->json_tree);
4052     }
4053   node = vat_json_array_add (&vam->json_tree);
4054
4055   vat_json_init_object (node);
4056   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4057   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4058 }
4059
4060 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
4061   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4062 {
4063   vat_main_t *vam = &vat_main;
4064   i32 retval = ntohl (mp->retval);
4065   if (vam->async_mode)
4066     {
4067       vam->async_errors += (retval < 0);
4068     }
4069   else
4070     {
4071       vam->retval = retval;
4072       vam->sw_if_index = ntohl (mp->sw_if_index);
4073       vam->result_ready = 1;
4074     }
4075 }
4076
4077 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
4078   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4079 {
4080   vat_main_t *vam = &vat_main;
4081   vat_json_node_t node;
4082
4083   vat_json_init_object (&node);
4084   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4085   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
4086
4087   vat_json_print (vam->ofp, &node);
4088   vat_json_free (&node);
4089
4090   vam->retval = ntohl (mp->retval);
4091   vam->result_ready = 1;
4092 }
4093
4094 static void vl_api_flow_classify_details_t_handler
4095   (vl_api_flow_classify_details_t * mp)
4096 {
4097   vat_main_t *vam = &vat_main;
4098
4099   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4100          ntohl (mp->table_index));
4101 }
4102
4103 static void vl_api_flow_classify_details_t_handler_json
4104   (vl_api_flow_classify_details_t * mp)
4105 {
4106   vat_main_t *vam = &vat_main;
4107   vat_json_node_t *node;
4108
4109   if (VAT_JSON_ARRAY != vam->json_tree.type)
4110     {
4111       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4112       vat_json_init_array (&vam->json_tree);
4113     }
4114   node = vat_json_array_add (&vam->json_tree);
4115
4116   vat_json_init_object (node);
4117   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4118   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4119 }
4120
4121
4122
4123 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
4124 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
4125 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
4126 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
4127 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
4128 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
4129 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
4130 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
4131 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
4132 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
4133
4134 /*
4135  * Generate boilerplate reply handlers, which
4136  * dig the return value out of the xxx_reply_t API message,
4137  * stick it into vam->retval, and set vam->result_ready
4138  *
4139  * Could also do this by pointing N message decode slots at
4140  * a single function, but that could break in subtle ways.
4141  */
4142
4143 #define foreach_standard_reply_retval_handler           \
4144 _(sw_interface_set_flags_reply)                         \
4145 _(sw_interface_add_del_address_reply)                   \
4146 _(sw_interface_set_table_reply)                         \
4147 _(sw_interface_set_mpls_enable_reply)                   \
4148 _(sw_interface_set_vpath_reply)                         \
4149 _(sw_interface_set_vxlan_bypass_reply)                  \
4150 _(sw_interface_set_l2_bridge_reply)                     \
4151 _(bridge_domain_add_del_reply)                          \
4152 _(sw_interface_set_l2_xconnect_reply)                   \
4153 _(l2fib_add_del_reply)                                  \
4154 _(l2fib_flush_int_reply)                                \
4155 _(l2fib_flush_bd_reply)                                 \
4156 _(ip_add_del_route_reply)                               \
4157 _(ip_mroute_add_del_reply)                              \
4158 _(mpls_route_add_del_reply)                             \
4159 _(mpls_ip_bind_unbind_reply)                            \
4160 _(proxy_arp_add_del_reply)                              \
4161 _(proxy_arp_intfc_enable_disable_reply)                 \
4162 _(sw_interface_set_unnumbered_reply)                    \
4163 _(ip_neighbor_add_del_reply)                            \
4164 _(reset_vrf_reply)                                      \
4165 _(oam_add_del_reply)                                    \
4166 _(reset_fib_reply)                                      \
4167 _(dhcp_proxy_config_reply)                              \
4168 _(dhcp_proxy_set_vss_reply)                             \
4169 _(dhcp_client_config_reply)                             \
4170 _(set_ip_flow_hash_reply)                               \
4171 _(sw_interface_ip6_enable_disable_reply)                \
4172 _(sw_interface_ip6_set_link_local_address_reply)        \
4173 _(ip6nd_proxy_add_del_reply)                            \
4174 _(sw_interface_ip6nd_ra_prefix_reply)                   \
4175 _(sw_interface_ip6nd_ra_config_reply)                   \
4176 _(set_arp_neighbor_limit_reply)                         \
4177 _(l2_patch_add_del_reply)                               \
4178 _(sr_policy_add_reply)                                  \
4179 _(sr_policy_mod_reply)                                  \
4180 _(sr_policy_del_reply)                                  \
4181 _(sr_localsid_add_del_reply)                            \
4182 _(sr_steering_add_del_reply)                            \
4183 _(classify_add_del_session_reply)                       \
4184 _(classify_set_interface_ip_table_reply)                \
4185 _(classify_set_interface_l2_tables_reply)               \
4186 _(l2tpv3_set_tunnel_cookies_reply)                      \
4187 _(l2tpv3_interface_enable_disable_reply)                \
4188 _(l2tpv3_set_lookup_key_reply)                          \
4189 _(l2_fib_clear_table_reply)                             \
4190 _(l2_interface_efp_filter_reply)                        \
4191 _(l2_interface_vlan_tag_rewrite_reply)                  \
4192 _(modify_vhost_user_if_reply)                           \
4193 _(delete_vhost_user_if_reply)                           \
4194 _(want_ip4_arp_events_reply)                            \
4195 _(want_ip6_nd_events_reply)                             \
4196 _(input_acl_set_interface_reply)                        \
4197 _(ipsec_spd_add_del_reply)                              \
4198 _(ipsec_interface_add_del_spd_reply)                    \
4199 _(ipsec_spd_add_del_entry_reply)                        \
4200 _(ipsec_sad_add_del_entry_reply)                        \
4201 _(ipsec_sa_set_key_reply)                               \
4202 _(ipsec_tunnel_if_add_del_reply)                        \
4203 _(ikev2_profile_add_del_reply)                          \
4204 _(ikev2_profile_set_auth_reply)                         \
4205 _(ikev2_profile_set_id_reply)                           \
4206 _(ikev2_profile_set_ts_reply)                           \
4207 _(ikev2_set_local_key_reply)                            \
4208 _(ikev2_set_responder_reply)                            \
4209 _(ikev2_set_ike_transforms_reply)                       \
4210 _(ikev2_set_esp_transforms_reply)                       \
4211 _(ikev2_set_sa_lifetime_reply)                          \
4212 _(ikev2_initiate_sa_init_reply)                         \
4213 _(ikev2_initiate_del_ike_sa_reply)                      \
4214 _(ikev2_initiate_del_child_sa_reply)                    \
4215 _(ikev2_initiate_rekey_child_sa_reply)                  \
4216 _(delete_loopback_reply)                                \
4217 _(bd_ip_mac_add_del_reply)                              \
4218 _(map_del_domain_reply)                                 \
4219 _(map_add_del_rule_reply)                               \
4220 _(want_interface_events_reply)                          \
4221 _(want_stats_reply)                                     \
4222 _(cop_interface_enable_disable_reply)                   \
4223 _(cop_whitelist_enable_disable_reply)                   \
4224 _(sw_interface_clear_stats_reply)                       \
4225 _(ioam_enable_reply)                              \
4226 _(ioam_disable_reply)                              \
4227 _(one_add_del_locator_reply)                            \
4228 _(one_add_del_local_eid_reply)                          \
4229 _(one_add_del_remote_mapping_reply)                     \
4230 _(one_add_del_adjacency_reply)                          \
4231 _(one_add_del_map_resolver_reply)                       \
4232 _(one_add_del_map_server_reply)                         \
4233 _(one_enable_disable_reply)                             \
4234 _(one_rloc_probe_enable_disable_reply)                  \
4235 _(one_map_register_enable_disable_reply)                \
4236 _(one_pitr_set_locator_set_reply)                       \
4237 _(one_map_request_mode_reply)                           \
4238 _(one_add_del_map_request_itr_rlocs_reply)              \
4239 _(one_eid_table_add_del_map_reply)                      \
4240 _(one_use_petr_reply)                                   \
4241 _(one_stats_enable_disable_reply)                       \
4242 _(one_stats_flush_reply)                                \
4243 _(gpe_add_del_fwd_entry_reply)                          \
4244 _(gpe_enable_disable_reply)                             \
4245 _(gpe_set_encap_mode_reply)                             \
4246 _(gpe_add_del_iface_reply)                              \
4247 _(vxlan_gpe_add_del_tunnel_reply)                       \
4248 _(af_packet_delete_reply)                               \
4249 _(policer_classify_set_interface_reply)                 \
4250 _(netmap_create_reply)                                  \
4251 _(netmap_delete_reply)                                  \
4252 _(set_ipfix_exporter_reply)                             \
4253 _(set_ipfix_classify_stream_reply)                      \
4254 _(ipfix_classify_table_add_del_reply)                   \
4255 _(flow_classify_set_interface_reply)                    \
4256 _(sw_interface_span_enable_disable_reply)               \
4257 _(pg_capture_reply)                                     \
4258 _(pg_enable_disable_reply)                              \
4259 _(ip_source_and_port_range_check_add_del_reply)         \
4260 _(ip_source_and_port_range_check_interface_add_del_reply)\
4261 _(delete_subif_reply)                                   \
4262 _(l2_interface_pbb_tag_rewrite_reply)                   \
4263 _(punt_reply)                                           \
4264 _(feature_enable_disable_reply)                         \
4265 _(sw_interface_tag_add_del_reply)                       \
4266 _(sw_interface_set_mtu_reply)
4267
4268 #define _(n)                                    \
4269     static void vl_api_##n##_t_handler          \
4270     (vl_api_##n##_t * mp)                       \
4271     {                                           \
4272         vat_main_t * vam = &vat_main;           \
4273         i32 retval = ntohl(mp->retval);         \
4274         if (vam->async_mode) {                  \
4275             vam->async_errors += (retval < 0);  \
4276         } else {                                \
4277             vam->retval = retval;               \
4278             vam->result_ready = 1;              \
4279         }                                       \
4280     }
4281 foreach_standard_reply_retval_handler;
4282 #undef _
4283
4284 #define _(n)                                    \
4285     static void vl_api_##n##_t_handler_json     \
4286     (vl_api_##n##_t * mp)                       \
4287     {                                           \
4288         vat_main_t * vam = &vat_main;           \
4289         vat_json_node_t node;                   \
4290         vat_json_init_object(&node);            \
4291         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
4292         vat_json_print(vam->ofp, &node);        \
4293         vam->retval = ntohl(mp->retval);        \
4294         vam->result_ready = 1;                  \
4295     }
4296 foreach_standard_reply_retval_handler;
4297 #undef _
4298
4299 /*
4300  * Table of message reply handlers, must include boilerplate handlers
4301  * we just generated
4302  */
4303
4304 #define foreach_vpe_api_reply_msg                                       \
4305 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
4306 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
4307 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
4308 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
4309 _(CONTROL_PING_REPLY, control_ping_reply)                               \
4310 _(CLI_REPLY, cli_reply)                                                 \
4311 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
4312 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
4313   sw_interface_add_del_address_reply)                                   \
4314 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
4315 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
4316 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
4317 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
4318 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
4319   sw_interface_set_l2_xconnect_reply)                                   \
4320 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
4321   sw_interface_set_l2_bridge_reply)                                     \
4322 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
4323 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
4324 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
4325 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
4326 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
4327 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
4328 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
4329 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
4330 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
4331 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
4332 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
4333 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
4334 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
4335 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
4336 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
4337 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
4338 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
4339 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
4340 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
4341   proxy_arp_intfc_enable_disable_reply)                                 \
4342 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
4343 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
4344   sw_interface_set_unnumbered_reply)                                    \
4345 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
4346 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
4347 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
4348 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
4349 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
4350 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
4351 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
4352 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
4353 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
4354 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
4355 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
4356 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
4357   sw_interface_ip6_enable_disable_reply)                                \
4358 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
4359   sw_interface_ip6_set_link_local_address_reply)                        \
4360 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
4361 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
4362 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
4363   sw_interface_ip6nd_ra_prefix_reply)                                   \
4364 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
4365   sw_interface_ip6nd_ra_config_reply)                                   \
4366 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
4367 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
4368 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
4369 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
4370 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
4371 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
4372 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
4373 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
4374 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
4375 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
4376 classify_set_interface_ip_table_reply)                                  \
4377 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
4378   classify_set_interface_l2_tables_reply)                               \
4379 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
4380 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
4381 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
4382 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
4383 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
4384   l2tpv3_interface_enable_disable_reply)                                \
4385 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
4386 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
4387 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
4388 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
4389 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
4390 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
4391 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
4392 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
4393 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4394 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
4395 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
4396 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
4397 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
4398 _(SHOW_VERSION_REPLY, show_version_reply)                               \
4399 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
4400 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
4401 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
4402 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
4403 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
4404 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
4405 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
4406 _(IP6_ND_EVENT, ip6_nd_event)                                           \
4407 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
4408 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
4409 _(IP_DETAILS, ip_details)                                               \
4410 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
4411 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4412 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
4413 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
4414 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
4415 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
4416 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
4417 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
4418 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
4419 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
4420 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
4421 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
4422 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
4423 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
4424 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
4425 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
4426 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
4427 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
4428 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
4429 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
4430 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
4431 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
4432 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
4433 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
4434 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
4435 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
4436 _(MAP_RULE_DETAILS, map_rule_details)                                   \
4437 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
4438 _(WANT_STATS_REPLY, want_stats_reply)                                   \
4439 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
4440 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4441 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4442 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
4443 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
4444 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
4445 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
4446 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
4447 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
4448 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
4449 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
4450 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
4451 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
4452 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
4453 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
4454 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
4455   one_map_register_enable_disable_reply)                                \
4456 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
4457   one_rloc_probe_enable_disable_reply)                                  \
4458 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
4459 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
4460 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
4461 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
4462 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
4463 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
4464 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
4465 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
4466 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
4467 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
4468 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
4469 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
4470 _(ONE_STATS_DETAILS, one_stats_details)                                 \
4471 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
4472 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
4473 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
4474   show_one_stats_enable_disable_reply)                                  \
4475 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
4476 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
4477 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
4478 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
4479 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
4480 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
4481 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
4482   gpe_fwd_entry_path_details)                                           \
4483 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
4484 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
4485   one_add_del_map_request_itr_rlocs_reply)                              \
4486 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
4487   one_get_map_request_itr_rlocs_reply)                                  \
4488 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
4489 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
4490 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
4491 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
4492 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
4493   show_one_map_register_state_reply)                                    \
4494 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
4495 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
4496 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
4497 _(POLICER_DETAILS, policer_details)                                     \
4498 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4499 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
4500 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
4501 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
4502 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
4503 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
4504 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
4505 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4506 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
4507 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
4508 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
4509 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
4510 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
4511 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
4512 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4513 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
4514 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4515 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
4516 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
4517 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
4518 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
4519 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
4520 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
4521 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
4522 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
4523  ip_source_and_port_range_check_add_del_reply)                          \
4524 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
4525  ip_source_and_port_range_check_interface_add_del_reply)                \
4526 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
4527 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
4528 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
4529 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
4530 _(PUNT_REPLY, punt_reply)                                               \
4531 _(IP_FIB_DETAILS, ip_fib_details)                                       \
4532 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
4533 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
4534 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
4535 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
4536 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
4537 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
4538 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
4539
4540 #define foreach_standalone_reply_msg                                    \
4541 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
4542 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
4543 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
4544 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
4545 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
4546 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
4547
4548 typedef struct
4549 {
4550   u8 *name;
4551   u32 value;
4552 } name_sort_t;
4553
4554
4555 #define STR_VTR_OP_CASE(op)     \
4556     case L2_VTR_ ## op:         \
4557         return "" # op;
4558
4559 static const char *
4560 str_vtr_op (u32 vtr_op)
4561 {
4562   switch (vtr_op)
4563     {
4564       STR_VTR_OP_CASE (DISABLED);
4565       STR_VTR_OP_CASE (PUSH_1);
4566       STR_VTR_OP_CASE (PUSH_2);
4567       STR_VTR_OP_CASE (POP_1);
4568       STR_VTR_OP_CASE (POP_2);
4569       STR_VTR_OP_CASE (TRANSLATE_1_1);
4570       STR_VTR_OP_CASE (TRANSLATE_1_2);
4571       STR_VTR_OP_CASE (TRANSLATE_2_1);
4572       STR_VTR_OP_CASE (TRANSLATE_2_2);
4573     }
4574
4575   return "UNKNOWN";
4576 }
4577
4578 static int
4579 dump_sub_interface_table (vat_main_t * vam)
4580 {
4581   const sw_interface_subif_t *sub = NULL;
4582
4583   if (vam->json_output)
4584     {
4585       clib_warning
4586         ("JSON output supported only for VPE API calls and dump_stats_table");
4587       return -99;
4588     }
4589
4590   print (vam->ofp,
4591          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4592          "Interface", "sw_if_index",
4593          "sub id", "dot1ad", "tags", "outer id",
4594          "inner id", "exact", "default", "outer any", "inner any");
4595
4596   vec_foreach (sub, vam->sw_if_subif_table)
4597   {
4598     print (vam->ofp,
4599            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4600            sub->interface_name,
4601            sub->sw_if_index,
4602            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4603            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4604            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4605            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4606     if (sub->vtr_op != L2_VTR_DISABLED)
4607       {
4608         print (vam->ofp,
4609                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4610                "tag1: %d tag2: %d ]",
4611                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4612                sub->vtr_tag1, sub->vtr_tag2);
4613       }
4614   }
4615
4616   return 0;
4617 }
4618
4619 static int
4620 name_sort_cmp (void *a1, void *a2)
4621 {
4622   name_sort_t *n1 = a1;
4623   name_sort_t *n2 = a2;
4624
4625   return strcmp ((char *) n1->name, (char *) n2->name);
4626 }
4627
4628 static int
4629 dump_interface_table (vat_main_t * vam)
4630 {
4631   hash_pair_t *p;
4632   name_sort_t *nses = 0, *ns;
4633
4634   if (vam->json_output)
4635     {
4636       clib_warning
4637         ("JSON output supported only for VPE API calls and dump_stats_table");
4638       return -99;
4639     }
4640
4641   /* *INDENT-OFF* */
4642   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4643   ({
4644     vec_add2 (nses, ns, 1);
4645     ns->name = (u8 *)(p->key);
4646     ns->value = (u32) p->value[0];
4647   }));
4648   /* *INDENT-ON* */
4649
4650   vec_sort_with_function (nses, name_sort_cmp);
4651
4652   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4653   vec_foreach (ns, nses)
4654   {
4655     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4656   }
4657   vec_free (nses);
4658   return 0;
4659 }
4660
4661 static int
4662 dump_ip_table (vat_main_t * vam, int is_ipv6)
4663 {
4664   const ip_details_t *det = NULL;
4665   const ip_address_details_t *address = NULL;
4666   u32 i = ~0;
4667
4668   print (vam->ofp, "%-12s", "sw_if_index");
4669
4670   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4671   {
4672     i++;
4673     if (!det->present)
4674       {
4675         continue;
4676       }
4677     print (vam->ofp, "%-12d", i);
4678     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
4679     if (!det->addr)
4680       {
4681         continue;
4682       }
4683     vec_foreach (address, det->addr)
4684     {
4685       print (vam->ofp,
4686              "            %-30U%-13d",
4687              is_ipv6 ? format_ip6_address : format_ip4_address,
4688              address->ip, address->prefix_length);
4689     }
4690   }
4691
4692   return 0;
4693 }
4694
4695 static int
4696 dump_ipv4_table (vat_main_t * vam)
4697 {
4698   if (vam->json_output)
4699     {
4700       clib_warning
4701         ("JSON output supported only for VPE API calls and dump_stats_table");
4702       return -99;
4703     }
4704
4705   return dump_ip_table (vam, 0);
4706 }
4707
4708 static int
4709 dump_ipv6_table (vat_main_t * vam)
4710 {
4711   if (vam->json_output)
4712     {
4713       clib_warning
4714         ("JSON output supported only for VPE API calls and dump_stats_table");
4715       return -99;
4716     }
4717
4718   return dump_ip_table (vam, 1);
4719 }
4720
4721 static char *
4722 counter_type_to_str (u8 counter_type, u8 is_combined)
4723 {
4724   if (!is_combined)
4725     {
4726       switch (counter_type)
4727         {
4728         case VNET_INTERFACE_COUNTER_DROP:
4729           return "drop";
4730         case VNET_INTERFACE_COUNTER_PUNT:
4731           return "punt";
4732         case VNET_INTERFACE_COUNTER_IP4:
4733           return "ip4";
4734         case VNET_INTERFACE_COUNTER_IP6:
4735           return "ip6";
4736         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4737           return "rx-no-buf";
4738         case VNET_INTERFACE_COUNTER_RX_MISS:
4739           return "rx-miss";
4740         case VNET_INTERFACE_COUNTER_RX_ERROR:
4741           return "rx-error";
4742         case VNET_INTERFACE_COUNTER_TX_ERROR:
4743           return "tx-error";
4744         default:
4745           return "INVALID-COUNTER-TYPE";
4746         }
4747     }
4748   else
4749     {
4750       switch (counter_type)
4751         {
4752         case VNET_INTERFACE_COUNTER_RX:
4753           return "rx";
4754         case VNET_INTERFACE_COUNTER_TX:
4755           return "tx";
4756         default:
4757           return "INVALID-COUNTER-TYPE";
4758         }
4759     }
4760 }
4761
4762 static int
4763 dump_stats_table (vat_main_t * vam)
4764 {
4765   vat_json_node_t node;
4766   vat_json_node_t *msg_array;
4767   vat_json_node_t *msg;
4768   vat_json_node_t *counter_array;
4769   vat_json_node_t *counter;
4770   interface_counter_t c;
4771   u64 packets;
4772   ip4_fib_counter_t *c4;
4773   ip6_fib_counter_t *c6;
4774   ip4_nbr_counter_t *n4;
4775   ip6_nbr_counter_t *n6;
4776   int i, j;
4777
4778   if (!vam->json_output)
4779     {
4780       clib_warning ("dump_stats_table supported only in JSON format");
4781       return -99;
4782     }
4783
4784   vat_json_init_object (&node);
4785
4786   /* interface counters */
4787   msg_array = vat_json_object_add (&node, "interface_counters");
4788   vat_json_init_array (msg_array);
4789   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4790     {
4791       msg = vat_json_array_add (msg_array);
4792       vat_json_init_object (msg);
4793       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4794                                        (u8 *) counter_type_to_str (i, 0));
4795       vat_json_object_add_int (msg, "is_combined", 0);
4796       counter_array = vat_json_object_add (msg, "data");
4797       vat_json_init_array (counter_array);
4798       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4799         {
4800           packets = vam->simple_interface_counters[i][j];
4801           vat_json_array_add_uint (counter_array, packets);
4802         }
4803     }
4804   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4805     {
4806       msg = vat_json_array_add (msg_array);
4807       vat_json_init_object (msg);
4808       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4809                                        (u8 *) counter_type_to_str (i, 1));
4810       vat_json_object_add_int (msg, "is_combined", 1);
4811       counter_array = vat_json_object_add (msg, "data");
4812       vat_json_init_array (counter_array);
4813       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4814         {
4815           c = vam->combined_interface_counters[i][j];
4816           counter = vat_json_array_add (counter_array);
4817           vat_json_init_object (counter);
4818           vat_json_object_add_uint (counter, "packets", c.packets);
4819           vat_json_object_add_uint (counter, "bytes", c.bytes);
4820         }
4821     }
4822
4823   /* ip4 fib counters */
4824   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4825   vat_json_init_array (msg_array);
4826   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4827     {
4828       msg = vat_json_array_add (msg_array);
4829       vat_json_init_object (msg);
4830       vat_json_object_add_uint (msg, "vrf_id",
4831                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4832       counter_array = vat_json_object_add (msg, "c");
4833       vat_json_init_array (counter_array);
4834       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4835         {
4836           counter = vat_json_array_add (counter_array);
4837           vat_json_init_object (counter);
4838           c4 = &vam->ip4_fib_counters[i][j];
4839           vat_json_object_add_ip4 (counter, "address", c4->address);
4840           vat_json_object_add_uint (counter, "address_length",
4841                                     c4->address_length);
4842           vat_json_object_add_uint (counter, "packets", c4->packets);
4843           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4844         }
4845     }
4846
4847   /* ip6 fib counters */
4848   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4849   vat_json_init_array (msg_array);
4850   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4851     {
4852       msg = vat_json_array_add (msg_array);
4853       vat_json_init_object (msg);
4854       vat_json_object_add_uint (msg, "vrf_id",
4855                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4856       counter_array = vat_json_object_add (msg, "c");
4857       vat_json_init_array (counter_array);
4858       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4859         {
4860           counter = vat_json_array_add (counter_array);
4861           vat_json_init_object (counter);
4862           c6 = &vam->ip6_fib_counters[i][j];
4863           vat_json_object_add_ip6 (counter, "address", c6->address);
4864           vat_json_object_add_uint (counter, "address_length",
4865                                     c6->address_length);
4866           vat_json_object_add_uint (counter, "packets", c6->packets);
4867           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4868         }
4869     }
4870
4871   /* ip4 nbr counters */
4872   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
4873   vat_json_init_array (msg_array);
4874   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
4875     {
4876       msg = vat_json_array_add (msg_array);
4877       vat_json_init_object (msg);
4878       vat_json_object_add_uint (msg, "sw_if_index", i);
4879       counter_array = vat_json_object_add (msg, "c");
4880       vat_json_init_array (counter_array);
4881       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
4882         {
4883           counter = vat_json_array_add (counter_array);
4884           vat_json_init_object (counter);
4885           n4 = &vam->ip4_nbr_counters[i][j];
4886           vat_json_object_add_ip4 (counter, "address", n4->address);
4887           vat_json_object_add_uint (counter, "link-type", n4->linkt);
4888           vat_json_object_add_uint (counter, "packets", n4->packets);
4889           vat_json_object_add_uint (counter, "bytes", n4->bytes);
4890         }
4891     }
4892
4893   /* ip6 nbr counters */
4894   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
4895   vat_json_init_array (msg_array);
4896   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
4897     {
4898       msg = vat_json_array_add (msg_array);
4899       vat_json_init_object (msg);
4900       vat_json_object_add_uint (msg, "sw_if_index", i);
4901       counter_array = vat_json_object_add (msg, "c");
4902       vat_json_init_array (counter_array);
4903       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
4904         {
4905           counter = vat_json_array_add (counter_array);
4906           vat_json_init_object (counter);
4907           n6 = &vam->ip6_nbr_counters[i][j];
4908           vat_json_object_add_ip6 (counter, "address", n6->address);
4909           vat_json_object_add_uint (counter, "packets", n6->packets);
4910           vat_json_object_add_uint (counter, "bytes", n6->bytes);
4911         }
4912     }
4913
4914   vat_json_print (vam->ofp, &node);
4915   vat_json_free (&node);
4916
4917   return 0;
4918 }
4919
4920 int
4921 exec (vat_main_t * vam)
4922 {
4923   api_main_t *am = &api_main;
4924   vl_api_cli_request_t *mp;
4925   f64 timeout;
4926   void *oldheap;
4927   u8 *cmd = 0;
4928   unformat_input_t *i = vam->input;
4929
4930   if (vec_len (i->buffer) == 0)
4931     return -1;
4932
4933   if (vam->exec_mode == 0 && unformat (i, "mode"))
4934     {
4935       vam->exec_mode = 1;
4936       return 0;
4937     }
4938   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4939     {
4940       vam->exec_mode = 0;
4941       return 0;
4942     }
4943
4944
4945   M (CLI_REQUEST, mp);
4946
4947   /*
4948    * Copy cmd into shared memory.
4949    * In order for the CLI command to work, it
4950    * must be a vector ending in \n, not a C-string ending
4951    * in \n\0.
4952    */
4953   pthread_mutex_lock (&am->vlib_rp->mutex);
4954   oldheap = svm_push_data_heap (am->vlib_rp);
4955
4956   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4957   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4958
4959   svm_pop_heap (oldheap);
4960   pthread_mutex_unlock (&am->vlib_rp->mutex);
4961
4962   mp->cmd_in_shmem = pointer_to_uword (cmd);
4963   S (mp);
4964   timeout = vat_time_now (vam) + 10.0;
4965
4966   while (vat_time_now (vam) < timeout)
4967     {
4968       if (vam->result_ready == 1)
4969         {
4970           u8 *free_me;
4971           if (vam->shmem_result != NULL)
4972             print (vam->ofp, "%s", vam->shmem_result);
4973           pthread_mutex_lock (&am->vlib_rp->mutex);
4974           oldheap = svm_push_data_heap (am->vlib_rp);
4975
4976           free_me = (u8 *) vam->shmem_result;
4977           vec_free (free_me);
4978
4979           svm_pop_heap (oldheap);
4980           pthread_mutex_unlock (&am->vlib_rp->mutex);
4981           return 0;
4982         }
4983     }
4984   return -99;
4985 }
4986
4987 /*
4988  * Future replacement of exec() that passes CLI buffers directly in
4989  * the API messages instead of an additional shared memory area.
4990  */
4991 static int
4992 exec_inband (vat_main_t * vam)
4993 {
4994   vl_api_cli_inband_t *mp;
4995   unformat_input_t *i = vam->input;
4996   int ret;
4997
4998   if (vec_len (i->buffer) == 0)
4999     return -1;
5000
5001   if (vam->exec_mode == 0 && unformat (i, "mode"))
5002     {
5003       vam->exec_mode = 1;
5004       return 0;
5005     }
5006   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5007     {
5008       vam->exec_mode = 0;
5009       return 0;
5010     }
5011
5012   /*
5013    * In order for the CLI command to work, it
5014    * must be a vector ending in \n, not a C-string ending
5015    * in \n\0.
5016    */
5017   u32 len = vec_len (vam->input->buffer);
5018   M2 (CLI_INBAND, mp, len);
5019   clib_memcpy (mp->cmd, vam->input->buffer, len);
5020   mp->length = htonl (len);
5021
5022   S (mp);
5023   W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
5024   return ret;
5025 }
5026
5027 static int
5028 api_create_loopback (vat_main_t * vam)
5029 {
5030   unformat_input_t *i = vam->input;
5031   vl_api_create_loopback_t *mp;
5032   vl_api_create_loopback_instance_t *mp_lbi;
5033   u8 mac_address[6];
5034   u8 mac_set = 0;
5035   u8 is_specified = 0;
5036   u32 user_instance = 0;
5037   int ret;
5038
5039   memset (mac_address, 0, sizeof (mac_address));
5040
5041   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5042     {
5043       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5044         mac_set = 1;
5045       if (unformat (i, "instance %d", &user_instance))
5046         is_specified = 1;
5047       else
5048         break;
5049     }
5050
5051   if (is_specified)
5052     {
5053       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5054       mp_lbi->is_specified = is_specified;
5055       if (is_specified)
5056         mp_lbi->user_instance = htonl (user_instance);
5057       if (mac_set)
5058         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5059       S (mp_lbi);
5060     }
5061   else
5062     {
5063       /* Construct the API message */
5064       M (CREATE_LOOPBACK, mp);
5065       if (mac_set)
5066         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5067       S (mp);
5068     }
5069
5070   W (ret);
5071   return ret;
5072 }
5073
5074 static int
5075 api_delete_loopback (vat_main_t * vam)
5076 {
5077   unformat_input_t *i = vam->input;
5078   vl_api_delete_loopback_t *mp;
5079   u32 sw_if_index = ~0;
5080   int ret;
5081
5082   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5083     {
5084       if (unformat (i, "sw_if_index %d", &sw_if_index))
5085         ;
5086       else
5087         break;
5088     }
5089
5090   if (sw_if_index == ~0)
5091     {
5092       errmsg ("missing sw_if_index");
5093       return -99;
5094     }
5095
5096   /* Construct the API message */
5097   M (DELETE_LOOPBACK, mp);
5098   mp->sw_if_index = ntohl (sw_if_index);
5099
5100   S (mp);
5101   W (ret);
5102   return ret;
5103 }
5104
5105 static int
5106 api_want_stats (vat_main_t * vam)
5107 {
5108   unformat_input_t *i = vam->input;
5109   vl_api_want_stats_t *mp;
5110   int enable = -1;
5111   int ret;
5112
5113   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5114     {
5115       if (unformat (i, "enable"))
5116         enable = 1;
5117       else if (unformat (i, "disable"))
5118         enable = 0;
5119       else
5120         break;
5121     }
5122
5123   if (enable == -1)
5124     {
5125       errmsg ("missing enable|disable");
5126       return -99;
5127     }
5128
5129   M (WANT_STATS, mp);
5130   mp->enable_disable = enable;
5131
5132   S (mp);
5133   W (ret);
5134   return ret;
5135 }
5136
5137 static int
5138 api_want_interface_events (vat_main_t * vam)
5139 {
5140   unformat_input_t *i = vam->input;
5141   vl_api_want_interface_events_t *mp;
5142   int enable = -1;
5143   int ret;
5144
5145   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5146     {
5147       if (unformat (i, "enable"))
5148         enable = 1;
5149       else if (unformat (i, "disable"))
5150         enable = 0;
5151       else
5152         break;
5153     }
5154
5155   if (enable == -1)
5156     {
5157       errmsg ("missing enable|disable");
5158       return -99;
5159     }
5160
5161   M (WANT_INTERFACE_EVENTS, mp);
5162   mp->enable_disable = enable;
5163
5164   vam->interface_event_display = enable;
5165
5166   S (mp);
5167   W (ret);
5168   return ret;
5169 }
5170
5171
5172 /* Note: non-static, called once to set up the initial intfc table */
5173 int
5174 api_sw_interface_dump (vat_main_t * vam)
5175 {
5176   vl_api_sw_interface_dump_t *mp;
5177   vl_api_control_ping_t *mp_ping;
5178   hash_pair_t *p;
5179   name_sort_t *nses = 0, *ns;
5180   sw_interface_subif_t *sub = NULL;
5181   int ret;
5182
5183   /* Toss the old name table */
5184   /* *INDENT-OFF* */
5185   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5186   ({
5187     vec_add2 (nses, ns, 1);
5188     ns->name = (u8 *)(p->key);
5189     ns->value = (u32) p->value[0];
5190   }));
5191   /* *INDENT-ON* */
5192
5193   hash_free (vam->sw_if_index_by_interface_name);
5194
5195   vec_foreach (ns, nses) vec_free (ns->name);
5196
5197   vec_free (nses);
5198
5199   vec_foreach (sub, vam->sw_if_subif_table)
5200   {
5201     vec_free (sub->interface_name);
5202   }
5203   vec_free (vam->sw_if_subif_table);
5204
5205   /* recreate the interface name hash table */
5206   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5207
5208   /* Get list of ethernets */
5209   M (SW_INTERFACE_DUMP, mp);
5210   mp->name_filter_valid = 1;
5211   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
5212   S (mp);
5213
5214   /* and local / loopback interfaces */
5215   M (SW_INTERFACE_DUMP, mp);
5216   mp->name_filter_valid = 1;
5217   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
5218   S (mp);
5219
5220   /* and packet-generator interfaces */
5221   M (SW_INTERFACE_DUMP, mp);
5222   mp->name_filter_valid = 1;
5223   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
5224   S (mp);
5225
5226   /* and vxlan-gpe tunnel interfaces */
5227   M (SW_INTERFACE_DUMP, mp);
5228   mp->name_filter_valid = 1;
5229   strncpy ((char *) mp->name_filter, "vxlan_gpe",
5230            sizeof (mp->name_filter) - 1);
5231   S (mp);
5232
5233   /* and vxlan tunnel interfaces */
5234   M (SW_INTERFACE_DUMP, mp);
5235   mp->name_filter_valid = 1;
5236   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
5237   S (mp);
5238
5239   /* and host (af_packet) interfaces */
5240   M (SW_INTERFACE_DUMP, mp);
5241   mp->name_filter_valid = 1;
5242   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
5243   S (mp);
5244
5245   /* and l2tpv3 tunnel interfaces */
5246   M (SW_INTERFACE_DUMP, mp);
5247   mp->name_filter_valid = 1;
5248   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
5249            sizeof (mp->name_filter) - 1);
5250   S (mp);
5251
5252   /* and GRE tunnel interfaces */
5253   M (SW_INTERFACE_DUMP, mp);
5254   mp->name_filter_valid = 1;
5255   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
5256   S (mp);
5257
5258   /* and LISP-GPE interfaces */
5259   M (SW_INTERFACE_DUMP, mp);
5260   mp->name_filter_valid = 1;
5261   strncpy ((char *) mp->name_filter, "lisp_gpe",
5262            sizeof (mp->name_filter) - 1);
5263   S (mp);
5264
5265   /* and IPSEC tunnel interfaces */
5266   M (SW_INTERFACE_DUMP, mp);
5267   mp->name_filter_valid = 1;
5268   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
5269   S (mp);
5270
5271   /* Use a control ping for synchronization */
5272   M (CONTROL_PING, mp_ping);
5273   S (mp_ping);
5274
5275   W (ret);
5276   return ret;
5277 }
5278
5279 static int
5280 api_sw_interface_set_flags (vat_main_t * vam)
5281 {
5282   unformat_input_t *i = vam->input;
5283   vl_api_sw_interface_set_flags_t *mp;
5284   u32 sw_if_index;
5285   u8 sw_if_index_set = 0;
5286   u8 admin_up = 0, link_up = 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, "admin-up"))
5293         admin_up = 1;
5294       else if (unformat (i, "admin-down"))
5295         admin_up = 0;
5296       else if (unformat (i, "link-up"))
5297         link_up = 1;
5298       else if (unformat (i, "link-down"))
5299         link_up = 0;
5300       else
5301         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5302         sw_if_index_set = 1;
5303       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5304         sw_if_index_set = 1;
5305       else
5306         break;
5307     }
5308
5309   if (sw_if_index_set == 0)
5310     {
5311       errmsg ("missing interface name or sw_if_index");
5312       return -99;
5313     }
5314
5315   /* Construct the API message */
5316   M (SW_INTERFACE_SET_FLAGS, mp);
5317   mp->sw_if_index = ntohl (sw_if_index);
5318   mp->admin_up_down = admin_up;
5319   mp->link_up_down = link_up;
5320
5321   /* send it... */
5322   S (mp);
5323
5324   /* Wait for a reply, return the good/bad news... */
5325   W (ret);
5326   return ret;
5327 }
5328
5329 static int
5330 api_sw_interface_clear_stats (vat_main_t * vam)
5331 {
5332   unformat_input_t *i = vam->input;
5333   vl_api_sw_interface_clear_stats_t *mp;
5334   u32 sw_if_index;
5335   u8 sw_if_index_set = 0;
5336   int ret;
5337
5338   /* Parse args required to build the message */
5339   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5340     {
5341       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5342         sw_if_index_set = 1;
5343       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5344         sw_if_index_set = 1;
5345       else
5346         break;
5347     }
5348
5349   /* Construct the API message */
5350   M (SW_INTERFACE_CLEAR_STATS, mp);
5351
5352   if (sw_if_index_set == 1)
5353     mp->sw_if_index = ntohl (sw_if_index);
5354   else
5355     mp->sw_if_index = ~0;
5356
5357   /* send it... */
5358   S (mp);
5359
5360   /* Wait for a reply, return the good/bad news... */
5361   W (ret);
5362   return ret;
5363 }
5364
5365 static int
5366 api_sw_interface_add_del_address (vat_main_t * vam)
5367 {
5368   unformat_input_t *i = vam->input;
5369   vl_api_sw_interface_add_del_address_t *mp;
5370   u32 sw_if_index;
5371   u8 sw_if_index_set = 0;
5372   u8 is_add = 1, del_all = 0;
5373   u32 address_length = 0;
5374   u8 v4_address_set = 0;
5375   u8 v6_address_set = 0;
5376   ip4_address_t v4address;
5377   ip6_address_t v6address;
5378   int ret;
5379
5380   /* Parse args required to build the message */
5381   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5382     {
5383       if (unformat (i, "del-all"))
5384         del_all = 1;
5385       else if (unformat (i, "del"))
5386         is_add = 0;
5387       else
5388         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5389         sw_if_index_set = 1;
5390       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5391         sw_if_index_set = 1;
5392       else if (unformat (i, "%U/%d",
5393                          unformat_ip4_address, &v4address, &address_length))
5394         v4_address_set = 1;
5395       else if (unformat (i, "%U/%d",
5396                          unformat_ip6_address, &v6address, &address_length))
5397         v6_address_set = 1;
5398       else
5399         break;
5400     }
5401
5402   if (sw_if_index_set == 0)
5403     {
5404       errmsg ("missing interface name or sw_if_index");
5405       return -99;
5406     }
5407   if (v4_address_set && v6_address_set)
5408     {
5409       errmsg ("both v4 and v6 addresses set");
5410       return -99;
5411     }
5412   if (!v4_address_set && !v6_address_set && !del_all)
5413     {
5414       errmsg ("no addresses set");
5415       return -99;
5416     }
5417
5418   /* Construct the API message */
5419   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
5420
5421   mp->sw_if_index = ntohl (sw_if_index);
5422   mp->is_add = is_add;
5423   mp->del_all = del_all;
5424   if (v6_address_set)
5425     {
5426       mp->is_ipv6 = 1;
5427       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5428     }
5429   else
5430     {
5431       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5432     }
5433   mp->address_length = address_length;
5434
5435   /* send it... */
5436   S (mp);
5437
5438   /* Wait for a reply, return good/bad news  */
5439   W (ret);
5440   return ret;
5441 }
5442
5443 static int
5444 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5445 {
5446   unformat_input_t *i = vam->input;
5447   vl_api_sw_interface_set_mpls_enable_t *mp;
5448   u32 sw_if_index;
5449   u8 sw_if_index_set = 0;
5450   u8 enable = 1;
5451   int ret;
5452
5453   /* Parse args required to build the message */
5454   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5455     {
5456       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5457         sw_if_index_set = 1;
5458       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5459         sw_if_index_set = 1;
5460       else if (unformat (i, "disable"))
5461         enable = 0;
5462       else if (unformat (i, "dis"))
5463         enable = 0;
5464       else
5465         break;
5466     }
5467
5468   if (sw_if_index_set == 0)
5469     {
5470       errmsg ("missing interface name or sw_if_index");
5471       return -99;
5472     }
5473
5474   /* Construct the API message */
5475   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
5476
5477   mp->sw_if_index = ntohl (sw_if_index);
5478   mp->enable = enable;
5479
5480   /* send it... */
5481   S (mp);
5482
5483   /* Wait for a reply... */
5484   W (ret);
5485   return ret;
5486 }
5487
5488 static int
5489 api_sw_interface_set_table (vat_main_t * vam)
5490 {
5491   unformat_input_t *i = vam->input;
5492   vl_api_sw_interface_set_table_t *mp;
5493   u32 sw_if_index, vrf_id = 0;
5494   u8 sw_if_index_set = 0;
5495   u8 is_ipv6 = 0;
5496   int ret;
5497
5498   /* Parse args required to build the message */
5499   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5500     {
5501       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5502         sw_if_index_set = 1;
5503       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5504         sw_if_index_set = 1;
5505       else if (unformat (i, "vrf %d", &vrf_id))
5506         ;
5507       else if (unformat (i, "ipv6"))
5508         is_ipv6 = 1;
5509       else
5510         break;
5511     }
5512
5513   if (sw_if_index_set == 0)
5514     {
5515       errmsg ("missing interface name or sw_if_index");
5516       return -99;
5517     }
5518
5519   /* Construct the API message */
5520   M (SW_INTERFACE_SET_TABLE, mp);
5521
5522   mp->sw_if_index = ntohl (sw_if_index);
5523   mp->is_ipv6 = is_ipv6;
5524   mp->vrf_id = ntohl (vrf_id);
5525
5526   /* send it... */
5527   S (mp);
5528
5529   /* Wait for a reply... */
5530   W (ret);
5531   return ret;
5532 }
5533
5534 static void vl_api_sw_interface_get_table_reply_t_handler
5535   (vl_api_sw_interface_get_table_reply_t * mp)
5536 {
5537   vat_main_t *vam = &vat_main;
5538
5539   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5540
5541   vam->retval = ntohl (mp->retval);
5542   vam->result_ready = 1;
5543
5544 }
5545
5546 static void vl_api_sw_interface_get_table_reply_t_handler_json
5547   (vl_api_sw_interface_get_table_reply_t * mp)
5548 {
5549   vat_main_t *vam = &vat_main;
5550   vat_json_node_t node;
5551
5552   vat_json_init_object (&node);
5553   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5554   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5555
5556   vat_json_print (vam->ofp, &node);
5557   vat_json_free (&node);
5558
5559   vam->retval = ntohl (mp->retval);
5560   vam->result_ready = 1;
5561 }
5562
5563 static int
5564 api_sw_interface_get_table (vat_main_t * vam)
5565 {
5566   unformat_input_t *i = vam->input;
5567   vl_api_sw_interface_get_table_t *mp;
5568   u32 sw_if_index;
5569   u8 sw_if_index_set = 0;
5570   u8 is_ipv6 = 0;
5571   int ret;
5572
5573   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5574     {
5575       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5576         sw_if_index_set = 1;
5577       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5578         sw_if_index_set = 1;
5579       else if (unformat (i, "ipv6"))
5580         is_ipv6 = 1;
5581       else
5582         break;
5583     }
5584
5585   if (sw_if_index_set == 0)
5586     {
5587       errmsg ("missing interface name or sw_if_index");
5588       return -99;
5589     }
5590
5591   M (SW_INTERFACE_GET_TABLE, mp);
5592   mp->sw_if_index = htonl (sw_if_index);
5593   mp->is_ipv6 = is_ipv6;
5594
5595   S (mp);
5596   W (ret);
5597   return ret;
5598 }
5599
5600 static int
5601 api_sw_interface_set_vpath (vat_main_t * vam)
5602 {
5603   unformat_input_t *i = vam->input;
5604   vl_api_sw_interface_set_vpath_t *mp;
5605   u32 sw_if_index = 0;
5606   u8 sw_if_index_set = 0;
5607   u8 is_enable = 0;
5608   int ret;
5609
5610   /* Parse args required to build the message */
5611   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5612     {
5613       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5614         sw_if_index_set = 1;
5615       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5616         sw_if_index_set = 1;
5617       else if (unformat (i, "enable"))
5618         is_enable = 1;
5619       else if (unformat (i, "disable"))
5620         is_enable = 0;
5621       else
5622         break;
5623     }
5624
5625   if (sw_if_index_set == 0)
5626     {
5627       errmsg ("missing interface name or sw_if_index");
5628       return -99;
5629     }
5630
5631   /* Construct the API message */
5632   M (SW_INTERFACE_SET_VPATH, mp);
5633
5634   mp->sw_if_index = ntohl (sw_if_index);
5635   mp->enable = is_enable;
5636
5637   /* send it... */
5638   S (mp);
5639
5640   /* Wait for a reply... */
5641   W (ret);
5642   return ret;
5643 }
5644
5645 static int
5646 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5647 {
5648   unformat_input_t *i = vam->input;
5649   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5650   u32 sw_if_index = 0;
5651   u8 sw_if_index_set = 0;
5652   u8 is_enable = 1;
5653   u8 is_ipv6 = 0;
5654   int ret;
5655
5656   /* Parse args required to build the message */
5657   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5658     {
5659       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5660         sw_if_index_set = 1;
5661       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5662         sw_if_index_set = 1;
5663       else if (unformat (i, "enable"))
5664         is_enable = 1;
5665       else if (unformat (i, "disable"))
5666         is_enable = 0;
5667       else if (unformat (i, "ip4"))
5668         is_ipv6 = 0;
5669       else if (unformat (i, "ip6"))
5670         is_ipv6 = 1;
5671       else
5672         break;
5673     }
5674
5675   if (sw_if_index_set == 0)
5676     {
5677       errmsg ("missing interface name or sw_if_index");
5678       return -99;
5679     }
5680
5681   /* Construct the API message */
5682   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
5683
5684   mp->sw_if_index = ntohl (sw_if_index);
5685   mp->enable = is_enable;
5686   mp->is_ipv6 = is_ipv6;
5687
5688   /* send it... */
5689   S (mp);
5690
5691   /* Wait for a reply... */
5692   W (ret);
5693   return ret;
5694 }
5695
5696 static int
5697 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5698 {
5699   unformat_input_t *i = vam->input;
5700   vl_api_sw_interface_set_l2_xconnect_t *mp;
5701   u32 rx_sw_if_index;
5702   u8 rx_sw_if_index_set = 0;
5703   u32 tx_sw_if_index;
5704   u8 tx_sw_if_index_set = 0;
5705   u8 enable = 1;
5706   int ret;
5707
5708   /* Parse args required to build the message */
5709   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5710     {
5711       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5712         rx_sw_if_index_set = 1;
5713       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5714         tx_sw_if_index_set = 1;
5715       else if (unformat (i, "rx"))
5716         {
5717           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5718             {
5719               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5720                             &rx_sw_if_index))
5721                 rx_sw_if_index_set = 1;
5722             }
5723           else
5724             break;
5725         }
5726       else if (unformat (i, "tx"))
5727         {
5728           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5729             {
5730               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5731                             &tx_sw_if_index))
5732                 tx_sw_if_index_set = 1;
5733             }
5734           else
5735             break;
5736         }
5737       else if (unformat (i, "enable"))
5738         enable = 1;
5739       else if (unformat (i, "disable"))
5740         enable = 0;
5741       else
5742         break;
5743     }
5744
5745   if (rx_sw_if_index_set == 0)
5746     {
5747       errmsg ("missing rx interface name or rx_sw_if_index");
5748       return -99;
5749     }
5750
5751   if (enable && (tx_sw_if_index_set == 0))
5752     {
5753       errmsg ("missing tx interface name or tx_sw_if_index");
5754       return -99;
5755     }
5756
5757   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
5758
5759   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5760   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5761   mp->enable = enable;
5762
5763   S (mp);
5764   W (ret);
5765   return ret;
5766 }
5767
5768 static int
5769 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5770 {
5771   unformat_input_t *i = vam->input;
5772   vl_api_sw_interface_set_l2_bridge_t *mp;
5773   u32 rx_sw_if_index;
5774   u8 rx_sw_if_index_set = 0;
5775   u32 bd_id;
5776   u8 bd_id_set = 0;
5777   u8 bvi = 0;
5778   u32 shg = 0;
5779   u8 enable = 1;
5780   int ret;
5781
5782   /* Parse args required to build the message */
5783   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5784     {
5785       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5786         rx_sw_if_index_set = 1;
5787       else if (unformat (i, "bd_id %d", &bd_id))
5788         bd_id_set = 1;
5789       else
5790         if (unformat
5791             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5792         rx_sw_if_index_set = 1;
5793       else if (unformat (i, "shg %d", &shg))
5794         ;
5795       else if (unformat (i, "bvi"))
5796         bvi = 1;
5797       else if (unformat (i, "enable"))
5798         enable = 1;
5799       else if (unformat (i, "disable"))
5800         enable = 0;
5801       else
5802         break;
5803     }
5804
5805   if (rx_sw_if_index_set == 0)
5806     {
5807       errmsg ("missing rx interface name or sw_if_index");
5808       return -99;
5809     }
5810
5811   if (enable && (bd_id_set == 0))
5812     {
5813       errmsg ("missing bridge domain");
5814       return -99;
5815     }
5816
5817   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
5818
5819   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5820   mp->bd_id = ntohl (bd_id);
5821   mp->shg = (u8) shg;
5822   mp->bvi = bvi;
5823   mp->enable = enable;
5824
5825   S (mp);
5826   W (ret);
5827   return ret;
5828 }
5829
5830 static int
5831 api_bridge_domain_dump (vat_main_t * vam)
5832 {
5833   unformat_input_t *i = vam->input;
5834   vl_api_bridge_domain_dump_t *mp;
5835   vl_api_control_ping_t *mp_ping;
5836   u32 bd_id = ~0;
5837   int ret;
5838
5839   /* Parse args required to build the message */
5840   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5841     {
5842       if (unformat (i, "bd_id %d", &bd_id))
5843         ;
5844       else
5845         break;
5846     }
5847
5848   M (BRIDGE_DOMAIN_DUMP, mp);
5849   mp->bd_id = ntohl (bd_id);
5850   S (mp);
5851
5852   /* Use a control ping for synchronization */
5853   M (CONTROL_PING, mp_ping);
5854   S (mp_ping);
5855
5856   W (ret);
5857   return ret;
5858 }
5859
5860 static int
5861 api_bridge_domain_add_del (vat_main_t * vam)
5862 {
5863   unformat_input_t *i = vam->input;
5864   vl_api_bridge_domain_add_del_t *mp;
5865   u32 bd_id = ~0;
5866   u8 is_add = 1;
5867   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5868   u32 mac_age = 0;
5869   int ret;
5870
5871   /* Parse args required to build the message */
5872   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5873     {
5874       if (unformat (i, "bd_id %d", &bd_id))
5875         ;
5876       else if (unformat (i, "flood %d", &flood))
5877         ;
5878       else if (unformat (i, "uu-flood %d", &uu_flood))
5879         ;
5880       else if (unformat (i, "forward %d", &forward))
5881         ;
5882       else if (unformat (i, "learn %d", &learn))
5883         ;
5884       else if (unformat (i, "arp-term %d", &arp_term))
5885         ;
5886       else if (unformat (i, "mac-age %d", &mac_age))
5887         ;
5888       else if (unformat (i, "del"))
5889         {
5890           is_add = 0;
5891           flood = uu_flood = forward = learn = 0;
5892         }
5893       else
5894         break;
5895     }
5896
5897   if (bd_id == ~0)
5898     {
5899       errmsg ("missing bridge domain");
5900       return -99;
5901     }
5902
5903   if (mac_age > 255)
5904     {
5905       errmsg ("mac age must be less than 256 ");
5906       return -99;
5907     }
5908
5909   M (BRIDGE_DOMAIN_ADD_DEL, mp);
5910
5911   mp->bd_id = ntohl (bd_id);
5912   mp->flood = flood;
5913   mp->uu_flood = uu_flood;
5914   mp->forward = forward;
5915   mp->learn = learn;
5916   mp->arp_term = arp_term;
5917   mp->is_add = is_add;
5918   mp->mac_age = (u8) mac_age;
5919
5920   S (mp);
5921   W (ret);
5922   return ret;
5923 }
5924
5925 static int
5926 api_l2fib_flush_bd (vat_main_t * vam)
5927 {
5928   unformat_input_t *i = vam->input;
5929   vl_api_l2fib_flush_bd_t *mp;
5930   u32 bd_id = ~0;
5931   int ret;
5932
5933   /* Parse args required to build the message */
5934   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5935     {
5936       if (unformat (i, "bd_id %d", &bd_id));
5937       else
5938         break;
5939     }
5940
5941   if (bd_id == ~0)
5942     {
5943       errmsg ("missing bridge domain");
5944       return -99;
5945     }
5946
5947   M (L2FIB_FLUSH_BD, mp);
5948
5949   mp->bd_id = htonl (bd_id);
5950
5951   S (mp);
5952   W (ret);
5953   return ret;
5954 }
5955
5956 static int
5957 api_l2fib_flush_int (vat_main_t * vam)
5958 {
5959   unformat_input_t *i = vam->input;
5960   vl_api_l2fib_flush_int_t *mp;
5961   u32 sw_if_index = ~0;
5962   int ret;
5963
5964   /* Parse args required to build the message */
5965   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5966     {
5967       if (unformat (i, "sw_if_index %d", &sw_if_index));
5968       else
5969         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
5970       else
5971         break;
5972     }
5973
5974   if (sw_if_index == ~0)
5975     {
5976       errmsg ("missing interface name or sw_if_index");
5977       return -99;
5978     }
5979
5980   M (L2FIB_FLUSH_INT, mp);
5981
5982   mp->sw_if_index = ntohl (sw_if_index);
5983
5984   S (mp);
5985   W (ret);
5986   return ret;
5987 }
5988
5989 static int
5990 api_l2fib_add_del (vat_main_t * vam)
5991 {
5992   unformat_input_t *i = vam->input;
5993   vl_api_l2fib_add_del_t *mp;
5994   f64 timeout;
5995   u64 mac = 0;
5996   u8 mac_set = 0;
5997   u32 bd_id;
5998   u8 bd_id_set = 0;
5999   u32 sw_if_index = ~0;
6000   u8 sw_if_index_set = 0;
6001   u8 is_add = 1;
6002   u8 static_mac = 0;
6003   u8 filter_mac = 0;
6004   u8 bvi_mac = 0;
6005   int count = 1;
6006   f64 before = 0;
6007   int j;
6008
6009   /* Parse args required to build the message */
6010   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6011     {
6012       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
6013         mac_set = 1;
6014       else if (unformat (i, "bd_id %d", &bd_id))
6015         bd_id_set = 1;
6016       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6017         sw_if_index_set = 1;
6018       else if (unformat (i, "sw_if"))
6019         {
6020           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6021             {
6022               if (unformat
6023                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6024                 sw_if_index_set = 1;
6025             }
6026           else
6027             break;
6028         }
6029       else if (unformat (i, "static"))
6030         static_mac = 1;
6031       else if (unformat (i, "filter"))
6032         {
6033           filter_mac = 1;
6034           static_mac = 1;
6035         }
6036       else if (unformat (i, "bvi"))
6037         {
6038           bvi_mac = 1;
6039           static_mac = 1;
6040         }
6041       else if (unformat (i, "del"))
6042         is_add = 0;
6043       else if (unformat (i, "count %d", &count))
6044         ;
6045       else
6046         break;
6047     }
6048
6049   if (mac_set == 0)
6050     {
6051       errmsg ("missing mac address");
6052       return -99;
6053     }
6054
6055   if (bd_id_set == 0)
6056     {
6057       errmsg ("missing bridge domain");
6058       return -99;
6059     }
6060
6061   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6062     {
6063       errmsg ("missing interface name or sw_if_index");
6064       return -99;
6065     }
6066
6067   if (count > 1)
6068     {
6069       /* Turn on async mode */
6070       vam->async_mode = 1;
6071       vam->async_errors = 0;
6072       before = vat_time_now (vam);
6073     }
6074
6075   for (j = 0; j < count; j++)
6076     {
6077       M (L2FIB_ADD_DEL, mp);
6078
6079       mp->mac = mac;
6080       mp->bd_id = ntohl (bd_id);
6081       mp->is_add = is_add;
6082
6083       if (is_add)
6084         {
6085           mp->sw_if_index = ntohl (sw_if_index);
6086           mp->static_mac = static_mac;
6087           mp->filter_mac = filter_mac;
6088           mp->bvi_mac = bvi_mac;
6089         }
6090       increment_mac_address (&mac);
6091       /* send it... */
6092       S (mp);
6093     }
6094
6095   if (count > 1)
6096     {
6097       vl_api_control_ping_t *mp_ping;
6098       f64 after;
6099
6100       /* Shut off async mode */
6101       vam->async_mode = 0;
6102
6103       M (CONTROL_PING, mp_ping);
6104       S (mp_ping);
6105
6106       timeout = vat_time_now (vam) + 1.0;
6107       while (vat_time_now (vam) < timeout)
6108         if (vam->result_ready == 1)
6109           goto out;
6110       vam->retval = -99;
6111
6112     out:
6113       if (vam->retval == -99)
6114         errmsg ("timeout");
6115
6116       if (vam->async_errors > 0)
6117         {
6118           errmsg ("%d asynchronous errors", vam->async_errors);
6119           vam->retval = -98;
6120         }
6121       vam->async_errors = 0;
6122       after = vat_time_now (vam);
6123
6124       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6125              count, after - before, count / (after - before));
6126     }
6127   else
6128     {
6129       int ret;
6130
6131       /* Wait for a reply... */
6132       W (ret);
6133       return ret;
6134     }
6135   /* Return the good/bad news */
6136   return (vam->retval);
6137 }
6138
6139 static int
6140 api_bridge_domain_set_mac_age (vat_main_t * vam)
6141 {
6142   unformat_input_t *i = vam->input;
6143   vl_api_bridge_domain_set_mac_age_t *mp;
6144   u32 bd_id = ~0;
6145   u32 mac_age = 0;
6146   int ret;
6147
6148   /* Parse args required to build the message */
6149   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6150     {
6151       if (unformat (i, "bd_id %d", &bd_id));
6152       else if (unformat (i, "mac-age %d", &mac_age));
6153       else
6154         break;
6155     }
6156
6157   if (bd_id == ~0)
6158     {
6159       errmsg ("missing bridge domain");
6160       return -99;
6161     }
6162
6163   if (mac_age > 255)
6164     {
6165       errmsg ("mac age must be less than 256 ");
6166       return -99;
6167     }
6168
6169   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6170
6171   mp->bd_id = htonl (bd_id);
6172   mp->mac_age = (u8) mac_age;
6173
6174   S (mp);
6175   W (ret);
6176   return ret;
6177 }
6178
6179 static int
6180 api_l2_flags (vat_main_t * vam)
6181 {
6182   unformat_input_t *i = vam->input;
6183   vl_api_l2_flags_t *mp;
6184   u32 sw_if_index;
6185   u32 feature_bitmap = 0;
6186   u8 sw_if_index_set = 0;
6187   int ret;
6188
6189   /* Parse args required to build the message */
6190   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6191     {
6192       if (unformat (i, "sw_if_index %d", &sw_if_index))
6193         sw_if_index_set = 1;
6194       else if (unformat (i, "sw_if"))
6195         {
6196           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6197             {
6198               if (unformat
6199                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6200                 sw_if_index_set = 1;
6201             }
6202           else
6203             break;
6204         }
6205       else if (unformat (i, "learn"))
6206         feature_bitmap |= L2INPUT_FEAT_LEARN;
6207       else if (unformat (i, "forward"))
6208         feature_bitmap |= L2INPUT_FEAT_FWD;
6209       else if (unformat (i, "flood"))
6210         feature_bitmap |= L2INPUT_FEAT_FLOOD;
6211       else if (unformat (i, "uu-flood"))
6212         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
6213       else
6214         break;
6215     }
6216
6217   if (sw_if_index_set == 0)
6218     {
6219       errmsg ("missing interface name or sw_if_index");
6220       return -99;
6221     }
6222
6223   M (L2_FLAGS, mp);
6224
6225   mp->sw_if_index = ntohl (sw_if_index);
6226   mp->feature_bitmap = ntohl (feature_bitmap);
6227
6228   S (mp);
6229   W (ret);
6230   return ret;
6231 }
6232
6233 static int
6234 api_bridge_flags (vat_main_t * vam)
6235 {
6236   unformat_input_t *i = vam->input;
6237   vl_api_bridge_flags_t *mp;
6238   u32 bd_id;
6239   u8 bd_id_set = 0;
6240   u8 is_set = 1;
6241   u32 flags = 0;
6242   int ret;
6243
6244   /* Parse args required to build the message */
6245   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6246     {
6247       if (unformat (i, "bd_id %d", &bd_id))
6248         bd_id_set = 1;
6249       else if (unformat (i, "learn"))
6250         flags |= L2_LEARN;
6251       else if (unformat (i, "forward"))
6252         flags |= L2_FWD;
6253       else if (unformat (i, "flood"))
6254         flags |= L2_FLOOD;
6255       else if (unformat (i, "uu-flood"))
6256         flags |= L2_UU_FLOOD;
6257       else if (unformat (i, "arp-term"))
6258         flags |= L2_ARP_TERM;
6259       else if (unformat (i, "off"))
6260         is_set = 0;
6261       else if (unformat (i, "disable"))
6262         is_set = 0;
6263       else
6264         break;
6265     }
6266
6267   if (bd_id_set == 0)
6268     {
6269       errmsg ("missing bridge domain");
6270       return -99;
6271     }
6272
6273   M (BRIDGE_FLAGS, mp);
6274
6275   mp->bd_id = ntohl (bd_id);
6276   mp->feature_bitmap = ntohl (flags);
6277   mp->is_set = is_set;
6278
6279   S (mp);
6280   W (ret);
6281   return ret;
6282 }
6283
6284 static int
6285 api_bd_ip_mac_add_del (vat_main_t * vam)
6286 {
6287   unformat_input_t *i = vam->input;
6288   vl_api_bd_ip_mac_add_del_t *mp;
6289   u32 bd_id;
6290   u8 is_ipv6 = 0;
6291   u8 is_add = 1;
6292   u8 bd_id_set = 0;
6293   u8 ip_set = 0;
6294   u8 mac_set = 0;
6295   ip4_address_t v4addr;
6296   ip6_address_t v6addr;
6297   u8 macaddr[6];
6298   int ret;
6299
6300
6301   /* Parse args required to build the message */
6302   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6303     {
6304       if (unformat (i, "bd_id %d", &bd_id))
6305         {
6306           bd_id_set++;
6307         }
6308       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
6309         {
6310           ip_set++;
6311         }
6312       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
6313         {
6314           ip_set++;
6315           is_ipv6++;
6316         }
6317       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
6318         {
6319           mac_set++;
6320         }
6321       else if (unformat (i, "del"))
6322         is_add = 0;
6323       else
6324         break;
6325     }
6326
6327   if (bd_id_set == 0)
6328     {
6329       errmsg ("missing bridge domain");
6330       return -99;
6331     }
6332   else if (ip_set == 0)
6333     {
6334       errmsg ("missing IP address");
6335       return -99;
6336     }
6337   else if (mac_set == 0)
6338     {
6339       errmsg ("missing MAC address");
6340       return -99;
6341     }
6342
6343   M (BD_IP_MAC_ADD_DEL, mp);
6344
6345   mp->bd_id = ntohl (bd_id);
6346   mp->is_ipv6 = is_ipv6;
6347   mp->is_add = is_add;
6348   if (is_ipv6)
6349     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
6350   else
6351     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
6352   clib_memcpy (mp->mac_address, macaddr, 6);
6353   S (mp);
6354   W (ret);
6355   return ret;
6356 }
6357
6358 static int
6359 api_tap_connect (vat_main_t * vam)
6360 {
6361   unformat_input_t *i = vam->input;
6362   vl_api_tap_connect_t *mp;
6363   u8 mac_address[6];
6364   u8 random_mac = 1;
6365   u8 name_set = 0;
6366   u8 *tap_name;
6367   u8 *tag = 0;
6368   ip4_address_t ip4_address;
6369   u32 ip4_mask_width;
6370   int ip4_address_set = 0;
6371   ip6_address_t ip6_address;
6372   u32 ip6_mask_width;
6373   int ip6_address_set = 0;
6374   int ret;
6375
6376   memset (mac_address, 0, sizeof (mac_address));
6377
6378   /* Parse args required to build the message */
6379   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6380     {
6381       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6382         {
6383           random_mac = 0;
6384         }
6385       else if (unformat (i, "random-mac"))
6386         random_mac = 1;
6387       else if (unformat (i, "tapname %s", &tap_name))
6388         name_set = 1;
6389       else if (unformat (i, "tag %s", &tag))
6390         ;
6391       else if (unformat (i, "address %U/%d",
6392                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
6393         ip4_address_set = 1;
6394       else if (unformat (i, "address %U/%d",
6395                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
6396         ip6_address_set = 1;
6397       else
6398         break;
6399     }
6400
6401   if (name_set == 0)
6402     {
6403       errmsg ("missing tap name");
6404       return -99;
6405     }
6406   if (vec_len (tap_name) > 63)
6407     {
6408       errmsg ("tap name too long");
6409       return -99;
6410     }
6411   vec_add1 (tap_name, 0);
6412
6413   if (vec_len (tag) > 63)
6414     {
6415       errmsg ("tag too long");
6416       return -99;
6417     }
6418
6419   /* Construct the API message */
6420   M (TAP_CONNECT, mp);
6421
6422   mp->use_random_mac = random_mac;
6423   clib_memcpy (mp->mac_address, mac_address, 6);
6424   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6425   if (tag)
6426     clib_memcpy (mp->tag, tag, vec_len (tag));
6427
6428   if (ip4_address_set)
6429     {
6430       mp->ip4_address_set = 1;
6431       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6432       mp->ip4_mask_width = ip4_mask_width;
6433     }
6434   if (ip6_address_set)
6435     {
6436       mp->ip6_address_set = 1;
6437       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6438       mp->ip6_mask_width = ip6_mask_width;
6439     }
6440
6441   vec_free (tap_name);
6442   vec_free (tag);
6443
6444   /* send it... */
6445   S (mp);
6446
6447   /* Wait for a reply... */
6448   W (ret);
6449   return ret;
6450 }
6451
6452 static int
6453 api_tap_modify (vat_main_t * vam)
6454 {
6455   unformat_input_t *i = vam->input;
6456   vl_api_tap_modify_t *mp;
6457   u8 mac_address[6];
6458   u8 random_mac = 1;
6459   u8 name_set = 0;
6460   u8 *tap_name;
6461   u32 sw_if_index = ~0;
6462   u8 sw_if_index_set = 0;
6463   int ret;
6464
6465   memset (mac_address, 0, sizeof (mac_address));
6466
6467   /* Parse args required to build the message */
6468   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6469     {
6470       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6471         sw_if_index_set = 1;
6472       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6473         sw_if_index_set = 1;
6474       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6475         {
6476           random_mac = 0;
6477         }
6478       else if (unformat (i, "random-mac"))
6479         random_mac = 1;
6480       else if (unformat (i, "tapname %s", &tap_name))
6481         name_set = 1;
6482       else
6483         break;
6484     }
6485
6486   if (sw_if_index_set == 0)
6487     {
6488       errmsg ("missing vpp interface name");
6489       return -99;
6490     }
6491   if (name_set == 0)
6492     {
6493       errmsg ("missing tap name");
6494       return -99;
6495     }
6496   if (vec_len (tap_name) > 63)
6497     {
6498       errmsg ("tap name too long");
6499     }
6500   vec_add1 (tap_name, 0);
6501
6502   /* Construct the API message */
6503   M (TAP_MODIFY, mp);
6504
6505   mp->use_random_mac = random_mac;
6506   mp->sw_if_index = ntohl (sw_if_index);
6507   clib_memcpy (mp->mac_address, mac_address, 6);
6508   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6509   vec_free (tap_name);
6510
6511   /* send it... */
6512   S (mp);
6513
6514   /* Wait for a reply... */
6515   W (ret);
6516   return ret;
6517 }
6518
6519 static int
6520 api_tap_delete (vat_main_t * vam)
6521 {
6522   unformat_input_t *i = vam->input;
6523   vl_api_tap_delete_t *mp;
6524   u32 sw_if_index = ~0;
6525   u8 sw_if_index_set = 0;
6526   int ret;
6527
6528   /* Parse args required to build the message */
6529   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6530     {
6531       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6532         sw_if_index_set = 1;
6533       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6534         sw_if_index_set = 1;
6535       else
6536         break;
6537     }
6538
6539   if (sw_if_index_set == 0)
6540     {
6541       errmsg ("missing vpp interface name");
6542       return -99;
6543     }
6544
6545   /* Construct the API message */
6546   M (TAP_DELETE, mp);
6547
6548   mp->sw_if_index = ntohl (sw_if_index);
6549
6550   /* send it... */
6551   S (mp);
6552
6553   /* Wait for a reply... */
6554   W (ret);
6555   return ret;
6556 }
6557
6558 static int
6559 api_ip_add_del_route (vat_main_t * vam)
6560 {
6561   unformat_input_t *i = vam->input;
6562   vl_api_ip_add_del_route_t *mp;
6563   u32 sw_if_index = ~0, vrf_id = 0;
6564   u8 is_ipv6 = 0;
6565   u8 is_local = 0, is_drop = 0;
6566   u8 is_unreach = 0, is_prohibit = 0;
6567   u8 create_vrf_if_needed = 0;
6568   u8 is_add = 1;
6569   u32 next_hop_weight = 1;
6570   u8 not_last = 0;
6571   u8 is_multipath = 0;
6572   u8 address_set = 0;
6573   u8 address_length_set = 0;
6574   u32 next_hop_table_id = 0;
6575   u32 resolve_attempts = 0;
6576   u32 dst_address_length = 0;
6577   u8 next_hop_set = 0;
6578   ip4_address_t v4_dst_address, v4_next_hop_address;
6579   ip6_address_t v6_dst_address, v6_next_hop_address;
6580   int count = 1;
6581   int j;
6582   f64 before = 0;
6583   u32 random_add_del = 0;
6584   u32 *random_vector = 0;
6585   uword *random_hash;
6586   u32 random_seed = 0xdeaddabe;
6587   u32 classify_table_index = ~0;
6588   u8 is_classify = 0;
6589   u8 resolve_host = 0, resolve_attached = 0;
6590   mpls_label_t *next_hop_out_label_stack = NULL;
6591   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6592   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6593
6594   /* Parse args required to build the message */
6595   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6596     {
6597       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6598         ;
6599       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6600         ;
6601       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6602         {
6603           address_set = 1;
6604           is_ipv6 = 0;
6605         }
6606       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6607         {
6608           address_set = 1;
6609           is_ipv6 = 1;
6610         }
6611       else if (unformat (i, "/%d", &dst_address_length))
6612         {
6613           address_length_set = 1;
6614         }
6615
6616       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6617                                          &v4_next_hop_address))
6618         {
6619           next_hop_set = 1;
6620         }
6621       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6622                                          &v6_next_hop_address))
6623         {
6624           next_hop_set = 1;
6625         }
6626       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6627         ;
6628       else if (unformat (i, "weight %d", &next_hop_weight))
6629         ;
6630       else if (unformat (i, "drop"))
6631         {
6632           is_drop = 1;
6633         }
6634       else if (unformat (i, "null-send-unreach"))
6635         {
6636           is_unreach = 1;
6637         }
6638       else if (unformat (i, "null-send-prohibit"))
6639         {
6640           is_prohibit = 1;
6641         }
6642       else if (unformat (i, "local"))
6643         {
6644           is_local = 1;
6645         }
6646       else if (unformat (i, "classify %d", &classify_table_index))
6647         {
6648           is_classify = 1;
6649         }
6650       else if (unformat (i, "del"))
6651         is_add = 0;
6652       else if (unformat (i, "add"))
6653         is_add = 1;
6654       else if (unformat (i, "not-last"))
6655         not_last = 1;
6656       else if (unformat (i, "resolve-via-host"))
6657         resolve_host = 1;
6658       else if (unformat (i, "resolve-via-attached"))
6659         resolve_attached = 1;
6660       else if (unformat (i, "multipath"))
6661         is_multipath = 1;
6662       else if (unformat (i, "vrf %d", &vrf_id))
6663         ;
6664       else if (unformat (i, "create-vrf"))
6665         create_vrf_if_needed = 1;
6666       else if (unformat (i, "count %d", &count))
6667         ;
6668       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6669         ;
6670       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6671         ;
6672       else if (unformat (i, "out-label %d", &next_hop_out_label))
6673         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6674       else if (unformat (i, "via-label %d", &next_hop_via_label))
6675         ;
6676       else if (unformat (i, "random"))
6677         random_add_del = 1;
6678       else if (unformat (i, "seed %d", &random_seed))
6679         ;
6680       else
6681         {
6682           clib_warning ("parse error '%U'", format_unformat_error, i);
6683           return -99;
6684         }
6685     }
6686
6687   if (!next_hop_set && !is_drop && !is_local &&
6688       !is_classify && !is_unreach && !is_prohibit &&
6689       MPLS_LABEL_INVALID == next_hop_via_label)
6690     {
6691       errmsg
6692         ("next hop / local / drop / unreach / prohibit / classify not set");
6693       return -99;
6694     }
6695
6696   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6697     {
6698       errmsg ("next hop and next-hop via label set");
6699       return -99;
6700     }
6701   if (address_set == 0)
6702     {
6703       errmsg ("missing addresses");
6704       return -99;
6705     }
6706
6707   if (address_length_set == 0)
6708     {
6709       errmsg ("missing address length");
6710       return -99;
6711     }
6712
6713   /* Generate a pile of unique, random routes */
6714   if (random_add_del)
6715     {
6716       u32 this_random_address;
6717       random_hash = hash_create (count, sizeof (uword));
6718
6719       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6720       for (j = 0; j <= count; j++)
6721         {
6722           do
6723             {
6724               this_random_address = random_u32 (&random_seed);
6725               this_random_address =
6726                 clib_host_to_net_u32 (this_random_address);
6727             }
6728           while (hash_get (random_hash, this_random_address));
6729           vec_add1 (random_vector, this_random_address);
6730           hash_set (random_hash, this_random_address, 1);
6731         }
6732       hash_free (random_hash);
6733       v4_dst_address.as_u32 = random_vector[0];
6734     }
6735
6736   if (count > 1)
6737     {
6738       /* Turn on async mode */
6739       vam->async_mode = 1;
6740       vam->async_errors = 0;
6741       before = vat_time_now (vam);
6742     }
6743
6744   for (j = 0; j < count; j++)
6745     {
6746       /* Construct the API message */
6747       M2 (IP_ADD_DEL_ROUTE, mp,
6748           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6749
6750       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6751       mp->table_id = ntohl (vrf_id);
6752       mp->create_vrf_if_needed = create_vrf_if_needed;
6753
6754       mp->is_add = is_add;
6755       mp->is_drop = is_drop;
6756       mp->is_unreach = is_unreach;
6757       mp->is_prohibit = is_prohibit;
6758       mp->is_ipv6 = is_ipv6;
6759       mp->is_local = is_local;
6760       mp->is_classify = is_classify;
6761       mp->is_multipath = is_multipath;
6762       mp->is_resolve_host = resolve_host;
6763       mp->is_resolve_attached = resolve_attached;
6764       mp->not_last = not_last;
6765       mp->next_hop_weight = next_hop_weight;
6766       mp->dst_address_length = dst_address_length;
6767       mp->next_hop_table_id = ntohl (next_hop_table_id);
6768       mp->classify_table_index = ntohl (classify_table_index);
6769       mp->next_hop_via_label = ntohl (next_hop_via_label);
6770       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6771       if (0 != mp->next_hop_n_out_labels)
6772         {
6773           memcpy (mp->next_hop_out_label_stack,
6774                   next_hop_out_label_stack,
6775                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6776           vec_free (next_hop_out_label_stack);
6777         }
6778
6779       if (is_ipv6)
6780         {
6781           clib_memcpy (mp->dst_address, &v6_dst_address,
6782                        sizeof (v6_dst_address));
6783           if (next_hop_set)
6784             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6785                          sizeof (v6_next_hop_address));
6786           increment_v6_address (&v6_dst_address);
6787         }
6788       else
6789         {
6790           clib_memcpy (mp->dst_address, &v4_dst_address,
6791                        sizeof (v4_dst_address));
6792           if (next_hop_set)
6793             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6794                          sizeof (v4_next_hop_address));
6795           if (random_add_del)
6796             v4_dst_address.as_u32 = random_vector[j + 1];
6797           else
6798             increment_v4_address (&v4_dst_address);
6799         }
6800       /* send it... */
6801       S (mp);
6802       /* If we receive SIGTERM, stop now... */
6803       if (vam->do_exit)
6804         break;
6805     }
6806
6807   /* When testing multiple add/del ops, use a control-ping to sync */
6808   if (count > 1)
6809     {
6810       vl_api_control_ping_t *mp_ping;
6811       f64 after;
6812       f64 timeout;
6813
6814       /* Shut off async mode */
6815       vam->async_mode = 0;
6816
6817       M (CONTROL_PING, mp_ping);
6818       S (mp_ping);
6819
6820       timeout = vat_time_now (vam) + 1.0;
6821       while (vat_time_now (vam) < timeout)
6822         if (vam->result_ready == 1)
6823           goto out;
6824       vam->retval = -99;
6825
6826     out:
6827       if (vam->retval == -99)
6828         errmsg ("timeout");
6829
6830       if (vam->async_errors > 0)
6831         {
6832           errmsg ("%d asynchronous errors", vam->async_errors);
6833           vam->retval = -98;
6834         }
6835       vam->async_errors = 0;
6836       after = vat_time_now (vam);
6837
6838       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6839       if (j > 0)
6840         count = j;
6841
6842       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6843              count, after - before, count / (after - before));
6844     }
6845   else
6846     {
6847       int ret;
6848
6849       /* Wait for a reply... */
6850       W (ret);
6851       return ret;
6852     }
6853
6854   /* Return the good/bad news */
6855   return (vam->retval);
6856 }
6857
6858 static int
6859 api_ip_mroute_add_del (vat_main_t * vam)
6860 {
6861   unformat_input_t *i = vam->input;
6862   vl_api_ip_mroute_add_del_t *mp;
6863   u32 sw_if_index = ~0, vrf_id = 0;
6864   u8 is_ipv6 = 0;
6865   u8 is_local = 0;
6866   u8 create_vrf_if_needed = 0;
6867   u8 is_add = 1;
6868   u8 address_set = 0;
6869   u32 grp_address_length = 0;
6870   ip4_address_t v4_grp_address, v4_src_address;
6871   ip6_address_t v6_grp_address, v6_src_address;
6872   mfib_itf_flags_t iflags = 0;
6873   mfib_entry_flags_t eflags = 0;
6874   int ret;
6875
6876   /* Parse args required to build the message */
6877   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6878     {
6879       if (unformat (i, "sw_if_index %d", &sw_if_index))
6880         ;
6881       else if (unformat (i, "%U %U",
6882                          unformat_ip4_address, &v4_src_address,
6883                          unformat_ip4_address, &v4_grp_address))
6884         {
6885           grp_address_length = 64;
6886           address_set = 1;
6887           is_ipv6 = 0;
6888         }
6889       else if (unformat (i, "%U %U",
6890                          unformat_ip6_address, &v6_src_address,
6891                          unformat_ip6_address, &v6_grp_address))
6892         {
6893           grp_address_length = 256;
6894           address_set = 1;
6895           is_ipv6 = 1;
6896         }
6897       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
6898         {
6899           memset (&v4_src_address, 0, sizeof (v4_src_address));
6900           grp_address_length = 32;
6901           address_set = 1;
6902           is_ipv6 = 0;
6903         }
6904       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
6905         {
6906           memset (&v6_src_address, 0, sizeof (v6_src_address));
6907           grp_address_length = 128;
6908           address_set = 1;
6909           is_ipv6 = 1;
6910         }
6911       else if (unformat (i, "/%d", &grp_address_length))
6912         ;
6913       else if (unformat (i, "local"))
6914         {
6915           is_local = 1;
6916         }
6917       else if (unformat (i, "del"))
6918         is_add = 0;
6919       else if (unformat (i, "add"))
6920         is_add = 1;
6921       else if (unformat (i, "vrf %d", &vrf_id))
6922         ;
6923       else if (unformat (i, "create-vrf"))
6924         create_vrf_if_needed = 1;
6925       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
6926         ;
6927       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6928         ;
6929       else
6930         {
6931           clib_warning ("parse error '%U'", format_unformat_error, i);
6932           return -99;
6933         }
6934     }
6935
6936   if (address_set == 0)
6937     {
6938       errmsg ("missing addresses\n");
6939       return -99;
6940     }
6941
6942   /* Construct the API message */
6943   M (IP_MROUTE_ADD_DEL, mp);
6944
6945   mp->next_hop_sw_if_index = ntohl (sw_if_index);
6946   mp->table_id = ntohl (vrf_id);
6947   mp->create_vrf_if_needed = create_vrf_if_needed;
6948
6949   mp->is_add = is_add;
6950   mp->is_ipv6 = is_ipv6;
6951   mp->is_local = is_local;
6952   mp->itf_flags = ntohl (iflags);
6953   mp->entry_flags = ntohl (eflags);
6954   mp->grp_address_length = grp_address_length;
6955   mp->grp_address_length = ntohs (mp->grp_address_length);
6956
6957   if (is_ipv6)
6958     {
6959       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
6960       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
6961     }
6962   else
6963     {
6964       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
6965       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
6966
6967     }
6968
6969   /* send it... */
6970   S (mp);
6971   /* Wait for a reply... */
6972   W (ret);
6973   return ret;
6974 }
6975
6976 static int
6977 api_mpls_route_add_del (vat_main_t * vam)
6978 {
6979   unformat_input_t *i = vam->input;
6980   vl_api_mpls_route_add_del_t *mp;
6981   u32 sw_if_index = ~0, table_id = 0;
6982   u8 create_table_if_needed = 0;
6983   u8 is_add = 1;
6984   u32 next_hop_weight = 1;
6985   u8 is_multipath = 0;
6986   u32 next_hop_table_id = 0;
6987   u8 next_hop_set = 0;
6988   ip4_address_t v4_next_hop_address = {
6989     .as_u32 = 0,
6990   };
6991   ip6_address_t v6_next_hop_address = { {0} };
6992   int count = 1;
6993   int j;
6994   f64 before = 0;
6995   u32 classify_table_index = ~0;
6996   u8 is_classify = 0;
6997   u8 resolve_host = 0, resolve_attached = 0;
6998   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6999   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7000   mpls_label_t *next_hop_out_label_stack = NULL;
7001   mpls_label_t local_label = MPLS_LABEL_INVALID;
7002   u8 is_eos = 0;
7003   u8 next_hop_proto_is_ip4 = 1;
7004
7005   /* Parse args required to build the message */
7006   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7007     {
7008       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7009         ;
7010       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7011         ;
7012       else if (unformat (i, "%d", &local_label))
7013         ;
7014       else if (unformat (i, "eos"))
7015         is_eos = 1;
7016       else if (unformat (i, "non-eos"))
7017         is_eos = 0;
7018       else if (unformat (i, "via %U", unformat_ip4_address,
7019                          &v4_next_hop_address))
7020         {
7021           next_hop_set = 1;
7022           next_hop_proto_is_ip4 = 1;
7023         }
7024       else if (unformat (i, "via %U", unformat_ip6_address,
7025                          &v6_next_hop_address))
7026         {
7027           next_hop_set = 1;
7028           next_hop_proto_is_ip4 = 0;
7029         }
7030       else if (unformat (i, "weight %d", &next_hop_weight))
7031         ;
7032       else if (unformat (i, "create-table"))
7033         create_table_if_needed = 1;
7034       else if (unformat (i, "classify %d", &classify_table_index))
7035         {
7036           is_classify = 1;
7037         }
7038       else if (unformat (i, "del"))
7039         is_add = 0;
7040       else if (unformat (i, "add"))
7041         is_add = 1;
7042       else if (unformat (i, "resolve-via-host"))
7043         resolve_host = 1;
7044       else if (unformat (i, "resolve-via-attached"))
7045         resolve_attached = 1;
7046       else if (unformat (i, "multipath"))
7047         is_multipath = 1;
7048       else if (unformat (i, "count %d", &count))
7049         ;
7050       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
7051         {
7052           next_hop_set = 1;
7053           next_hop_proto_is_ip4 = 1;
7054         }
7055       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
7056         {
7057           next_hop_set = 1;
7058           next_hop_proto_is_ip4 = 0;
7059         }
7060       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7061         ;
7062       else if (unformat (i, "via-label %d", &next_hop_via_label))
7063         ;
7064       else if (unformat (i, "out-label %d", &next_hop_out_label))
7065         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7066       else
7067         {
7068           clib_warning ("parse error '%U'", format_unformat_error, i);
7069           return -99;
7070         }
7071     }
7072
7073   if (!next_hop_set && !is_classify)
7074     {
7075       errmsg ("next hop / classify not set");
7076       return -99;
7077     }
7078
7079   if (MPLS_LABEL_INVALID == local_label)
7080     {
7081       errmsg ("missing label");
7082       return -99;
7083     }
7084
7085   if (count > 1)
7086     {
7087       /* Turn on async mode */
7088       vam->async_mode = 1;
7089       vam->async_errors = 0;
7090       before = vat_time_now (vam);
7091     }
7092
7093   for (j = 0; j < count; j++)
7094     {
7095       /* Construct the API message */
7096       M2 (MPLS_ROUTE_ADD_DEL, mp,
7097           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7098
7099       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
7100       mp->mr_table_id = ntohl (table_id);
7101       mp->mr_create_table_if_needed = create_table_if_needed;
7102
7103       mp->mr_is_add = is_add;
7104       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7105       mp->mr_is_classify = is_classify;
7106       mp->mr_is_multipath = is_multipath;
7107       mp->mr_is_resolve_host = resolve_host;
7108       mp->mr_is_resolve_attached = resolve_attached;
7109       mp->mr_next_hop_weight = next_hop_weight;
7110       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
7111       mp->mr_classify_table_index = ntohl (classify_table_index);
7112       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
7113       mp->mr_label = ntohl (local_label);
7114       mp->mr_eos = is_eos;
7115
7116       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7117       if (0 != mp->mr_next_hop_n_out_labels)
7118         {
7119           memcpy (mp->mr_next_hop_out_label_stack,
7120                   next_hop_out_label_stack,
7121                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7122           vec_free (next_hop_out_label_stack);
7123         }
7124
7125       if (next_hop_set)
7126         {
7127           if (next_hop_proto_is_ip4)
7128             {
7129               clib_memcpy (mp->mr_next_hop,
7130                            &v4_next_hop_address,
7131                            sizeof (v4_next_hop_address));
7132             }
7133           else
7134             {
7135               clib_memcpy (mp->mr_next_hop,
7136                            &v6_next_hop_address,
7137                            sizeof (v6_next_hop_address));
7138             }
7139         }
7140       local_label++;
7141
7142       /* send it... */
7143       S (mp);
7144       /* If we receive SIGTERM, stop now... */
7145       if (vam->do_exit)
7146         break;
7147     }
7148
7149   /* When testing multiple add/del ops, use a control-ping to sync */
7150   if (count > 1)
7151     {
7152       vl_api_control_ping_t *mp_ping;
7153       f64 after;
7154       f64 timeout;
7155
7156       /* Shut off async mode */
7157       vam->async_mode = 0;
7158
7159       M (CONTROL_PING, mp_ping);
7160       S (mp_ping);
7161
7162       timeout = vat_time_now (vam) + 1.0;
7163       while (vat_time_now (vam) < timeout)
7164         if (vam->result_ready == 1)
7165           goto out;
7166       vam->retval = -99;
7167
7168     out:
7169       if (vam->retval == -99)
7170         errmsg ("timeout");
7171
7172       if (vam->async_errors > 0)
7173         {
7174           errmsg ("%d asynchronous errors", vam->async_errors);
7175           vam->retval = -98;
7176         }
7177       vam->async_errors = 0;
7178       after = vat_time_now (vam);
7179
7180       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7181       if (j > 0)
7182         count = j;
7183
7184       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7185              count, after - before, count / (after - before));
7186     }
7187   else
7188     {
7189       int ret;
7190
7191       /* Wait for a reply... */
7192       W (ret);
7193       return ret;
7194     }
7195
7196   /* Return the good/bad news */
7197   return (vam->retval);
7198 }
7199
7200 static int
7201 api_mpls_ip_bind_unbind (vat_main_t * vam)
7202 {
7203   unformat_input_t *i = vam->input;
7204   vl_api_mpls_ip_bind_unbind_t *mp;
7205   u32 ip_table_id = 0;
7206   u8 create_table_if_needed = 0;
7207   u8 is_bind = 1;
7208   u8 is_ip4 = 1;
7209   ip4_address_t v4_address;
7210   ip6_address_t v6_address;
7211   u32 address_length;
7212   u8 address_set = 0;
7213   mpls_label_t local_label = MPLS_LABEL_INVALID;
7214   int ret;
7215
7216   /* Parse args required to build the message */
7217   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7218     {
7219       if (unformat (i, "%U/%d", unformat_ip4_address,
7220                     &v4_address, &address_length))
7221         {
7222           is_ip4 = 1;
7223           address_set = 1;
7224         }
7225       else if (unformat (i, "%U/%d", unformat_ip6_address,
7226                          &v6_address, &address_length))
7227         {
7228           is_ip4 = 0;
7229           address_set = 1;
7230         }
7231       else if (unformat (i, "%d", &local_label))
7232         ;
7233       else if (unformat (i, "create-table"))
7234         create_table_if_needed = 1;
7235       else if (unformat (i, "table-id %d", &ip_table_id))
7236         ;
7237       else if (unformat (i, "unbind"))
7238         is_bind = 0;
7239       else if (unformat (i, "bind"))
7240         is_bind = 1;
7241       else
7242         {
7243           clib_warning ("parse error '%U'", format_unformat_error, i);
7244           return -99;
7245         }
7246     }
7247
7248   if (!address_set)
7249     {
7250       errmsg ("IP addres not set");
7251       return -99;
7252     }
7253
7254   if (MPLS_LABEL_INVALID == local_label)
7255     {
7256       errmsg ("missing label");
7257       return -99;
7258     }
7259
7260   /* Construct the API message */
7261   M (MPLS_IP_BIND_UNBIND, mp);
7262
7263   mp->mb_create_table_if_needed = create_table_if_needed;
7264   mp->mb_is_bind = is_bind;
7265   mp->mb_is_ip4 = is_ip4;
7266   mp->mb_ip_table_id = ntohl (ip_table_id);
7267   mp->mb_mpls_table_id = 0;
7268   mp->mb_label = ntohl (local_label);
7269   mp->mb_address_length = address_length;
7270
7271   if (is_ip4)
7272     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
7273   else
7274     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
7275
7276   /* send it... */
7277   S (mp);
7278
7279   /* Wait for a reply... */
7280   W (ret);
7281   return ret;
7282 }
7283
7284 static int
7285 api_proxy_arp_add_del (vat_main_t * vam)
7286 {
7287   unformat_input_t *i = vam->input;
7288   vl_api_proxy_arp_add_del_t *mp;
7289   u32 vrf_id = 0;
7290   u8 is_add = 1;
7291   ip4_address_t lo, hi;
7292   u8 range_set = 0;
7293   int ret;
7294
7295   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7296     {
7297       if (unformat (i, "vrf %d", &vrf_id))
7298         ;
7299       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
7300                          unformat_ip4_address, &hi))
7301         range_set = 1;
7302       else if (unformat (i, "del"))
7303         is_add = 0;
7304       else
7305         {
7306           clib_warning ("parse error '%U'", format_unformat_error, i);
7307           return -99;
7308         }
7309     }
7310
7311   if (range_set == 0)
7312     {
7313       errmsg ("address range not set");
7314       return -99;
7315     }
7316
7317   M (PROXY_ARP_ADD_DEL, mp);
7318
7319   mp->vrf_id = ntohl (vrf_id);
7320   mp->is_add = is_add;
7321   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
7322   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
7323
7324   S (mp);
7325   W (ret);
7326   return ret;
7327 }
7328
7329 static int
7330 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
7331 {
7332   unformat_input_t *i = vam->input;
7333   vl_api_proxy_arp_intfc_enable_disable_t *mp;
7334   u32 sw_if_index;
7335   u8 enable = 1;
7336   u8 sw_if_index_set = 0;
7337   int ret;
7338
7339   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7340     {
7341       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7342         sw_if_index_set = 1;
7343       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7344         sw_if_index_set = 1;
7345       else if (unformat (i, "enable"))
7346         enable = 1;
7347       else if (unformat (i, "disable"))
7348         enable = 0;
7349       else
7350         {
7351           clib_warning ("parse error '%U'", format_unformat_error, i);
7352           return -99;
7353         }
7354     }
7355
7356   if (sw_if_index_set == 0)
7357     {
7358       errmsg ("missing interface name or sw_if_index");
7359       return -99;
7360     }
7361
7362   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
7363
7364   mp->sw_if_index = ntohl (sw_if_index);
7365   mp->enable_disable = enable;
7366
7367   S (mp);
7368   W (ret);
7369   return ret;
7370 }
7371
7372 static int
7373 api_mpls_tunnel_add_del (vat_main_t * vam)
7374 {
7375   unformat_input_t *i = vam->input;
7376   vl_api_mpls_tunnel_add_del_t *mp;
7377
7378   u8 is_add = 1;
7379   u8 l2_only = 0;
7380   u32 sw_if_index = ~0;
7381   u32 next_hop_sw_if_index = ~0;
7382   u32 next_hop_proto_is_ip4 = 1;
7383
7384   u32 next_hop_table_id = 0;
7385   ip4_address_t v4_next_hop_address = {
7386     .as_u32 = 0,
7387   };
7388   ip6_address_t v6_next_hop_address = { {0} };
7389   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
7390   int ret;
7391
7392   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7393     {
7394       if (unformat (i, "add"))
7395         is_add = 1;
7396       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7397         is_add = 0;
7398       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7399         ;
7400       else if (unformat (i, "via %U",
7401                          unformat_ip4_address, &v4_next_hop_address))
7402         {
7403           next_hop_proto_is_ip4 = 1;
7404         }
7405       else if (unformat (i, "via %U",
7406                          unformat_ip6_address, &v6_next_hop_address))
7407         {
7408           next_hop_proto_is_ip4 = 0;
7409         }
7410       else if (unformat (i, "l2-only"))
7411         l2_only = 1;
7412       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7413         ;
7414       else if (unformat (i, "out-label %d", &next_hop_out_label))
7415         vec_add1 (labels, ntohl (next_hop_out_label));
7416       else
7417         {
7418           clib_warning ("parse error '%U'", format_unformat_error, i);
7419           return -99;
7420         }
7421     }
7422
7423   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
7424
7425   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
7426   mp->mt_sw_if_index = ntohl (sw_if_index);
7427   mp->mt_is_add = is_add;
7428   mp->mt_l2_only = l2_only;
7429   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
7430   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7431
7432   mp->mt_next_hop_n_out_labels = vec_len (labels);
7433
7434   if (0 != mp->mt_next_hop_n_out_labels)
7435     {
7436       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7437                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7438       vec_free (labels);
7439     }
7440
7441   if (next_hop_proto_is_ip4)
7442     {
7443       clib_memcpy (mp->mt_next_hop,
7444                    &v4_next_hop_address, sizeof (v4_next_hop_address));
7445     }
7446   else
7447     {
7448       clib_memcpy (mp->mt_next_hop,
7449                    &v6_next_hop_address, sizeof (v6_next_hop_address));
7450     }
7451
7452   S (mp);
7453   W (ret);
7454   return ret;
7455 }
7456
7457 static int
7458 api_sw_interface_set_unnumbered (vat_main_t * vam)
7459 {
7460   unformat_input_t *i = vam->input;
7461   vl_api_sw_interface_set_unnumbered_t *mp;
7462   u32 sw_if_index;
7463   u32 unnum_sw_index = ~0;
7464   u8 is_add = 1;
7465   u8 sw_if_index_set = 0;
7466   int ret;
7467
7468   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7469     {
7470       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7471         sw_if_index_set = 1;
7472       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7473         sw_if_index_set = 1;
7474       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7475         ;
7476       else if (unformat (i, "del"))
7477         is_add = 0;
7478       else
7479         {
7480           clib_warning ("parse error '%U'", format_unformat_error, i);
7481           return -99;
7482         }
7483     }
7484
7485   if (sw_if_index_set == 0)
7486     {
7487       errmsg ("missing interface name or sw_if_index");
7488       return -99;
7489     }
7490
7491   M (SW_INTERFACE_SET_UNNUMBERED, mp);
7492
7493   mp->sw_if_index = ntohl (sw_if_index);
7494   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7495   mp->is_add = is_add;
7496
7497   S (mp);
7498   W (ret);
7499   return ret;
7500 }
7501
7502 static int
7503 api_ip_neighbor_add_del (vat_main_t * vam)
7504 {
7505   unformat_input_t *i = vam->input;
7506   vl_api_ip_neighbor_add_del_t *mp;
7507   u32 sw_if_index;
7508   u8 sw_if_index_set = 0;
7509   u8 is_add = 1;
7510   u8 is_static = 0;
7511   u8 is_no_fib_entry = 0;
7512   u8 mac_address[6];
7513   u8 mac_set = 0;
7514   u8 v4_address_set = 0;
7515   u8 v6_address_set = 0;
7516   ip4_address_t v4address;
7517   ip6_address_t v6address;
7518   int ret;
7519
7520   memset (mac_address, 0, sizeof (mac_address));
7521
7522   /* Parse args required to build the message */
7523   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7524     {
7525       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7526         {
7527           mac_set = 1;
7528         }
7529       else if (unformat (i, "del"))
7530         is_add = 0;
7531       else
7532         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7533         sw_if_index_set = 1;
7534       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7535         sw_if_index_set = 1;
7536       else if (unformat (i, "is_static"))
7537         is_static = 1;
7538       else if (unformat (i, "no-fib-entry"))
7539         is_no_fib_entry = 1;
7540       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
7541         v4_address_set = 1;
7542       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
7543         v6_address_set = 1;
7544       else
7545         {
7546           clib_warning ("parse error '%U'", format_unformat_error, i);
7547           return -99;
7548         }
7549     }
7550
7551   if (sw_if_index_set == 0)
7552     {
7553       errmsg ("missing interface name or sw_if_index");
7554       return -99;
7555     }
7556   if (v4_address_set && v6_address_set)
7557     {
7558       errmsg ("both v4 and v6 addresses set");
7559       return -99;
7560     }
7561   if (!v4_address_set && !v6_address_set)
7562     {
7563       errmsg ("no address set");
7564       return -99;
7565     }
7566
7567   /* Construct the API message */
7568   M (IP_NEIGHBOR_ADD_DEL, mp);
7569
7570   mp->sw_if_index = ntohl (sw_if_index);
7571   mp->is_add = is_add;
7572   mp->is_static = is_static;
7573   mp->is_no_adj_fib = is_no_fib_entry;
7574   if (mac_set)
7575     clib_memcpy (mp->mac_address, mac_address, 6);
7576   if (v6_address_set)
7577     {
7578       mp->is_ipv6 = 1;
7579       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
7580     }
7581   else
7582     {
7583       /* mp->is_ipv6 = 0; via memset in M macro above */
7584       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
7585     }
7586
7587   /* send it... */
7588   S (mp);
7589
7590   /* Wait for a reply, return good/bad news  */
7591   W (ret);
7592   return ret;
7593 }
7594
7595 static int
7596 api_reset_vrf (vat_main_t * vam)
7597 {
7598   unformat_input_t *i = vam->input;
7599   vl_api_reset_vrf_t *mp;
7600   u32 vrf_id = 0;
7601   u8 is_ipv6 = 0;
7602   u8 vrf_id_set = 0;
7603   int ret;
7604
7605   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7606     {
7607       if (unformat (i, "vrf %d", &vrf_id))
7608         vrf_id_set = 1;
7609       else if (unformat (i, "ipv6"))
7610         is_ipv6 = 1;
7611       else
7612         {
7613           clib_warning ("parse error '%U'", format_unformat_error, i);
7614           return -99;
7615         }
7616     }
7617
7618   if (vrf_id_set == 0)
7619     {
7620       errmsg ("missing vrf id");
7621       return -99;
7622     }
7623
7624   M (RESET_VRF, mp);
7625
7626   mp->vrf_id = ntohl (vrf_id);
7627   mp->is_ipv6 = is_ipv6;
7628
7629   S (mp);
7630   W (ret);
7631   return ret;
7632 }
7633
7634 static int
7635 api_create_vlan_subif (vat_main_t * vam)
7636 {
7637   unformat_input_t *i = vam->input;
7638   vl_api_create_vlan_subif_t *mp;
7639   u32 sw_if_index;
7640   u8 sw_if_index_set = 0;
7641   u32 vlan_id;
7642   u8 vlan_id_set = 0;
7643   int ret;
7644
7645   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7646     {
7647       if (unformat (i, "sw_if_index %d", &sw_if_index))
7648         sw_if_index_set = 1;
7649       else
7650         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7651         sw_if_index_set = 1;
7652       else if (unformat (i, "vlan %d", &vlan_id))
7653         vlan_id_set = 1;
7654       else
7655         {
7656           clib_warning ("parse error '%U'", format_unformat_error, i);
7657           return -99;
7658         }
7659     }
7660
7661   if (sw_if_index_set == 0)
7662     {
7663       errmsg ("missing interface name or sw_if_index");
7664       return -99;
7665     }
7666
7667   if (vlan_id_set == 0)
7668     {
7669       errmsg ("missing vlan_id");
7670       return -99;
7671     }
7672   M (CREATE_VLAN_SUBIF, mp);
7673
7674   mp->sw_if_index = ntohl (sw_if_index);
7675   mp->vlan_id = ntohl (vlan_id);
7676
7677   S (mp);
7678   W (ret);
7679   return ret;
7680 }
7681
7682 #define foreach_create_subif_bit                \
7683 _(no_tags)                                      \
7684 _(one_tag)                                      \
7685 _(two_tags)                                     \
7686 _(dot1ad)                                       \
7687 _(exact_match)                                  \
7688 _(default_sub)                                  \
7689 _(outer_vlan_id_any)                            \
7690 _(inner_vlan_id_any)
7691
7692 static int
7693 api_create_subif (vat_main_t * vam)
7694 {
7695   unformat_input_t *i = vam->input;
7696   vl_api_create_subif_t *mp;
7697   u32 sw_if_index;
7698   u8 sw_if_index_set = 0;
7699   u32 sub_id;
7700   u8 sub_id_set = 0;
7701   u32 no_tags = 0;
7702   u32 one_tag = 0;
7703   u32 two_tags = 0;
7704   u32 dot1ad = 0;
7705   u32 exact_match = 0;
7706   u32 default_sub = 0;
7707   u32 outer_vlan_id_any = 0;
7708   u32 inner_vlan_id_any = 0;
7709   u32 tmp;
7710   u16 outer_vlan_id = 0;
7711   u16 inner_vlan_id = 0;
7712   int ret;
7713
7714   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7715     {
7716       if (unformat (i, "sw_if_index %d", &sw_if_index))
7717         sw_if_index_set = 1;
7718       else
7719         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7720         sw_if_index_set = 1;
7721       else if (unformat (i, "sub_id %d", &sub_id))
7722         sub_id_set = 1;
7723       else if (unformat (i, "outer_vlan_id %d", &tmp))
7724         outer_vlan_id = tmp;
7725       else if (unformat (i, "inner_vlan_id %d", &tmp))
7726         inner_vlan_id = tmp;
7727
7728 #define _(a) else if (unformat (i, #a)) a = 1 ;
7729       foreach_create_subif_bit
7730 #undef _
7731         else
7732         {
7733           clib_warning ("parse error '%U'", format_unformat_error, i);
7734           return -99;
7735         }
7736     }
7737
7738   if (sw_if_index_set == 0)
7739     {
7740       errmsg ("missing interface name or sw_if_index");
7741       return -99;
7742     }
7743
7744   if (sub_id_set == 0)
7745     {
7746       errmsg ("missing sub_id");
7747       return -99;
7748     }
7749   M (CREATE_SUBIF, mp);
7750
7751   mp->sw_if_index = ntohl (sw_if_index);
7752   mp->sub_id = ntohl (sub_id);
7753
7754 #define _(a) mp->a = a;
7755   foreach_create_subif_bit;
7756 #undef _
7757
7758   mp->outer_vlan_id = ntohs (outer_vlan_id);
7759   mp->inner_vlan_id = ntohs (inner_vlan_id);
7760
7761   S (mp);
7762   W (ret);
7763   return ret;
7764 }
7765
7766 static int
7767 api_oam_add_del (vat_main_t * vam)
7768 {
7769   unformat_input_t *i = vam->input;
7770   vl_api_oam_add_del_t *mp;
7771   u32 vrf_id = 0;
7772   u8 is_add = 1;
7773   ip4_address_t src, dst;
7774   u8 src_set = 0;
7775   u8 dst_set = 0;
7776   int ret;
7777
7778   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7779     {
7780       if (unformat (i, "vrf %d", &vrf_id))
7781         ;
7782       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7783         src_set = 1;
7784       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7785         dst_set = 1;
7786       else if (unformat (i, "del"))
7787         is_add = 0;
7788       else
7789         {
7790           clib_warning ("parse error '%U'", format_unformat_error, i);
7791           return -99;
7792         }
7793     }
7794
7795   if (src_set == 0)
7796     {
7797       errmsg ("missing src addr");
7798       return -99;
7799     }
7800
7801   if (dst_set == 0)
7802     {
7803       errmsg ("missing dst addr");
7804       return -99;
7805     }
7806
7807   M (OAM_ADD_DEL, mp);
7808
7809   mp->vrf_id = ntohl (vrf_id);
7810   mp->is_add = is_add;
7811   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7812   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7813
7814   S (mp);
7815   W (ret);
7816   return ret;
7817 }
7818
7819 static int
7820 api_reset_fib (vat_main_t * vam)
7821 {
7822   unformat_input_t *i = vam->input;
7823   vl_api_reset_fib_t *mp;
7824   u32 vrf_id = 0;
7825   u8 is_ipv6 = 0;
7826   u8 vrf_id_set = 0;
7827
7828   int ret;
7829   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7830     {
7831       if (unformat (i, "vrf %d", &vrf_id))
7832         vrf_id_set = 1;
7833       else if (unformat (i, "ipv6"))
7834         is_ipv6 = 1;
7835       else
7836         {
7837           clib_warning ("parse error '%U'", format_unformat_error, i);
7838           return -99;
7839         }
7840     }
7841
7842   if (vrf_id_set == 0)
7843     {
7844       errmsg ("missing vrf id");
7845       return -99;
7846     }
7847
7848   M (RESET_FIB, mp);
7849
7850   mp->vrf_id = ntohl (vrf_id);
7851   mp->is_ipv6 = is_ipv6;
7852
7853   S (mp);
7854   W (ret);
7855   return ret;
7856 }
7857
7858 static int
7859 api_dhcp_proxy_config (vat_main_t * vam)
7860 {
7861   unformat_input_t *i = vam->input;
7862   vl_api_dhcp_proxy_config_t *mp;
7863   u32 rx_vrf_id = 0;
7864   u32 server_vrf_id = 0;
7865   u8 is_add = 1;
7866   u8 v4_address_set = 0;
7867   u8 v6_address_set = 0;
7868   ip4_address_t v4address;
7869   ip6_address_t v6address;
7870   u8 v4_src_address_set = 0;
7871   u8 v6_src_address_set = 0;
7872   ip4_address_t v4srcaddress;
7873   ip6_address_t v6srcaddress;
7874   int ret;
7875
7876   /* Parse args required to build the message */
7877   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7878     {
7879       if (unformat (i, "del"))
7880         is_add = 0;
7881       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7882         ;
7883       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7884         ;
7885       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7886         v4_address_set = 1;
7887       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7888         v6_address_set = 1;
7889       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7890         v4_src_address_set = 1;
7891       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7892         v6_src_address_set = 1;
7893       else
7894         break;
7895     }
7896
7897   if (v4_address_set && v6_address_set)
7898     {
7899       errmsg ("both v4 and v6 server addresses set");
7900       return -99;
7901     }
7902   if (!v4_address_set && !v6_address_set)
7903     {
7904       errmsg ("no server addresses set");
7905       return -99;
7906     }
7907
7908   if (v4_src_address_set && v6_src_address_set)
7909     {
7910       errmsg ("both v4 and v6  src addresses set");
7911       return -99;
7912     }
7913   if (!v4_src_address_set && !v6_src_address_set)
7914     {
7915       errmsg ("no src addresses set");
7916       return -99;
7917     }
7918
7919   if (!(v4_src_address_set && v4_address_set) &&
7920       !(v6_src_address_set && v6_address_set))
7921     {
7922       errmsg ("no matching server and src addresses set");
7923       return -99;
7924     }
7925
7926   /* Construct the API message */
7927   M (DHCP_PROXY_CONFIG, mp);
7928
7929   mp->is_add = is_add;
7930   mp->rx_vrf_id = ntohl (rx_vrf_id);
7931   mp->server_vrf_id = ntohl (server_vrf_id);
7932   if (v6_address_set)
7933     {
7934       mp->is_ipv6 = 1;
7935       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7936       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7937     }
7938   else
7939     {
7940       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7941       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7942     }
7943
7944   /* send it... */
7945   S (mp);
7946
7947   /* Wait for a reply, return good/bad news  */
7948   W (ret);
7949   return ret;
7950 }
7951
7952 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
7953 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
7954
7955 static void
7956 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
7957 {
7958   vat_main_t *vam = &vat_main;
7959   u32 i, count = mp->count;
7960   vl_api_dhcp_server_t *s;
7961
7962   if (mp->is_ipv6)
7963     print (vam->ofp,
7964            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7965            ntohl (mp->rx_vrf_id),
7966            format_ip6_address, mp->dhcp_src_address,
7967            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7968   else
7969     print (vam->ofp,
7970            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7971            ntohl (mp->rx_vrf_id),
7972            format_ip4_address, mp->dhcp_src_address,
7973            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7974
7975   for (i = 0; i < count; i++)
7976     {
7977       s = &mp->servers[i];
7978
7979       if (mp->is_ipv6)
7980         print (vam->ofp,
7981                " Server Table-ID %d, Server Address %U",
7982                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
7983       else
7984         print (vam->ofp,
7985                " Server Table-ID %d, Server Address %U",
7986                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
7987     }
7988 }
7989
7990 static void vl_api_dhcp_proxy_details_t_handler_json
7991   (vl_api_dhcp_proxy_details_t * mp)
7992 {
7993   vat_main_t *vam = &vat_main;
7994   vat_json_node_t *node = NULL;
7995   u32 i, count = mp->count;
7996   struct in_addr ip4;
7997   struct in6_addr ip6;
7998   vl_api_dhcp_server_t *s;
7999
8000   if (VAT_JSON_ARRAY != vam->json_tree.type)
8001     {
8002       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8003       vat_json_init_array (&vam->json_tree);
8004     }
8005   node = vat_json_array_add (&vam->json_tree);
8006
8007   vat_json_init_object (node);
8008   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
8009   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
8010   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
8011
8012   if (mp->is_ipv6)
8013     {
8014       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
8015       vat_json_object_add_ip6 (node, "src_address", ip6);
8016     }
8017   else
8018     {
8019       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
8020       vat_json_object_add_ip4 (node, "src_address", ip4);
8021     }
8022
8023   for (i = 0; i < count; i++)
8024     {
8025       s = &mp->servers[i];
8026
8027       vat_json_object_add_uint (node, "server-table-id",
8028                                 ntohl (s->server_vrf_id));
8029
8030       if (mp->is_ipv6)
8031         {
8032           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
8033           vat_json_object_add_ip4 (node, "src_address", ip4);
8034         }
8035       else
8036         {
8037           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
8038           vat_json_object_add_ip6 (node, "server_address", ip6);
8039         }
8040     }
8041 }
8042
8043 static int
8044 api_dhcp_proxy_dump (vat_main_t * vam)
8045 {
8046   unformat_input_t *i = vam->input;
8047   vl_api_control_ping_t *mp_ping;
8048   vl_api_dhcp_proxy_dump_t *mp;
8049   u8 is_ipv6 = 0;
8050   int ret;
8051
8052   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8053     {
8054       if (unformat (i, "ipv6"))
8055         is_ipv6 = 1;
8056       else
8057         {
8058           clib_warning ("parse error '%U'", format_unformat_error, i);
8059           return -99;
8060         }
8061     }
8062
8063   M (DHCP_PROXY_DUMP, mp);
8064
8065   mp->is_ip6 = is_ipv6;
8066   S (mp);
8067
8068   /* Use a control ping for synchronization */
8069   M (CONTROL_PING, mp_ping);
8070   S (mp_ping);
8071
8072   W (ret);
8073   return ret;
8074 }
8075
8076 static int
8077 api_dhcp_proxy_set_vss (vat_main_t * vam)
8078 {
8079   unformat_input_t *i = vam->input;
8080   vl_api_dhcp_proxy_set_vss_t *mp;
8081   u8 is_ipv6 = 0;
8082   u8 is_add = 1;
8083   u32 tbl_id;
8084   u8 tbl_id_set = 0;
8085   u32 oui;
8086   u8 oui_set = 0;
8087   u32 fib_id;
8088   u8 fib_id_set = 0;
8089   int ret;
8090
8091   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8092     {
8093       if (unformat (i, "tbl_id %d", &tbl_id))
8094         tbl_id_set = 1;
8095       if (unformat (i, "fib_id %d", &fib_id))
8096         fib_id_set = 1;
8097       if (unformat (i, "oui %d", &oui))
8098         oui_set = 1;
8099       else if (unformat (i, "ipv6"))
8100         is_ipv6 = 1;
8101       else if (unformat (i, "del"))
8102         is_add = 0;
8103       else
8104         {
8105           clib_warning ("parse error '%U'", format_unformat_error, i);
8106           return -99;
8107         }
8108     }
8109
8110   if (tbl_id_set == 0)
8111     {
8112       errmsg ("missing tbl id");
8113       return -99;
8114     }
8115
8116   if (fib_id_set == 0)
8117     {
8118       errmsg ("missing fib id");
8119       return -99;
8120     }
8121   if (oui_set == 0)
8122     {
8123       errmsg ("missing oui");
8124       return -99;
8125     }
8126
8127   M (DHCP_PROXY_SET_VSS, mp);
8128   mp->tbl_id = ntohl (tbl_id);
8129   mp->fib_id = ntohl (fib_id);
8130   mp->oui = ntohl (oui);
8131   mp->is_ipv6 = is_ipv6;
8132   mp->is_add = is_add;
8133
8134   S (mp);
8135   W (ret);
8136   return ret;
8137 }
8138
8139 static int
8140 api_dhcp_client_config (vat_main_t * vam)
8141 {
8142   unformat_input_t *i = vam->input;
8143   vl_api_dhcp_client_config_t *mp;
8144   u32 sw_if_index;
8145   u8 sw_if_index_set = 0;
8146   u8 is_add = 1;
8147   u8 *hostname = 0;
8148   u8 disable_event = 0;
8149   int ret;
8150
8151   /* Parse args required to build the message */
8152   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8153     {
8154       if (unformat (i, "del"))
8155         is_add = 0;
8156       else
8157         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8158         sw_if_index_set = 1;
8159       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8160         sw_if_index_set = 1;
8161       else if (unformat (i, "hostname %s", &hostname))
8162         ;
8163       else if (unformat (i, "disable_event"))
8164         disable_event = 1;
8165       else
8166         break;
8167     }
8168
8169   if (sw_if_index_set == 0)
8170     {
8171       errmsg ("missing interface name or sw_if_index");
8172       return -99;
8173     }
8174
8175   if (vec_len (hostname) > 63)
8176     {
8177       errmsg ("hostname too long");
8178     }
8179   vec_add1 (hostname, 0);
8180
8181   /* Construct the API message */
8182   M (DHCP_CLIENT_CONFIG, mp);
8183
8184   mp->sw_if_index = htonl (sw_if_index);
8185   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
8186   vec_free (hostname);
8187   mp->is_add = is_add;
8188   mp->want_dhcp_event = disable_event ? 0 : 1;
8189   mp->pid = htonl (getpid ());
8190
8191   /* send it... */
8192   S (mp);
8193
8194   /* Wait for a reply, return good/bad news  */
8195   W (ret);
8196   return ret;
8197 }
8198
8199 static int
8200 api_set_ip_flow_hash (vat_main_t * vam)
8201 {
8202   unformat_input_t *i = vam->input;
8203   vl_api_set_ip_flow_hash_t *mp;
8204   u32 vrf_id = 0;
8205   u8 is_ipv6 = 0;
8206   u8 vrf_id_set = 0;
8207   u8 src = 0;
8208   u8 dst = 0;
8209   u8 sport = 0;
8210   u8 dport = 0;
8211   u8 proto = 0;
8212   u8 reverse = 0;
8213   int ret;
8214
8215   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8216     {
8217       if (unformat (i, "vrf %d", &vrf_id))
8218         vrf_id_set = 1;
8219       else if (unformat (i, "ipv6"))
8220         is_ipv6 = 1;
8221       else if (unformat (i, "src"))
8222         src = 1;
8223       else if (unformat (i, "dst"))
8224         dst = 1;
8225       else if (unformat (i, "sport"))
8226         sport = 1;
8227       else if (unformat (i, "dport"))
8228         dport = 1;
8229       else if (unformat (i, "proto"))
8230         proto = 1;
8231       else if (unformat (i, "reverse"))
8232         reverse = 1;
8233
8234       else
8235         {
8236           clib_warning ("parse error '%U'", format_unformat_error, i);
8237           return -99;
8238         }
8239     }
8240
8241   if (vrf_id_set == 0)
8242     {
8243       errmsg ("missing vrf id");
8244       return -99;
8245     }
8246
8247   M (SET_IP_FLOW_HASH, mp);
8248   mp->src = src;
8249   mp->dst = dst;
8250   mp->sport = sport;
8251   mp->dport = dport;
8252   mp->proto = proto;
8253   mp->reverse = reverse;
8254   mp->vrf_id = ntohl (vrf_id);
8255   mp->is_ipv6 = is_ipv6;
8256
8257   S (mp);
8258   W (ret);
8259   return ret;
8260 }
8261
8262 static int
8263 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
8264 {
8265   unformat_input_t *i = vam->input;
8266   vl_api_sw_interface_ip6_enable_disable_t *mp;
8267   u32 sw_if_index;
8268   u8 sw_if_index_set = 0;
8269   u8 enable = 0;
8270   int ret;
8271
8272   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8273     {
8274       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8275         sw_if_index_set = 1;
8276       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8277         sw_if_index_set = 1;
8278       else if (unformat (i, "enable"))
8279         enable = 1;
8280       else if (unformat (i, "disable"))
8281         enable = 0;
8282       else
8283         {
8284           clib_warning ("parse error '%U'", format_unformat_error, i);
8285           return -99;
8286         }
8287     }
8288
8289   if (sw_if_index_set == 0)
8290     {
8291       errmsg ("missing interface name or sw_if_index");
8292       return -99;
8293     }
8294
8295   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
8296
8297   mp->sw_if_index = ntohl (sw_if_index);
8298   mp->enable = enable;
8299
8300   S (mp);
8301   W (ret);
8302   return ret;
8303 }
8304
8305 static int
8306 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
8307 {
8308   unformat_input_t *i = vam->input;
8309   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
8310   u32 sw_if_index;
8311   u8 sw_if_index_set = 0;
8312   u8 v6_address_set = 0;
8313   ip6_address_t v6address;
8314   int ret;
8315
8316   /* Parse args required to build the message */
8317   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8318     {
8319       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8320         sw_if_index_set = 1;
8321       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8322         sw_if_index_set = 1;
8323       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8324         v6_address_set = 1;
8325       else
8326         break;
8327     }
8328
8329   if (sw_if_index_set == 0)
8330     {
8331       errmsg ("missing interface name or sw_if_index");
8332       return -99;
8333     }
8334   if (!v6_address_set)
8335     {
8336       errmsg ("no address set");
8337       return -99;
8338     }
8339
8340   /* Construct the API message */
8341   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
8342
8343   mp->sw_if_index = ntohl (sw_if_index);
8344   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8345
8346   /* send it... */
8347   S (mp);
8348
8349   /* Wait for a reply, return good/bad news  */
8350   W (ret);
8351   return ret;
8352 }
8353
8354 static int
8355 api_ip6nd_proxy_add_del (vat_main_t * vam)
8356 {
8357   unformat_input_t *i = vam->input;
8358   vl_api_ip6nd_proxy_add_del_t *mp;
8359   u32 sw_if_index = ~0;
8360   u8 v6_address_set = 0;
8361   ip6_address_t v6address;
8362   u8 is_del = 0;
8363   int ret;
8364
8365   /* Parse args required to build the message */
8366   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8367     {
8368       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8369         ;
8370       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8371         ;
8372       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8373         v6_address_set = 1;
8374       if (unformat (i, "del"))
8375         is_del = 1;
8376       else
8377         {
8378           clib_warning ("parse error '%U'", format_unformat_error, i);
8379           return -99;
8380         }
8381     }
8382
8383   if (sw_if_index == ~0)
8384     {
8385       errmsg ("missing interface name or sw_if_index");
8386       return -99;
8387     }
8388   if (!v6_address_set)
8389     {
8390       errmsg ("no address set");
8391       return -99;
8392     }
8393
8394   /* Construct the API message */
8395   M (IP6ND_PROXY_ADD_DEL, mp);
8396
8397   mp->is_del = is_del;
8398   mp->sw_if_index = ntohl (sw_if_index);
8399   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8400
8401   /* send it... */
8402   S (mp);
8403
8404   /* Wait for a reply, return good/bad news  */
8405   W (ret);
8406   return ret;
8407 }
8408
8409 static int
8410 api_ip6nd_proxy_dump (vat_main_t * vam)
8411 {
8412   vl_api_ip6nd_proxy_dump_t *mp;
8413   vl_api_control_ping_t *mp_ping;
8414   int ret;
8415
8416   M (IP6ND_PROXY_DUMP, mp);
8417
8418   S (mp);
8419
8420   /* Use a control ping for synchronization */
8421   M (CONTROL_PING, mp_ping);
8422   S (mp_ping);
8423
8424   W (ret);
8425   return ret;
8426 }
8427
8428 static void vl_api_ip6nd_proxy_details_t_handler
8429   (vl_api_ip6nd_proxy_details_t * mp)
8430 {
8431   vat_main_t *vam = &vat_main;
8432
8433   print (vam->ofp, "host %U sw_if_index %d",
8434          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
8435 }
8436
8437 static void vl_api_ip6nd_proxy_details_t_handler_json
8438   (vl_api_ip6nd_proxy_details_t * mp)
8439 {
8440   vat_main_t *vam = &vat_main;
8441   struct in6_addr ip6;
8442   vat_json_node_t *node = NULL;
8443
8444   if (VAT_JSON_ARRAY != vam->json_tree.type)
8445     {
8446       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8447       vat_json_init_array (&vam->json_tree);
8448     }
8449   node = vat_json_array_add (&vam->json_tree);
8450
8451   vat_json_init_object (node);
8452   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
8453
8454   clib_memcpy (&ip6, mp->address, sizeof (ip6));
8455   vat_json_object_add_ip6 (node, "host", ip6);
8456 }
8457
8458 static int
8459 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
8460 {
8461   unformat_input_t *i = vam->input;
8462   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
8463   u32 sw_if_index;
8464   u8 sw_if_index_set = 0;
8465   u32 address_length = 0;
8466   u8 v6_address_set = 0;
8467   ip6_address_t v6address;
8468   u8 use_default = 0;
8469   u8 no_advertise = 0;
8470   u8 off_link = 0;
8471   u8 no_autoconfig = 0;
8472   u8 no_onlink = 0;
8473   u8 is_no = 0;
8474   u32 val_lifetime = 0;
8475   u32 pref_lifetime = 0;
8476   int ret;
8477
8478   /* Parse args required to build the message */
8479   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8480     {
8481       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8482         sw_if_index_set = 1;
8483       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8484         sw_if_index_set = 1;
8485       else if (unformat (i, "%U/%d",
8486                          unformat_ip6_address, &v6address, &address_length))
8487         v6_address_set = 1;
8488       else if (unformat (i, "val_life %d", &val_lifetime))
8489         ;
8490       else if (unformat (i, "pref_life %d", &pref_lifetime))
8491         ;
8492       else if (unformat (i, "def"))
8493         use_default = 1;
8494       else if (unformat (i, "noadv"))
8495         no_advertise = 1;
8496       else if (unformat (i, "offl"))
8497         off_link = 1;
8498       else if (unformat (i, "noauto"))
8499         no_autoconfig = 1;
8500       else if (unformat (i, "nolink"))
8501         no_onlink = 1;
8502       else if (unformat (i, "isno"))
8503         is_no = 1;
8504       else
8505         {
8506           clib_warning ("parse error '%U'", format_unformat_error, i);
8507           return -99;
8508         }
8509     }
8510
8511   if (sw_if_index_set == 0)
8512     {
8513       errmsg ("missing interface name or sw_if_index");
8514       return -99;
8515     }
8516   if (!v6_address_set)
8517     {
8518       errmsg ("no address set");
8519       return -99;
8520     }
8521
8522   /* Construct the API message */
8523   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
8524
8525   mp->sw_if_index = ntohl (sw_if_index);
8526   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8527   mp->address_length = address_length;
8528   mp->use_default = use_default;
8529   mp->no_advertise = no_advertise;
8530   mp->off_link = off_link;
8531   mp->no_autoconfig = no_autoconfig;
8532   mp->no_onlink = no_onlink;
8533   mp->is_no = is_no;
8534   mp->val_lifetime = ntohl (val_lifetime);
8535   mp->pref_lifetime = ntohl (pref_lifetime);
8536
8537   /* send it... */
8538   S (mp);
8539
8540   /* Wait for a reply, return good/bad news  */
8541   W (ret);
8542   return ret;
8543 }
8544
8545 static int
8546 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
8547 {
8548   unformat_input_t *i = vam->input;
8549   vl_api_sw_interface_ip6nd_ra_config_t *mp;
8550   u32 sw_if_index;
8551   u8 sw_if_index_set = 0;
8552   u8 suppress = 0;
8553   u8 managed = 0;
8554   u8 other = 0;
8555   u8 ll_option = 0;
8556   u8 send_unicast = 0;
8557   u8 cease = 0;
8558   u8 is_no = 0;
8559   u8 default_router = 0;
8560   u32 max_interval = 0;
8561   u32 min_interval = 0;
8562   u32 lifetime = 0;
8563   u32 initial_count = 0;
8564   u32 initial_interval = 0;
8565   int ret;
8566
8567
8568   /* Parse args required to build the message */
8569   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8570     {
8571       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8572         sw_if_index_set = 1;
8573       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8574         sw_if_index_set = 1;
8575       else if (unformat (i, "maxint %d", &max_interval))
8576         ;
8577       else if (unformat (i, "minint %d", &min_interval))
8578         ;
8579       else if (unformat (i, "life %d", &lifetime))
8580         ;
8581       else if (unformat (i, "count %d", &initial_count))
8582         ;
8583       else if (unformat (i, "interval %d", &initial_interval))
8584         ;
8585       else if (unformat (i, "suppress") || unformat (i, "surpress"))
8586         suppress = 1;
8587       else if (unformat (i, "managed"))
8588         managed = 1;
8589       else if (unformat (i, "other"))
8590         other = 1;
8591       else if (unformat (i, "ll"))
8592         ll_option = 1;
8593       else if (unformat (i, "send"))
8594         send_unicast = 1;
8595       else if (unformat (i, "cease"))
8596         cease = 1;
8597       else if (unformat (i, "isno"))
8598         is_no = 1;
8599       else if (unformat (i, "def"))
8600         default_router = 1;
8601       else
8602         {
8603           clib_warning ("parse error '%U'", format_unformat_error, i);
8604           return -99;
8605         }
8606     }
8607
8608   if (sw_if_index_set == 0)
8609     {
8610       errmsg ("missing interface name or sw_if_index");
8611       return -99;
8612     }
8613
8614   /* Construct the API message */
8615   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
8616
8617   mp->sw_if_index = ntohl (sw_if_index);
8618   mp->max_interval = ntohl (max_interval);
8619   mp->min_interval = ntohl (min_interval);
8620   mp->lifetime = ntohl (lifetime);
8621   mp->initial_count = ntohl (initial_count);
8622   mp->initial_interval = ntohl (initial_interval);
8623   mp->suppress = suppress;
8624   mp->managed = managed;
8625   mp->other = other;
8626   mp->ll_option = ll_option;
8627   mp->send_unicast = send_unicast;
8628   mp->cease = cease;
8629   mp->is_no = is_no;
8630   mp->default_router = default_router;
8631
8632   /* send it... */
8633   S (mp);
8634
8635   /* Wait for a reply, return good/bad news  */
8636   W (ret);
8637   return ret;
8638 }
8639
8640 static int
8641 api_set_arp_neighbor_limit (vat_main_t * vam)
8642 {
8643   unformat_input_t *i = vam->input;
8644   vl_api_set_arp_neighbor_limit_t *mp;
8645   u32 arp_nbr_limit;
8646   u8 limit_set = 0;
8647   u8 is_ipv6 = 0;
8648   int ret;
8649
8650   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8651     {
8652       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
8653         limit_set = 1;
8654       else if (unformat (i, "ipv6"))
8655         is_ipv6 = 1;
8656       else
8657         {
8658           clib_warning ("parse error '%U'", format_unformat_error, i);
8659           return -99;
8660         }
8661     }
8662
8663   if (limit_set == 0)
8664     {
8665       errmsg ("missing limit value");
8666       return -99;
8667     }
8668
8669   M (SET_ARP_NEIGHBOR_LIMIT, mp);
8670
8671   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
8672   mp->is_ipv6 = is_ipv6;
8673
8674   S (mp);
8675   W (ret);
8676   return ret;
8677 }
8678
8679 static int
8680 api_l2_patch_add_del (vat_main_t * vam)
8681 {
8682   unformat_input_t *i = vam->input;
8683   vl_api_l2_patch_add_del_t *mp;
8684   u32 rx_sw_if_index;
8685   u8 rx_sw_if_index_set = 0;
8686   u32 tx_sw_if_index;
8687   u8 tx_sw_if_index_set = 0;
8688   u8 is_add = 1;
8689   int ret;
8690
8691   /* Parse args required to build the message */
8692   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8693     {
8694       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
8695         rx_sw_if_index_set = 1;
8696       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
8697         tx_sw_if_index_set = 1;
8698       else if (unformat (i, "rx"))
8699         {
8700           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8701             {
8702               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8703                             &rx_sw_if_index))
8704                 rx_sw_if_index_set = 1;
8705             }
8706           else
8707             break;
8708         }
8709       else if (unformat (i, "tx"))
8710         {
8711           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8712             {
8713               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8714                             &tx_sw_if_index))
8715                 tx_sw_if_index_set = 1;
8716             }
8717           else
8718             break;
8719         }
8720       else if (unformat (i, "del"))
8721         is_add = 0;
8722       else
8723         break;
8724     }
8725
8726   if (rx_sw_if_index_set == 0)
8727     {
8728       errmsg ("missing rx interface name or rx_sw_if_index");
8729       return -99;
8730     }
8731
8732   if (tx_sw_if_index_set == 0)
8733     {
8734       errmsg ("missing tx interface name or tx_sw_if_index");
8735       return -99;
8736     }
8737
8738   M (L2_PATCH_ADD_DEL, mp);
8739
8740   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
8741   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
8742   mp->is_add = is_add;
8743
8744   S (mp);
8745   W (ret);
8746   return ret;
8747 }
8748
8749 u8 is_del;
8750 u8 localsid_addr[16];
8751 u8 end_psp;
8752 u8 behavior;
8753 u32 sw_if_index;
8754 u32 vlan_index;
8755 u32 fib_table;
8756 u8 nh_addr[16];
8757
8758 static int
8759 api_sr_localsid_add_del (vat_main_t * vam)
8760 {
8761   unformat_input_t *i = vam->input;
8762   vl_api_sr_localsid_add_del_t *mp;
8763
8764   u8 is_del;
8765   ip6_address_t localsid;
8766   u8 end_psp = 0;
8767   u8 behavior = ~0;
8768   u32 sw_if_index;
8769   u32 fib_table = ~(u32) 0;
8770   ip6_address_t next_hop;
8771
8772   bool nexthop_set = 0;
8773
8774   int ret;
8775
8776   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8777     {
8778       if (unformat (i, "del"))
8779         is_del = 1;
8780       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
8781       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
8782         nexthop_set = 1;
8783       else if (unformat (i, "behavior %u", &behavior));
8784       else if (unformat (i, "sw_if_index %u", &sw_if_index));
8785       else if (unformat (i, "fib-table %u", &fib_table));
8786       else if (unformat (i, "end.psp %u", &behavior));
8787       else
8788         break;
8789     }
8790
8791   M (SR_LOCALSID_ADD_DEL, mp);
8792
8793   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
8794   if (nexthop_set)
8795     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
8796   mp->behavior = behavior;
8797   mp->sw_if_index = ntohl (sw_if_index);
8798   mp->fib_table = ntohl (fib_table);
8799   mp->end_psp = end_psp;
8800   mp->is_del = is_del;
8801
8802   S (mp);
8803   W (ret);
8804   return ret;
8805 }
8806
8807 static int
8808 api_ioam_enable (vat_main_t * vam)
8809 {
8810   unformat_input_t *input = vam->input;
8811   vl_api_ioam_enable_t *mp;
8812   u32 id = 0;
8813   int has_trace_option = 0;
8814   int has_pot_option = 0;
8815   int has_seqno_option = 0;
8816   int has_analyse_option = 0;
8817   int ret;
8818
8819   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8820     {
8821       if (unformat (input, "trace"))
8822         has_trace_option = 1;
8823       else if (unformat (input, "pot"))
8824         has_pot_option = 1;
8825       else if (unformat (input, "seqno"))
8826         has_seqno_option = 1;
8827       else if (unformat (input, "analyse"))
8828         has_analyse_option = 1;
8829       else
8830         break;
8831     }
8832   M (IOAM_ENABLE, mp);
8833   mp->id = htons (id);
8834   mp->seqno = has_seqno_option;
8835   mp->analyse = has_analyse_option;
8836   mp->pot_enable = has_pot_option;
8837   mp->trace_enable = has_trace_option;
8838
8839   S (mp);
8840   W (ret);
8841   return ret;
8842 }
8843
8844
8845 static int
8846 api_ioam_disable (vat_main_t * vam)
8847 {
8848   vl_api_ioam_disable_t *mp;
8849   int ret;
8850
8851   M (IOAM_DISABLE, mp);
8852   S (mp);
8853   W (ret);
8854   return ret;
8855 }
8856
8857 #define foreach_tcp_proto_field                 \
8858 _(src_port)                                     \
8859 _(dst_port)
8860
8861 #define foreach_udp_proto_field                 \
8862 _(src_port)                                     \
8863 _(dst_port)
8864
8865 #define foreach_ip4_proto_field                 \
8866 _(src_address)                                  \
8867 _(dst_address)                                  \
8868 _(tos)                                          \
8869 _(length)                                       \
8870 _(fragment_id)                                  \
8871 _(ttl)                                          \
8872 _(protocol)                                     \
8873 _(checksum)
8874
8875 typedef struct
8876 {
8877   u16 src_port, dst_port;
8878 } tcpudp_header_t;
8879
8880 #if VPP_API_TEST_BUILTIN == 0
8881 uword
8882 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8883 {
8884   u8 **maskp = va_arg (*args, u8 **);
8885   u8 *mask = 0;
8886   u8 found_something = 0;
8887   tcp_header_t *tcp;
8888
8889 #define _(a) u8 a=0;
8890   foreach_tcp_proto_field;
8891 #undef _
8892
8893   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8894     {
8895       if (0);
8896 #define _(a) else if (unformat (input, #a)) a=1;
8897       foreach_tcp_proto_field
8898 #undef _
8899         else
8900         break;
8901     }
8902
8903 #define _(a) found_something += a;
8904   foreach_tcp_proto_field;
8905 #undef _
8906
8907   if (found_something == 0)
8908     return 0;
8909
8910   vec_validate (mask, sizeof (*tcp) - 1);
8911
8912   tcp = (tcp_header_t *) mask;
8913
8914 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8915   foreach_tcp_proto_field;
8916 #undef _
8917
8918   *maskp = mask;
8919   return 1;
8920 }
8921
8922 uword
8923 unformat_udp_mask (unformat_input_t * input, va_list * args)
8924 {
8925   u8 **maskp = va_arg (*args, u8 **);
8926   u8 *mask = 0;
8927   u8 found_something = 0;
8928   udp_header_t *udp;
8929
8930 #define _(a) u8 a=0;
8931   foreach_udp_proto_field;
8932 #undef _
8933
8934   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8935     {
8936       if (0);
8937 #define _(a) else if (unformat (input, #a)) a=1;
8938       foreach_udp_proto_field
8939 #undef _
8940         else
8941         break;
8942     }
8943
8944 #define _(a) found_something += a;
8945   foreach_udp_proto_field;
8946 #undef _
8947
8948   if (found_something == 0)
8949     return 0;
8950
8951   vec_validate (mask, sizeof (*udp) - 1);
8952
8953   udp = (udp_header_t *) mask;
8954
8955 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8956   foreach_udp_proto_field;
8957 #undef _
8958
8959   *maskp = mask;
8960   return 1;
8961 }
8962
8963 uword
8964 unformat_l4_mask (unformat_input_t * input, va_list * args)
8965 {
8966   u8 **maskp = va_arg (*args, u8 **);
8967   u16 src_port = 0, dst_port = 0;
8968   tcpudp_header_t *tcpudp;
8969
8970   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8971     {
8972       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8973         return 1;
8974       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8975         return 1;
8976       else if (unformat (input, "src_port"))
8977         src_port = 0xFFFF;
8978       else if (unformat (input, "dst_port"))
8979         dst_port = 0xFFFF;
8980       else
8981         return 0;
8982     }
8983
8984   if (!src_port && !dst_port)
8985     return 0;
8986
8987   u8 *mask = 0;
8988   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8989
8990   tcpudp = (tcpudp_header_t *) mask;
8991   tcpudp->src_port = src_port;
8992   tcpudp->dst_port = dst_port;
8993
8994   *maskp = mask;
8995
8996   return 1;
8997 }
8998
8999 uword
9000 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9001 {
9002   u8 **maskp = va_arg (*args, u8 **);
9003   u8 *mask = 0;
9004   u8 found_something = 0;
9005   ip4_header_t *ip;
9006
9007 #define _(a) u8 a=0;
9008   foreach_ip4_proto_field;
9009 #undef _
9010   u8 version = 0;
9011   u8 hdr_length = 0;
9012
9013
9014   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9015     {
9016       if (unformat (input, "version"))
9017         version = 1;
9018       else if (unformat (input, "hdr_length"))
9019         hdr_length = 1;
9020       else if (unformat (input, "src"))
9021         src_address = 1;
9022       else if (unformat (input, "dst"))
9023         dst_address = 1;
9024       else if (unformat (input, "proto"))
9025         protocol = 1;
9026
9027 #define _(a) else if (unformat (input, #a)) a=1;
9028       foreach_ip4_proto_field
9029 #undef _
9030         else
9031         break;
9032     }
9033
9034 #define _(a) found_something += a;
9035   foreach_ip4_proto_field;
9036 #undef _
9037
9038   if (found_something == 0)
9039     return 0;
9040
9041   vec_validate (mask, sizeof (*ip) - 1);
9042
9043   ip = (ip4_header_t *) mask;
9044
9045 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9046   foreach_ip4_proto_field;
9047 #undef _
9048
9049   ip->ip_version_and_header_length = 0;
9050
9051   if (version)
9052     ip->ip_version_and_header_length |= 0xF0;
9053
9054   if (hdr_length)
9055     ip->ip_version_and_header_length |= 0x0F;
9056
9057   *maskp = mask;
9058   return 1;
9059 }
9060
9061 #define foreach_ip6_proto_field                 \
9062 _(src_address)                                  \
9063 _(dst_address)                                  \
9064 _(payload_length)                               \
9065 _(hop_limit)                                    \
9066 _(protocol)
9067
9068 uword
9069 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9070 {
9071   u8 **maskp = va_arg (*args, u8 **);
9072   u8 *mask = 0;
9073   u8 found_something = 0;
9074   ip6_header_t *ip;
9075   u32 ip_version_traffic_class_and_flow_label;
9076
9077 #define _(a) u8 a=0;
9078   foreach_ip6_proto_field;
9079 #undef _
9080   u8 version = 0;
9081   u8 traffic_class = 0;
9082   u8 flow_label = 0;
9083
9084   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9085     {
9086       if (unformat (input, "version"))
9087         version = 1;
9088       else if (unformat (input, "traffic-class"))
9089         traffic_class = 1;
9090       else if (unformat (input, "flow-label"))
9091         flow_label = 1;
9092       else if (unformat (input, "src"))
9093         src_address = 1;
9094       else if (unformat (input, "dst"))
9095         dst_address = 1;
9096       else if (unformat (input, "proto"))
9097         protocol = 1;
9098
9099 #define _(a) else if (unformat (input, #a)) a=1;
9100       foreach_ip6_proto_field
9101 #undef _
9102         else
9103         break;
9104     }
9105
9106 #define _(a) found_something += a;
9107   foreach_ip6_proto_field;
9108 #undef _
9109
9110   if (found_something == 0)
9111     return 0;
9112
9113   vec_validate (mask, sizeof (*ip) - 1);
9114
9115   ip = (ip6_header_t *) mask;
9116
9117 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9118   foreach_ip6_proto_field;
9119 #undef _
9120
9121   ip_version_traffic_class_and_flow_label = 0;
9122
9123   if (version)
9124     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9125
9126   if (traffic_class)
9127     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9128
9129   if (flow_label)
9130     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9131
9132   ip->ip_version_traffic_class_and_flow_label =
9133     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9134
9135   *maskp = mask;
9136   return 1;
9137 }
9138
9139 uword
9140 unformat_l3_mask (unformat_input_t * input, va_list * args)
9141 {
9142   u8 **maskp = va_arg (*args, u8 **);
9143
9144   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9145     {
9146       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9147         return 1;
9148       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9149         return 1;
9150       else
9151         break;
9152     }
9153   return 0;
9154 }
9155
9156 uword
9157 unformat_l2_mask (unformat_input_t * input, va_list * args)
9158 {
9159   u8 **maskp = va_arg (*args, u8 **);
9160   u8 *mask = 0;
9161   u8 src = 0;
9162   u8 dst = 0;
9163   u8 proto = 0;
9164   u8 tag1 = 0;
9165   u8 tag2 = 0;
9166   u8 ignore_tag1 = 0;
9167   u8 ignore_tag2 = 0;
9168   u8 cos1 = 0;
9169   u8 cos2 = 0;
9170   u8 dot1q = 0;
9171   u8 dot1ad = 0;
9172   int len = 14;
9173
9174   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9175     {
9176       if (unformat (input, "src"))
9177         src = 1;
9178       else if (unformat (input, "dst"))
9179         dst = 1;
9180       else if (unformat (input, "proto"))
9181         proto = 1;
9182       else if (unformat (input, "tag1"))
9183         tag1 = 1;
9184       else if (unformat (input, "tag2"))
9185         tag2 = 1;
9186       else if (unformat (input, "ignore-tag1"))
9187         ignore_tag1 = 1;
9188       else if (unformat (input, "ignore-tag2"))
9189         ignore_tag2 = 1;
9190       else if (unformat (input, "cos1"))
9191         cos1 = 1;
9192       else if (unformat (input, "cos2"))
9193         cos2 = 1;
9194       else if (unformat (input, "dot1q"))
9195         dot1q = 1;
9196       else if (unformat (input, "dot1ad"))
9197         dot1ad = 1;
9198       else
9199         break;
9200     }
9201   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9202        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9203     return 0;
9204
9205   if (tag1 || ignore_tag1 || cos1 || dot1q)
9206     len = 18;
9207   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9208     len = 22;
9209
9210   vec_validate (mask, len - 1);
9211
9212   if (dst)
9213     memset (mask, 0xff, 6);
9214
9215   if (src)
9216     memset (mask + 6, 0xff, 6);
9217
9218   if (tag2 || dot1ad)
9219     {
9220       /* inner vlan tag */
9221       if (tag2)
9222         {
9223           mask[19] = 0xff;
9224           mask[18] = 0x0f;
9225         }
9226       if (cos2)
9227         mask[18] |= 0xe0;
9228       if (proto)
9229         mask[21] = mask[20] = 0xff;
9230       if (tag1)
9231         {
9232           mask[15] = 0xff;
9233           mask[14] = 0x0f;
9234         }
9235       if (cos1)
9236         mask[14] |= 0xe0;
9237       *maskp = mask;
9238       return 1;
9239     }
9240   if (tag1 | dot1q)
9241     {
9242       if (tag1)
9243         {
9244           mask[15] = 0xff;
9245           mask[14] = 0x0f;
9246         }
9247       if (cos1)
9248         mask[14] |= 0xe0;
9249       if (proto)
9250         mask[16] = mask[17] = 0xff;
9251
9252       *maskp = mask;
9253       return 1;
9254     }
9255   if (cos2)
9256     mask[18] |= 0xe0;
9257   if (cos1)
9258     mask[14] |= 0xe0;
9259   if (proto)
9260     mask[12] = mask[13] = 0xff;
9261
9262   *maskp = mask;
9263   return 1;
9264 }
9265
9266 uword
9267 unformat_classify_mask (unformat_input_t * input, va_list * args)
9268 {
9269   u8 **maskp = va_arg (*args, u8 **);
9270   u32 *skipp = va_arg (*args, u32 *);
9271   u32 *matchp = va_arg (*args, u32 *);
9272   u32 match;
9273   u8 *mask = 0;
9274   u8 *l2 = 0;
9275   u8 *l3 = 0;
9276   u8 *l4 = 0;
9277   int i;
9278
9279   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9280     {
9281       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9282         ;
9283       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9284         ;
9285       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9286         ;
9287       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9288         ;
9289       else
9290         break;
9291     }
9292
9293   if (l4 && !l3)
9294     {
9295       vec_free (mask);
9296       vec_free (l2);
9297       vec_free (l4);
9298       return 0;
9299     }
9300
9301   if (mask || l2 || l3 || l4)
9302     {
9303       if (l2 || l3 || l4)
9304         {
9305           /* "With a free Ethernet header in every package" */
9306           if (l2 == 0)
9307             vec_validate (l2, 13);
9308           mask = l2;
9309           if (vec_len (l3))
9310             {
9311               vec_append (mask, l3);
9312               vec_free (l3);
9313             }
9314           if (vec_len (l4))
9315             {
9316               vec_append (mask, l4);
9317               vec_free (l4);
9318             }
9319         }
9320
9321       /* Scan forward looking for the first significant mask octet */
9322       for (i = 0; i < vec_len (mask); i++)
9323         if (mask[i])
9324           break;
9325
9326       /* compute (skip, match) params */
9327       *skipp = i / sizeof (u32x4);
9328       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9329
9330       /* Pad mask to an even multiple of the vector size */
9331       while (vec_len (mask) % sizeof (u32x4))
9332         vec_add1 (mask, 0);
9333
9334       match = vec_len (mask) / sizeof (u32x4);
9335
9336       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9337         {
9338           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9339           if (*tmp || *(tmp + 1))
9340             break;
9341           match--;
9342         }
9343       if (match == 0)
9344         clib_warning ("BUG: match 0");
9345
9346       _vec_len (mask) = match * sizeof (u32x4);
9347
9348       *matchp = match;
9349       *maskp = mask;
9350
9351       return 1;
9352     }
9353
9354   return 0;
9355 }
9356 #endif /* VPP_API_TEST_BUILTIN */
9357
9358 #define foreach_l2_next                         \
9359 _(drop, DROP)                                   \
9360 _(ethernet, ETHERNET_INPUT)                     \
9361 _(ip4, IP4_INPUT)                               \
9362 _(ip6, IP6_INPUT)
9363
9364 uword
9365 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9366 {
9367   u32 *miss_next_indexp = va_arg (*args, u32 *);
9368   u32 next_index = 0;
9369   u32 tmp;
9370
9371 #define _(n,N) \
9372   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9373   foreach_l2_next;
9374 #undef _
9375
9376   if (unformat (input, "%d", &tmp))
9377     {
9378       next_index = tmp;
9379       goto out;
9380     }
9381
9382   return 0;
9383
9384 out:
9385   *miss_next_indexp = next_index;
9386   return 1;
9387 }
9388
9389 #define foreach_ip_next                         \
9390 _(drop, DROP)                                   \
9391 _(local, LOCAL)                                 \
9392 _(rewrite, REWRITE)
9393
9394 uword
9395 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9396 {
9397   u32 *miss_next_indexp = va_arg (*args, u32 *);
9398   u32 next_index = 0;
9399   u32 tmp;
9400
9401 #define _(n,N) \
9402   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9403   foreach_ip_next;
9404 #undef _
9405
9406   if (unformat (input, "%d", &tmp))
9407     {
9408       next_index = tmp;
9409       goto out;
9410     }
9411
9412   return 0;
9413
9414 out:
9415   *miss_next_indexp = next_index;
9416   return 1;
9417 }
9418
9419 #define foreach_acl_next                        \
9420 _(deny, DENY)
9421
9422 uword
9423 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9424 {
9425   u32 *miss_next_indexp = va_arg (*args, u32 *);
9426   u32 next_index = 0;
9427   u32 tmp;
9428
9429 #define _(n,N) \
9430   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9431   foreach_acl_next;
9432 #undef _
9433
9434   if (unformat (input, "permit"))
9435     {
9436       next_index = ~0;
9437       goto out;
9438     }
9439   else if (unformat (input, "%d", &tmp))
9440     {
9441       next_index = tmp;
9442       goto out;
9443     }
9444
9445   return 0;
9446
9447 out:
9448   *miss_next_indexp = next_index;
9449   return 1;
9450 }
9451
9452 uword
9453 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9454 {
9455   u32 *r = va_arg (*args, u32 *);
9456
9457   if (unformat (input, "conform-color"))
9458     *r = POLICE_CONFORM;
9459   else if (unformat (input, "exceed-color"))
9460     *r = POLICE_EXCEED;
9461   else
9462     return 0;
9463
9464   return 1;
9465 }
9466
9467 static int
9468 api_classify_add_del_table (vat_main_t * vam)
9469 {
9470   unformat_input_t *i = vam->input;
9471   vl_api_classify_add_del_table_t *mp;
9472
9473   u32 nbuckets = 2;
9474   u32 skip = ~0;
9475   u32 match = ~0;
9476   int is_add = 1;
9477   int del_chain = 0;
9478   u32 table_index = ~0;
9479   u32 next_table_index = ~0;
9480   u32 miss_next_index = ~0;
9481   u32 memory_size = 32 << 20;
9482   u8 *mask = 0;
9483   u32 current_data_flag = 0;
9484   int current_data_offset = 0;
9485   int ret;
9486
9487   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9488     {
9489       if (unformat (i, "del"))
9490         is_add = 0;
9491       else if (unformat (i, "del-chain"))
9492         {
9493           is_add = 0;
9494           del_chain = 1;
9495         }
9496       else if (unformat (i, "buckets %d", &nbuckets))
9497         ;
9498       else if (unformat (i, "memory_size %d", &memory_size))
9499         ;
9500       else if (unformat (i, "skip %d", &skip))
9501         ;
9502       else if (unformat (i, "match %d", &match))
9503         ;
9504       else if (unformat (i, "table %d", &table_index))
9505         ;
9506       else if (unformat (i, "mask %U", unformat_classify_mask,
9507                          &mask, &skip, &match))
9508         ;
9509       else if (unformat (i, "next-table %d", &next_table_index))
9510         ;
9511       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
9512                          &miss_next_index))
9513         ;
9514       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
9515                          &miss_next_index))
9516         ;
9517       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
9518                          &miss_next_index))
9519         ;
9520       else if (unformat (i, "current-data-flag %d", &current_data_flag))
9521         ;
9522       else if (unformat (i, "current-data-offset %d", &current_data_offset))
9523         ;
9524       else
9525         break;
9526     }
9527
9528   if (is_add && mask == 0)
9529     {
9530       errmsg ("Mask required");
9531       return -99;
9532     }
9533
9534   if (is_add && skip == ~0)
9535     {
9536       errmsg ("skip count required");
9537       return -99;
9538     }
9539
9540   if (is_add && match == ~0)
9541     {
9542       errmsg ("match count required");
9543       return -99;
9544     }
9545
9546   if (!is_add && table_index == ~0)
9547     {
9548       errmsg ("table index required for delete");
9549       return -99;
9550     }
9551
9552   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
9553
9554   mp->is_add = is_add;
9555   mp->del_chain = del_chain;
9556   mp->table_index = ntohl (table_index);
9557   mp->nbuckets = ntohl (nbuckets);
9558   mp->memory_size = ntohl (memory_size);
9559   mp->skip_n_vectors = ntohl (skip);
9560   mp->match_n_vectors = ntohl (match);
9561   mp->next_table_index = ntohl (next_table_index);
9562   mp->miss_next_index = ntohl (miss_next_index);
9563   mp->current_data_flag = ntohl (current_data_flag);
9564   mp->current_data_offset = ntohl (current_data_offset);
9565   clib_memcpy (mp->mask, mask, vec_len (mask));
9566
9567   vec_free (mask);
9568
9569   S (mp);
9570   W (ret);
9571   return ret;
9572 }
9573
9574 #if VPP_API_TEST_BUILTIN == 0
9575 uword
9576 unformat_l4_match (unformat_input_t * input, va_list * args)
9577 {
9578   u8 **matchp = va_arg (*args, u8 **);
9579
9580   u8 *proto_header = 0;
9581   int src_port = 0;
9582   int dst_port = 0;
9583
9584   tcpudp_header_t h;
9585
9586   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9587     {
9588       if (unformat (input, "src_port %d", &src_port))
9589         ;
9590       else if (unformat (input, "dst_port %d", &dst_port))
9591         ;
9592       else
9593         return 0;
9594     }
9595
9596   h.src_port = clib_host_to_net_u16 (src_port);
9597   h.dst_port = clib_host_to_net_u16 (dst_port);
9598   vec_validate (proto_header, sizeof (h) - 1);
9599   memcpy (proto_header, &h, sizeof (h));
9600
9601   *matchp = proto_header;
9602
9603   return 1;
9604 }
9605
9606 uword
9607 unformat_ip4_match (unformat_input_t * input, va_list * args)
9608 {
9609   u8 **matchp = va_arg (*args, u8 **);
9610   u8 *match = 0;
9611   ip4_header_t *ip;
9612   int version = 0;
9613   u32 version_val;
9614   int hdr_length = 0;
9615   u32 hdr_length_val;
9616   int src = 0, dst = 0;
9617   ip4_address_t src_val, dst_val;
9618   int proto = 0;
9619   u32 proto_val;
9620   int tos = 0;
9621   u32 tos_val;
9622   int length = 0;
9623   u32 length_val;
9624   int fragment_id = 0;
9625   u32 fragment_id_val;
9626   int ttl = 0;
9627   int ttl_val;
9628   int checksum = 0;
9629   u32 checksum_val;
9630
9631   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9632     {
9633       if (unformat (input, "version %d", &version_val))
9634         version = 1;
9635       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9636         hdr_length = 1;
9637       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9638         src = 1;
9639       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9640         dst = 1;
9641       else if (unformat (input, "proto %d", &proto_val))
9642         proto = 1;
9643       else if (unformat (input, "tos %d", &tos_val))
9644         tos = 1;
9645       else if (unformat (input, "length %d", &length_val))
9646         length = 1;
9647       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9648         fragment_id = 1;
9649       else if (unformat (input, "ttl %d", &ttl_val))
9650         ttl = 1;
9651       else if (unformat (input, "checksum %d", &checksum_val))
9652         checksum = 1;
9653       else
9654         break;
9655     }
9656
9657   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9658       + ttl + checksum == 0)
9659     return 0;
9660
9661   /*
9662    * Aligned because we use the real comparison functions
9663    */
9664   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9665
9666   ip = (ip4_header_t *) match;
9667
9668   /* These are realistically matched in practice */
9669   if (src)
9670     ip->src_address.as_u32 = src_val.as_u32;
9671
9672   if (dst)
9673     ip->dst_address.as_u32 = dst_val.as_u32;
9674
9675   if (proto)
9676     ip->protocol = proto_val;
9677
9678
9679   /* These are not, but they're included for completeness */
9680   if (version)
9681     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9682
9683   if (hdr_length)
9684     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9685
9686   if (tos)
9687     ip->tos = tos_val;
9688
9689   if (length)
9690     ip->length = clib_host_to_net_u16 (length_val);
9691
9692   if (ttl)
9693     ip->ttl = ttl_val;
9694
9695   if (checksum)
9696     ip->checksum = clib_host_to_net_u16 (checksum_val);
9697
9698   *matchp = match;
9699   return 1;
9700 }
9701
9702 uword
9703 unformat_ip6_match (unformat_input_t * input, va_list * args)
9704 {
9705   u8 **matchp = va_arg (*args, u8 **);
9706   u8 *match = 0;
9707   ip6_header_t *ip;
9708   int version = 0;
9709   u32 version_val;
9710   u8 traffic_class = 0;
9711   u32 traffic_class_val = 0;
9712   u8 flow_label = 0;
9713   u8 flow_label_val;
9714   int src = 0, dst = 0;
9715   ip6_address_t src_val, dst_val;
9716   int proto = 0;
9717   u32 proto_val;
9718   int payload_length = 0;
9719   u32 payload_length_val;
9720   int hop_limit = 0;
9721   int hop_limit_val;
9722   u32 ip_version_traffic_class_and_flow_label;
9723
9724   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9725     {
9726       if (unformat (input, "version %d", &version_val))
9727         version = 1;
9728       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9729         traffic_class = 1;
9730       else if (unformat (input, "flow_label %d", &flow_label_val))
9731         flow_label = 1;
9732       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9733         src = 1;
9734       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9735         dst = 1;
9736       else if (unformat (input, "proto %d", &proto_val))
9737         proto = 1;
9738       else if (unformat (input, "payload_length %d", &payload_length_val))
9739         payload_length = 1;
9740       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9741         hop_limit = 1;
9742       else
9743         break;
9744     }
9745
9746   if (version + traffic_class + flow_label + src + dst + proto +
9747       payload_length + hop_limit == 0)
9748     return 0;
9749
9750   /*
9751    * Aligned because we use the real comparison functions
9752    */
9753   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9754
9755   ip = (ip6_header_t *) match;
9756
9757   if (src)
9758     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9759
9760   if (dst)
9761     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9762
9763   if (proto)
9764     ip->protocol = proto_val;
9765
9766   ip_version_traffic_class_and_flow_label = 0;
9767
9768   if (version)
9769     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9770
9771   if (traffic_class)
9772     ip_version_traffic_class_and_flow_label |=
9773       (traffic_class_val & 0xFF) << 20;
9774
9775   if (flow_label)
9776     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9777
9778   ip->ip_version_traffic_class_and_flow_label =
9779     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9780
9781   if (payload_length)
9782     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9783
9784   if (hop_limit)
9785     ip->hop_limit = hop_limit_val;
9786
9787   *matchp = match;
9788   return 1;
9789 }
9790
9791 uword
9792 unformat_l3_match (unformat_input_t * input, va_list * args)
9793 {
9794   u8 **matchp = va_arg (*args, u8 **);
9795
9796   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9797     {
9798       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9799         return 1;
9800       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9801         return 1;
9802       else
9803         break;
9804     }
9805   return 0;
9806 }
9807
9808 uword
9809 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9810 {
9811   u8 *tagp = va_arg (*args, u8 *);
9812   u32 tag;
9813
9814   if (unformat (input, "%d", &tag))
9815     {
9816       tagp[0] = (tag >> 8) & 0x0F;
9817       tagp[1] = tag & 0xFF;
9818       return 1;
9819     }
9820
9821   return 0;
9822 }
9823
9824 uword
9825 unformat_l2_match (unformat_input_t * input, va_list * args)
9826 {
9827   u8 **matchp = va_arg (*args, u8 **);
9828   u8 *match = 0;
9829   u8 src = 0;
9830   u8 src_val[6];
9831   u8 dst = 0;
9832   u8 dst_val[6];
9833   u8 proto = 0;
9834   u16 proto_val;
9835   u8 tag1 = 0;
9836   u8 tag1_val[2];
9837   u8 tag2 = 0;
9838   u8 tag2_val[2];
9839   int len = 14;
9840   u8 ignore_tag1 = 0;
9841   u8 ignore_tag2 = 0;
9842   u8 cos1 = 0;
9843   u8 cos2 = 0;
9844   u32 cos1_val = 0;
9845   u32 cos2_val = 0;
9846
9847   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9848     {
9849       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9850         src = 1;
9851       else
9852         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9853         dst = 1;
9854       else if (unformat (input, "proto %U",
9855                          unformat_ethernet_type_host_byte_order, &proto_val))
9856         proto = 1;
9857       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9858         tag1 = 1;
9859       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9860         tag2 = 1;
9861       else if (unformat (input, "ignore-tag1"))
9862         ignore_tag1 = 1;
9863       else if (unformat (input, "ignore-tag2"))
9864         ignore_tag2 = 1;
9865       else if (unformat (input, "cos1 %d", &cos1_val))
9866         cos1 = 1;
9867       else if (unformat (input, "cos2 %d", &cos2_val))
9868         cos2 = 1;
9869       else
9870         break;
9871     }
9872   if ((src + dst + proto + tag1 + tag2 +
9873        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9874     return 0;
9875
9876   if (tag1 || ignore_tag1 || cos1)
9877     len = 18;
9878   if (tag2 || ignore_tag2 || cos2)
9879     len = 22;
9880
9881   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9882
9883   if (dst)
9884     clib_memcpy (match, dst_val, 6);
9885
9886   if (src)
9887     clib_memcpy (match + 6, src_val, 6);
9888
9889   if (tag2)
9890     {
9891       /* inner vlan tag */
9892       match[19] = tag2_val[1];
9893       match[18] = tag2_val[0];
9894       if (cos2)
9895         match[18] |= (cos2_val & 0x7) << 5;
9896       if (proto)
9897         {
9898           match[21] = proto_val & 0xff;
9899           match[20] = proto_val >> 8;
9900         }
9901       if (tag1)
9902         {
9903           match[15] = tag1_val[1];
9904           match[14] = tag1_val[0];
9905         }
9906       if (cos1)
9907         match[14] |= (cos1_val & 0x7) << 5;
9908       *matchp = match;
9909       return 1;
9910     }
9911   if (tag1)
9912     {
9913       match[15] = tag1_val[1];
9914       match[14] = tag1_val[0];
9915       if (proto)
9916         {
9917           match[17] = proto_val & 0xff;
9918           match[16] = proto_val >> 8;
9919         }
9920       if (cos1)
9921         match[14] |= (cos1_val & 0x7) << 5;
9922
9923       *matchp = match;
9924       return 1;
9925     }
9926   if (cos2)
9927     match[18] |= (cos2_val & 0x7) << 5;
9928   if (cos1)
9929     match[14] |= (cos1_val & 0x7) << 5;
9930   if (proto)
9931     {
9932       match[13] = proto_val & 0xff;
9933       match[12] = proto_val >> 8;
9934     }
9935
9936   *matchp = match;
9937   return 1;
9938 }
9939 #endif
9940
9941 uword
9942 api_unformat_classify_match (unformat_input_t * input, va_list * args)
9943 {
9944   u8 **matchp = va_arg (*args, u8 **);
9945   u32 skip_n_vectors = va_arg (*args, u32);
9946   u32 match_n_vectors = va_arg (*args, u32);
9947
9948   u8 *match = 0;
9949   u8 *l2 = 0;
9950   u8 *l3 = 0;
9951   u8 *l4 = 0;
9952
9953   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9954     {
9955       if (unformat (input, "hex %U", unformat_hex_string, &match))
9956         ;
9957       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9958         ;
9959       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9960         ;
9961       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9962         ;
9963       else
9964         break;
9965     }
9966
9967   if (l4 && !l3)
9968     {
9969       vec_free (match);
9970       vec_free (l2);
9971       vec_free (l4);
9972       return 0;
9973     }
9974
9975   if (match || l2 || l3 || l4)
9976     {
9977       if (l2 || l3 || l4)
9978         {
9979           /* "Win a free Ethernet header in every packet" */
9980           if (l2 == 0)
9981             vec_validate_aligned (l2, 13, sizeof (u32x4));
9982           match = l2;
9983           if (vec_len (l3))
9984             {
9985               vec_append_aligned (match, l3, sizeof (u32x4));
9986               vec_free (l3);
9987             }
9988           if (vec_len (l4))
9989             {
9990               vec_append_aligned (match, l4, sizeof (u32x4));
9991               vec_free (l4);
9992             }
9993         }
9994
9995       /* Make sure the vector is big enough even if key is all 0's */
9996       vec_validate_aligned
9997         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9998          sizeof (u32x4));
9999
10000       /* Set size, include skipped vectors */
10001       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10002
10003       *matchp = match;
10004
10005       return 1;
10006     }
10007
10008   return 0;
10009 }
10010
10011 static int
10012 api_classify_add_del_session (vat_main_t * vam)
10013 {
10014   unformat_input_t *i = vam->input;
10015   vl_api_classify_add_del_session_t *mp;
10016   int is_add = 1;
10017   u32 table_index = ~0;
10018   u32 hit_next_index = ~0;
10019   u32 opaque_index = ~0;
10020   u8 *match = 0;
10021   i32 advance = 0;
10022   u32 skip_n_vectors = 0;
10023   u32 match_n_vectors = 0;
10024   u32 action = 0;
10025   u32 metadata = 0;
10026   int ret;
10027
10028   /*
10029    * Warning: you have to supply skip_n and match_n
10030    * because the API client cant simply look at the classify
10031    * table object.
10032    */
10033
10034   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10035     {
10036       if (unformat (i, "del"))
10037         is_add = 0;
10038       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10039                          &hit_next_index))
10040         ;
10041       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10042                          &hit_next_index))
10043         ;
10044       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10045                          &hit_next_index))
10046         ;
10047       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10048         ;
10049       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10050         ;
10051       else if (unformat (i, "opaque-index %d", &opaque_index))
10052         ;
10053       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10054         ;
10055       else if (unformat (i, "match_n %d", &match_n_vectors))
10056         ;
10057       else if (unformat (i, "match %U", api_unformat_classify_match,
10058                          &match, skip_n_vectors, match_n_vectors))
10059         ;
10060       else if (unformat (i, "advance %d", &advance))
10061         ;
10062       else if (unformat (i, "table-index %d", &table_index))
10063         ;
10064       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10065         action = 1;
10066       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10067         action = 2;
10068       else if (unformat (i, "action %d", &action))
10069         ;
10070       else if (unformat (i, "metadata %d", &metadata))
10071         ;
10072       else
10073         break;
10074     }
10075
10076   if (table_index == ~0)
10077     {
10078       errmsg ("Table index required");
10079       return -99;
10080     }
10081
10082   if (is_add && match == 0)
10083     {
10084       errmsg ("Match value required");
10085       return -99;
10086     }
10087
10088   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10089
10090   mp->is_add = is_add;
10091   mp->table_index = ntohl (table_index);
10092   mp->hit_next_index = ntohl (hit_next_index);
10093   mp->opaque_index = ntohl (opaque_index);
10094   mp->advance = ntohl (advance);
10095   mp->action = action;
10096   mp->metadata = ntohl (metadata);
10097   clib_memcpy (mp->match, match, vec_len (match));
10098   vec_free (match);
10099
10100   S (mp);
10101   W (ret);
10102   return ret;
10103 }
10104
10105 static int
10106 api_classify_set_interface_ip_table (vat_main_t * vam)
10107 {
10108   unformat_input_t *i = vam->input;
10109   vl_api_classify_set_interface_ip_table_t *mp;
10110   u32 sw_if_index;
10111   int sw_if_index_set;
10112   u32 table_index = ~0;
10113   u8 is_ipv6 = 0;
10114   int ret;
10115
10116   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10117     {
10118       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10119         sw_if_index_set = 1;
10120       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10121         sw_if_index_set = 1;
10122       else if (unformat (i, "table %d", &table_index))
10123         ;
10124       else
10125         {
10126           clib_warning ("parse error '%U'", format_unformat_error, i);
10127           return -99;
10128         }
10129     }
10130
10131   if (sw_if_index_set == 0)
10132     {
10133       errmsg ("missing interface name or sw_if_index");
10134       return -99;
10135     }
10136
10137
10138   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10139
10140   mp->sw_if_index = ntohl (sw_if_index);
10141   mp->table_index = ntohl (table_index);
10142   mp->is_ipv6 = is_ipv6;
10143
10144   S (mp);
10145   W (ret);
10146   return ret;
10147 }
10148
10149 static int
10150 api_classify_set_interface_l2_tables (vat_main_t * vam)
10151 {
10152   unformat_input_t *i = vam->input;
10153   vl_api_classify_set_interface_l2_tables_t *mp;
10154   u32 sw_if_index;
10155   int sw_if_index_set;
10156   u32 ip4_table_index = ~0;
10157   u32 ip6_table_index = ~0;
10158   u32 other_table_index = ~0;
10159   u32 is_input = 1;
10160   int ret;
10161
10162   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10163     {
10164       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10165         sw_if_index_set = 1;
10166       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10167         sw_if_index_set = 1;
10168       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10169         ;
10170       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10171         ;
10172       else if (unformat (i, "other-table %d", &other_table_index))
10173         ;
10174       else if (unformat (i, "is-input %d", &is_input))
10175         ;
10176       else
10177         {
10178           clib_warning ("parse error '%U'", format_unformat_error, i);
10179           return -99;
10180         }
10181     }
10182
10183   if (sw_if_index_set == 0)
10184     {
10185       errmsg ("missing interface name or sw_if_index");
10186       return -99;
10187     }
10188
10189
10190   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10191
10192   mp->sw_if_index = ntohl (sw_if_index);
10193   mp->ip4_table_index = ntohl (ip4_table_index);
10194   mp->ip6_table_index = ntohl (ip6_table_index);
10195   mp->other_table_index = ntohl (other_table_index);
10196   mp->is_input = (u8) is_input;
10197
10198   S (mp);
10199   W (ret);
10200   return ret;
10201 }
10202
10203 static int
10204 api_set_ipfix_exporter (vat_main_t * vam)
10205 {
10206   unformat_input_t *i = vam->input;
10207   vl_api_set_ipfix_exporter_t *mp;
10208   ip4_address_t collector_address;
10209   u8 collector_address_set = 0;
10210   u32 collector_port = ~0;
10211   ip4_address_t src_address;
10212   u8 src_address_set = 0;
10213   u32 vrf_id = ~0;
10214   u32 path_mtu = ~0;
10215   u32 template_interval = ~0;
10216   u8 udp_checksum = 0;
10217   int ret;
10218
10219   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10220     {
10221       if (unformat (i, "collector_address %U", unformat_ip4_address,
10222                     &collector_address))
10223         collector_address_set = 1;
10224       else if (unformat (i, "collector_port %d", &collector_port))
10225         ;
10226       else if (unformat (i, "src_address %U", unformat_ip4_address,
10227                          &src_address))
10228         src_address_set = 1;
10229       else if (unformat (i, "vrf_id %d", &vrf_id))
10230         ;
10231       else if (unformat (i, "path_mtu %d", &path_mtu))
10232         ;
10233       else if (unformat (i, "template_interval %d", &template_interval))
10234         ;
10235       else if (unformat (i, "udp_checksum"))
10236         udp_checksum = 1;
10237       else
10238         break;
10239     }
10240
10241   if (collector_address_set == 0)
10242     {
10243       errmsg ("collector_address required");
10244       return -99;
10245     }
10246
10247   if (src_address_set == 0)
10248     {
10249       errmsg ("src_address required");
10250       return -99;
10251     }
10252
10253   M (SET_IPFIX_EXPORTER, mp);
10254
10255   memcpy (mp->collector_address, collector_address.data,
10256           sizeof (collector_address.data));
10257   mp->collector_port = htons ((u16) collector_port);
10258   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
10259   mp->vrf_id = htonl (vrf_id);
10260   mp->path_mtu = htonl (path_mtu);
10261   mp->template_interval = htonl (template_interval);
10262   mp->udp_checksum = udp_checksum;
10263
10264   S (mp);
10265   W (ret);
10266   return ret;
10267 }
10268
10269 static int
10270 api_set_ipfix_classify_stream (vat_main_t * vam)
10271 {
10272   unformat_input_t *i = vam->input;
10273   vl_api_set_ipfix_classify_stream_t *mp;
10274   u32 domain_id = 0;
10275   u32 src_port = UDP_DST_PORT_ipfix;
10276   int ret;
10277
10278   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10279     {
10280       if (unformat (i, "domain %d", &domain_id))
10281         ;
10282       else if (unformat (i, "src_port %d", &src_port))
10283         ;
10284       else
10285         {
10286           errmsg ("unknown input `%U'", format_unformat_error, i);
10287           return -99;
10288         }
10289     }
10290
10291   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10292
10293   mp->domain_id = htonl (domain_id);
10294   mp->src_port = htons ((u16) src_port);
10295
10296   S (mp);
10297   W (ret);
10298   return ret;
10299 }
10300
10301 static int
10302 api_ipfix_classify_table_add_del (vat_main_t * vam)
10303 {
10304   unformat_input_t *i = vam->input;
10305   vl_api_ipfix_classify_table_add_del_t *mp;
10306   int is_add = -1;
10307   u32 classify_table_index = ~0;
10308   u8 ip_version = 0;
10309   u8 transport_protocol = 255;
10310   int ret;
10311
10312   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10313     {
10314       if (unformat (i, "add"))
10315         is_add = 1;
10316       else if (unformat (i, "del"))
10317         is_add = 0;
10318       else if (unformat (i, "table %d", &classify_table_index))
10319         ;
10320       else if (unformat (i, "ip4"))
10321         ip_version = 4;
10322       else if (unformat (i, "ip6"))
10323         ip_version = 6;
10324       else if (unformat (i, "tcp"))
10325         transport_protocol = 6;
10326       else if (unformat (i, "udp"))
10327         transport_protocol = 17;
10328       else
10329         {
10330           errmsg ("unknown input `%U'", format_unformat_error, i);
10331           return -99;
10332         }
10333     }
10334
10335   if (is_add == -1)
10336     {
10337       errmsg ("expecting: add|del");
10338       return -99;
10339     }
10340   if (classify_table_index == ~0)
10341     {
10342       errmsg ("classifier table not specified");
10343       return -99;
10344     }
10345   if (ip_version == 0)
10346     {
10347       errmsg ("IP version not specified");
10348       return -99;
10349     }
10350
10351   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10352
10353   mp->is_add = is_add;
10354   mp->table_id = htonl (classify_table_index);
10355   mp->ip_version = ip_version;
10356   mp->transport_protocol = transport_protocol;
10357
10358   S (mp);
10359   W (ret);
10360   return ret;
10361 }
10362
10363 static int
10364 api_get_node_index (vat_main_t * vam)
10365 {
10366   unformat_input_t *i = vam->input;
10367   vl_api_get_node_index_t *mp;
10368   u8 *name = 0;
10369   int ret;
10370
10371   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10372     {
10373       if (unformat (i, "node %s", &name))
10374         ;
10375       else
10376         break;
10377     }
10378   if (name == 0)
10379     {
10380       errmsg ("node name required");
10381       return -99;
10382     }
10383   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10384     {
10385       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10386       return -99;
10387     }
10388
10389   M (GET_NODE_INDEX, mp);
10390   clib_memcpy (mp->node_name, name, vec_len (name));
10391   vec_free (name);
10392
10393   S (mp);
10394   W (ret);
10395   return ret;
10396 }
10397
10398 static int
10399 api_get_next_index (vat_main_t * vam)
10400 {
10401   unformat_input_t *i = vam->input;
10402   vl_api_get_next_index_t *mp;
10403   u8 *node_name = 0, *next_node_name = 0;
10404   int ret;
10405
10406   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10407     {
10408       if (unformat (i, "node-name %s", &node_name))
10409         ;
10410       else if (unformat (i, "next-node-name %s", &next_node_name))
10411         break;
10412     }
10413
10414   if (node_name == 0)
10415     {
10416       errmsg ("node name required");
10417       return -99;
10418     }
10419   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10420     {
10421       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10422       return -99;
10423     }
10424
10425   if (next_node_name == 0)
10426     {
10427       errmsg ("next node name required");
10428       return -99;
10429     }
10430   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10431     {
10432       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10433       return -99;
10434     }
10435
10436   M (GET_NEXT_INDEX, mp);
10437   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10438   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10439   vec_free (node_name);
10440   vec_free (next_node_name);
10441
10442   S (mp);
10443   W (ret);
10444   return ret;
10445 }
10446
10447 static int
10448 api_add_node_next (vat_main_t * vam)
10449 {
10450   unformat_input_t *i = vam->input;
10451   vl_api_add_node_next_t *mp;
10452   u8 *name = 0;
10453   u8 *next = 0;
10454   int ret;
10455
10456   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10457     {
10458       if (unformat (i, "node %s", &name))
10459         ;
10460       else if (unformat (i, "next %s", &next))
10461         ;
10462       else
10463         break;
10464     }
10465   if (name == 0)
10466     {
10467       errmsg ("node name required");
10468       return -99;
10469     }
10470   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10471     {
10472       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10473       return -99;
10474     }
10475   if (next == 0)
10476     {
10477       errmsg ("next node required");
10478       return -99;
10479     }
10480   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10481     {
10482       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10483       return -99;
10484     }
10485
10486   M (ADD_NODE_NEXT, mp);
10487   clib_memcpy (mp->node_name, name, vec_len (name));
10488   clib_memcpy (mp->next_name, next, vec_len (next));
10489   vec_free (name);
10490   vec_free (next);
10491
10492   S (mp);
10493   W (ret);
10494   return ret;
10495 }
10496
10497 static int
10498 api_l2tpv3_create_tunnel (vat_main_t * vam)
10499 {
10500   unformat_input_t *i = vam->input;
10501   ip6_address_t client_address, our_address;
10502   int client_address_set = 0;
10503   int our_address_set = 0;
10504   u32 local_session_id = 0;
10505   u32 remote_session_id = 0;
10506   u64 local_cookie = 0;
10507   u64 remote_cookie = 0;
10508   u8 l2_sublayer_present = 0;
10509   vl_api_l2tpv3_create_tunnel_t *mp;
10510   int ret;
10511
10512   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10513     {
10514       if (unformat (i, "client_address %U", unformat_ip6_address,
10515                     &client_address))
10516         client_address_set = 1;
10517       else if (unformat (i, "our_address %U", unformat_ip6_address,
10518                          &our_address))
10519         our_address_set = 1;
10520       else if (unformat (i, "local_session_id %d", &local_session_id))
10521         ;
10522       else if (unformat (i, "remote_session_id %d", &remote_session_id))
10523         ;
10524       else if (unformat (i, "local_cookie %lld", &local_cookie))
10525         ;
10526       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10527         ;
10528       else if (unformat (i, "l2-sublayer-present"))
10529         l2_sublayer_present = 1;
10530       else
10531         break;
10532     }
10533
10534   if (client_address_set == 0)
10535     {
10536       errmsg ("client_address required");
10537       return -99;
10538     }
10539
10540   if (our_address_set == 0)
10541     {
10542       errmsg ("our_address required");
10543       return -99;
10544     }
10545
10546   M (L2TPV3_CREATE_TUNNEL, mp);
10547
10548   clib_memcpy (mp->client_address, client_address.as_u8,
10549                sizeof (mp->client_address));
10550
10551   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10552
10553   mp->local_session_id = ntohl (local_session_id);
10554   mp->remote_session_id = ntohl (remote_session_id);
10555   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10556   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10557   mp->l2_sublayer_present = l2_sublayer_present;
10558   mp->is_ipv6 = 1;
10559
10560   S (mp);
10561   W (ret);
10562   return ret;
10563 }
10564
10565 static int
10566 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10567 {
10568   unformat_input_t *i = vam->input;
10569   u32 sw_if_index;
10570   u8 sw_if_index_set = 0;
10571   u64 new_local_cookie = 0;
10572   u64 new_remote_cookie = 0;
10573   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10574   int ret;
10575
10576   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10577     {
10578       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10579         sw_if_index_set = 1;
10580       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10581         sw_if_index_set = 1;
10582       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10583         ;
10584       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10585         ;
10586       else
10587         break;
10588     }
10589
10590   if (sw_if_index_set == 0)
10591     {
10592       errmsg ("missing interface name or sw_if_index");
10593       return -99;
10594     }
10595
10596   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
10597
10598   mp->sw_if_index = ntohl (sw_if_index);
10599   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10600   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10601
10602   S (mp);
10603   W (ret);
10604   return ret;
10605 }
10606
10607 static int
10608 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10609 {
10610   unformat_input_t *i = vam->input;
10611   vl_api_l2tpv3_interface_enable_disable_t *mp;
10612   u32 sw_if_index;
10613   u8 sw_if_index_set = 0;
10614   u8 enable_disable = 1;
10615   int ret;
10616
10617   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10618     {
10619       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10620         sw_if_index_set = 1;
10621       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10622         sw_if_index_set = 1;
10623       else if (unformat (i, "enable"))
10624         enable_disable = 1;
10625       else if (unformat (i, "disable"))
10626         enable_disable = 0;
10627       else
10628         break;
10629     }
10630
10631   if (sw_if_index_set == 0)
10632     {
10633       errmsg ("missing interface name or sw_if_index");
10634       return -99;
10635     }
10636
10637   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
10638
10639   mp->sw_if_index = ntohl (sw_if_index);
10640   mp->enable_disable = enable_disable;
10641
10642   S (mp);
10643   W (ret);
10644   return ret;
10645 }
10646
10647 static int
10648 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10649 {
10650   unformat_input_t *i = vam->input;
10651   vl_api_l2tpv3_set_lookup_key_t *mp;
10652   u8 key = ~0;
10653   int ret;
10654
10655   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10656     {
10657       if (unformat (i, "lookup_v6_src"))
10658         key = L2T_LOOKUP_SRC_ADDRESS;
10659       else if (unformat (i, "lookup_v6_dst"))
10660         key = L2T_LOOKUP_DST_ADDRESS;
10661       else if (unformat (i, "lookup_session_id"))
10662         key = L2T_LOOKUP_SESSION_ID;
10663       else
10664         break;
10665     }
10666
10667   if (key == (u8) ~ 0)
10668     {
10669       errmsg ("l2tp session lookup key unset");
10670       return -99;
10671     }
10672
10673   M (L2TPV3_SET_LOOKUP_KEY, mp);
10674
10675   mp->key = key;
10676
10677   S (mp);
10678   W (ret);
10679   return ret;
10680 }
10681
10682 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10683   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10684 {
10685   vat_main_t *vam = &vat_main;
10686
10687   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10688          format_ip6_address, mp->our_address,
10689          format_ip6_address, mp->client_address,
10690          clib_net_to_host_u32 (mp->sw_if_index));
10691
10692   print (vam->ofp,
10693          "   local cookies %016llx %016llx remote cookie %016llx",
10694          clib_net_to_host_u64 (mp->local_cookie[0]),
10695          clib_net_to_host_u64 (mp->local_cookie[1]),
10696          clib_net_to_host_u64 (mp->remote_cookie));
10697
10698   print (vam->ofp, "   local session-id %d remote session-id %d",
10699          clib_net_to_host_u32 (mp->local_session_id),
10700          clib_net_to_host_u32 (mp->remote_session_id));
10701
10702   print (vam->ofp, "   l2 specific sublayer %s\n",
10703          mp->l2_sublayer_present ? "preset" : "absent");
10704
10705 }
10706
10707 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10708   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10709 {
10710   vat_main_t *vam = &vat_main;
10711   vat_json_node_t *node = NULL;
10712   struct in6_addr addr;
10713
10714   if (VAT_JSON_ARRAY != vam->json_tree.type)
10715     {
10716       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10717       vat_json_init_array (&vam->json_tree);
10718     }
10719   node = vat_json_array_add (&vam->json_tree);
10720
10721   vat_json_init_object (node);
10722
10723   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10724   vat_json_object_add_ip6 (node, "our_address", addr);
10725   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10726   vat_json_object_add_ip6 (node, "client_address", addr);
10727
10728   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10729   vat_json_init_array (lc);
10730   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10731   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10732   vat_json_object_add_uint (node, "remote_cookie",
10733                             clib_net_to_host_u64 (mp->remote_cookie));
10734
10735   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10736   vat_json_object_add_uint (node, "local_session_id",
10737                             clib_net_to_host_u32 (mp->local_session_id));
10738   vat_json_object_add_uint (node, "remote_session_id",
10739                             clib_net_to_host_u32 (mp->remote_session_id));
10740   vat_json_object_add_string_copy (node, "l2_sublayer",
10741                                    mp->l2_sublayer_present ? (u8 *) "present"
10742                                    : (u8 *) "absent");
10743 }
10744
10745 static int
10746 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10747 {
10748   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10749   vl_api_control_ping_t *mp_ping;
10750   int ret;
10751
10752   /* Get list of l2tpv3-tunnel interfaces */
10753   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
10754   S (mp);
10755
10756   /* Use a control ping for synchronization */
10757   M (CONTROL_PING, mp_ping);
10758   S (mp_ping);
10759
10760   W (ret);
10761   return ret;
10762 }
10763
10764
10765 static void vl_api_sw_interface_tap_details_t_handler
10766   (vl_api_sw_interface_tap_details_t * mp)
10767 {
10768   vat_main_t *vam = &vat_main;
10769
10770   print (vam->ofp, "%-16s %d",
10771          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10772 }
10773
10774 static void vl_api_sw_interface_tap_details_t_handler_json
10775   (vl_api_sw_interface_tap_details_t * mp)
10776 {
10777   vat_main_t *vam = &vat_main;
10778   vat_json_node_t *node = NULL;
10779
10780   if (VAT_JSON_ARRAY != vam->json_tree.type)
10781     {
10782       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10783       vat_json_init_array (&vam->json_tree);
10784     }
10785   node = vat_json_array_add (&vam->json_tree);
10786
10787   vat_json_init_object (node);
10788   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10789   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10790 }
10791
10792 static int
10793 api_sw_interface_tap_dump (vat_main_t * vam)
10794 {
10795   vl_api_sw_interface_tap_dump_t *mp;
10796   vl_api_control_ping_t *mp_ping;
10797   int ret;
10798
10799   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10800   /* Get list of tap interfaces */
10801   M (SW_INTERFACE_TAP_DUMP, mp);
10802   S (mp);
10803
10804   /* Use a control ping for synchronization */
10805   M (CONTROL_PING, mp_ping);
10806   S (mp_ping);
10807
10808   W (ret);
10809   return ret;
10810 }
10811
10812 static uword unformat_vxlan_decap_next
10813   (unformat_input_t * input, va_list * args)
10814 {
10815   u32 *result = va_arg (*args, u32 *);
10816   u32 tmp;
10817
10818   if (unformat (input, "l2"))
10819     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10820   else if (unformat (input, "%d", &tmp))
10821     *result = tmp;
10822   else
10823     return 0;
10824   return 1;
10825 }
10826
10827 static int
10828 api_vxlan_add_del_tunnel (vat_main_t * vam)
10829 {
10830   unformat_input_t *line_input = vam->input;
10831   vl_api_vxlan_add_del_tunnel_t *mp;
10832   ip46_address_t src, dst;
10833   u8 is_add = 1;
10834   u8 ipv4_set = 0, ipv6_set = 0;
10835   u8 src_set = 0;
10836   u8 dst_set = 0;
10837   u8 grp_set = 0;
10838   u32 mcast_sw_if_index = ~0;
10839   u32 encap_vrf_id = 0;
10840   u32 decap_next_index = ~0;
10841   u32 vni = 0;
10842   int ret;
10843
10844   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10845   memset (&src, 0, sizeof src);
10846   memset (&dst, 0, sizeof dst);
10847
10848   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10849     {
10850       if (unformat (line_input, "del"))
10851         is_add = 0;
10852       else
10853         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10854         {
10855           ipv4_set = 1;
10856           src_set = 1;
10857         }
10858       else
10859         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10860         {
10861           ipv4_set = 1;
10862           dst_set = 1;
10863         }
10864       else
10865         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10866         {
10867           ipv6_set = 1;
10868           src_set = 1;
10869         }
10870       else
10871         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10872         {
10873           ipv6_set = 1;
10874           dst_set = 1;
10875         }
10876       else if (unformat (line_input, "group %U %U",
10877                          unformat_ip4_address, &dst.ip4,
10878                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10879         {
10880           grp_set = dst_set = 1;
10881           ipv4_set = 1;
10882         }
10883       else if (unformat (line_input, "group %U",
10884                          unformat_ip4_address, &dst.ip4))
10885         {
10886           grp_set = dst_set = 1;
10887           ipv4_set = 1;
10888         }
10889       else if (unformat (line_input, "group %U %U",
10890                          unformat_ip6_address, &dst.ip6,
10891                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10892         {
10893           grp_set = dst_set = 1;
10894           ipv6_set = 1;
10895         }
10896       else if (unformat (line_input, "group %U",
10897                          unformat_ip6_address, &dst.ip6))
10898         {
10899           grp_set = dst_set = 1;
10900           ipv6_set = 1;
10901         }
10902       else
10903         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10904         ;
10905       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10906         ;
10907       else if (unformat (line_input, "decap-next %U",
10908                          unformat_vxlan_decap_next, &decap_next_index))
10909         ;
10910       else if (unformat (line_input, "vni %d", &vni))
10911         ;
10912       else
10913         {
10914           errmsg ("parse error '%U'", format_unformat_error, line_input);
10915           return -99;
10916         }
10917     }
10918
10919   if (src_set == 0)
10920     {
10921       errmsg ("tunnel src address not specified");
10922       return -99;
10923     }
10924   if (dst_set == 0)
10925     {
10926       errmsg ("tunnel dst address not specified");
10927       return -99;
10928     }
10929
10930   if (grp_set && !ip46_address_is_multicast (&dst))
10931     {
10932       errmsg ("tunnel group address not multicast");
10933       return -99;
10934     }
10935   if (grp_set && mcast_sw_if_index == ~0)
10936     {
10937       errmsg ("tunnel nonexistent multicast device");
10938       return -99;
10939     }
10940   if (grp_set == 0 && ip46_address_is_multicast (&dst))
10941     {
10942       errmsg ("tunnel dst address must be unicast");
10943       return -99;
10944     }
10945
10946
10947   if (ipv4_set && ipv6_set)
10948     {
10949       errmsg ("both IPv4 and IPv6 addresses specified");
10950       return -99;
10951     }
10952
10953   if ((vni == 0) || (vni >> 24))
10954     {
10955       errmsg ("vni not specified or out of range");
10956       return -99;
10957     }
10958
10959   M (VXLAN_ADD_DEL_TUNNEL, mp);
10960
10961   if (ipv6_set)
10962     {
10963       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10964       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10965     }
10966   else
10967     {
10968       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10969       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10970     }
10971   mp->encap_vrf_id = ntohl (encap_vrf_id);
10972   mp->decap_next_index = ntohl (decap_next_index);
10973   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10974   mp->vni = ntohl (vni);
10975   mp->is_add = is_add;
10976   mp->is_ipv6 = ipv6_set;
10977
10978   S (mp);
10979   W (ret);
10980   return ret;
10981 }
10982
10983 static void vl_api_vxlan_tunnel_details_t_handler
10984   (vl_api_vxlan_tunnel_details_t * mp)
10985 {
10986   vat_main_t *vam = &vat_main;
10987   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
10988   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
10989
10990   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
10991          ntohl (mp->sw_if_index),
10992          format_ip46_address, &src, IP46_TYPE_ANY,
10993          format_ip46_address, &dst, IP46_TYPE_ANY,
10994          ntohl (mp->encap_vrf_id),
10995          ntohl (mp->decap_next_index), ntohl (mp->vni),
10996          ntohl (mp->mcast_sw_if_index));
10997 }
10998
10999 static void vl_api_vxlan_tunnel_details_t_handler_json
11000   (vl_api_vxlan_tunnel_details_t * mp)
11001 {
11002   vat_main_t *vam = &vat_main;
11003   vat_json_node_t *node = NULL;
11004
11005   if (VAT_JSON_ARRAY != vam->json_tree.type)
11006     {
11007       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11008       vat_json_init_array (&vam->json_tree);
11009     }
11010   node = vat_json_array_add (&vam->json_tree);
11011
11012   vat_json_init_object (node);
11013   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11014   if (mp->is_ipv6)
11015     {
11016       struct in6_addr ip6;
11017
11018       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
11019       vat_json_object_add_ip6 (node, "src_address", ip6);
11020       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
11021       vat_json_object_add_ip6 (node, "dst_address", ip6);
11022     }
11023   else
11024     {
11025       struct in_addr ip4;
11026
11027       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
11028       vat_json_object_add_ip4 (node, "src_address", ip4);
11029       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
11030       vat_json_object_add_ip4 (node, "dst_address", ip4);
11031     }
11032   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11033   vat_json_object_add_uint (node, "decap_next_index",
11034                             ntohl (mp->decap_next_index));
11035   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11036   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11037   vat_json_object_add_uint (node, "mcast_sw_if_index",
11038                             ntohl (mp->mcast_sw_if_index));
11039 }
11040
11041 static int
11042 api_vxlan_tunnel_dump (vat_main_t * vam)
11043 {
11044   unformat_input_t *i = vam->input;
11045   vl_api_vxlan_tunnel_dump_t *mp;
11046   vl_api_control_ping_t *mp_ping;
11047   u32 sw_if_index;
11048   u8 sw_if_index_set = 0;
11049   int ret;
11050
11051   /* Parse args required to build the message */
11052   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11053     {
11054       if (unformat (i, "sw_if_index %d", &sw_if_index))
11055         sw_if_index_set = 1;
11056       else
11057         break;
11058     }
11059
11060   if (sw_if_index_set == 0)
11061     {
11062       sw_if_index = ~0;
11063     }
11064
11065   if (!vam->json_output)
11066     {
11067       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
11068              "sw_if_index", "src_address", "dst_address",
11069              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11070     }
11071
11072   /* Get list of vxlan-tunnel interfaces */
11073   M (VXLAN_TUNNEL_DUMP, mp);
11074
11075   mp->sw_if_index = htonl (sw_if_index);
11076
11077   S (mp);
11078
11079   /* Use a control ping for synchronization */
11080   M (CONTROL_PING, mp_ping);
11081   S (mp_ping);
11082
11083   W (ret);
11084   return ret;
11085 }
11086
11087 static int
11088 api_gre_add_del_tunnel (vat_main_t * vam)
11089 {
11090   unformat_input_t *line_input = vam->input;
11091   vl_api_gre_add_del_tunnel_t *mp;
11092   ip4_address_t src4, dst4;
11093   ip6_address_t src6, dst6;
11094   u8 is_add = 1;
11095   u8 ipv4_set = 0;
11096   u8 ipv6_set = 0;
11097   u8 teb = 0;
11098   u8 src_set = 0;
11099   u8 dst_set = 0;
11100   u32 outer_fib_id = 0;
11101   int ret;
11102
11103   memset (&src4, 0, sizeof src4);
11104   memset (&dst4, 0, sizeof dst4);
11105   memset (&src6, 0, sizeof src6);
11106   memset (&dst6, 0, sizeof dst6);
11107
11108   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11109     {
11110       if (unformat (line_input, "del"))
11111         is_add = 0;
11112       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
11113         {
11114           src_set = 1;
11115           ipv4_set = 1;
11116         }
11117       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
11118         {
11119           dst_set = 1;
11120           ipv4_set = 1;
11121         }
11122       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
11123         {
11124           src_set = 1;
11125           ipv6_set = 1;
11126         }
11127       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
11128         {
11129           dst_set = 1;
11130           ipv6_set = 1;
11131         }
11132       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
11133         ;
11134       else if (unformat (line_input, "teb"))
11135         teb = 1;
11136       else
11137         {
11138           errmsg ("parse error '%U'", format_unformat_error, line_input);
11139           return -99;
11140         }
11141     }
11142
11143   if (src_set == 0)
11144     {
11145       errmsg ("tunnel src address not specified");
11146       return -99;
11147     }
11148   if (dst_set == 0)
11149     {
11150       errmsg ("tunnel dst address not specified");
11151       return -99;
11152     }
11153   if (ipv4_set && ipv6_set)
11154     {
11155       errmsg ("both IPv4 and IPv6 addresses specified");
11156       return -99;
11157     }
11158
11159
11160   M (GRE_ADD_DEL_TUNNEL, mp);
11161
11162   if (ipv4_set)
11163     {
11164       clib_memcpy (&mp->src_address, &src4, 4);
11165       clib_memcpy (&mp->dst_address, &dst4, 4);
11166     }
11167   else
11168     {
11169       clib_memcpy (&mp->src_address, &src6, 16);
11170       clib_memcpy (&mp->dst_address, &dst6, 16);
11171     }
11172   mp->outer_fib_id = ntohl (outer_fib_id);
11173   mp->is_add = is_add;
11174   mp->teb = teb;
11175   mp->is_ipv6 = ipv6_set;
11176
11177   S (mp);
11178   W (ret);
11179   return ret;
11180 }
11181
11182 static void vl_api_gre_tunnel_details_t_handler
11183   (vl_api_gre_tunnel_details_t * mp)
11184 {
11185   vat_main_t *vam = &vat_main;
11186   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
11187   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
11188
11189   print (vam->ofp, "%11d%24U%24U%6d%14d",
11190          ntohl (mp->sw_if_index),
11191          format_ip46_address, &src, IP46_TYPE_ANY,
11192          format_ip46_address, &dst, IP46_TYPE_ANY,
11193          mp->teb, ntohl (mp->outer_fib_id));
11194 }
11195
11196 static void vl_api_gre_tunnel_details_t_handler_json
11197   (vl_api_gre_tunnel_details_t * mp)
11198 {
11199   vat_main_t *vam = &vat_main;
11200   vat_json_node_t *node = NULL;
11201   struct in_addr ip4;
11202   struct in6_addr ip6;
11203
11204   if (VAT_JSON_ARRAY != vam->json_tree.type)
11205     {
11206       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11207       vat_json_init_array (&vam->json_tree);
11208     }
11209   node = vat_json_array_add (&vam->json_tree);
11210
11211   vat_json_init_object (node);
11212   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11213   if (!mp->is_ipv6)
11214     {
11215       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
11216       vat_json_object_add_ip4 (node, "src_address", ip4);
11217       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
11218       vat_json_object_add_ip4 (node, "dst_address", ip4);
11219     }
11220   else
11221     {
11222       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
11223       vat_json_object_add_ip6 (node, "src_address", ip6);
11224       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
11225       vat_json_object_add_ip6 (node, "dst_address", ip6);
11226     }
11227   vat_json_object_add_uint (node, "teb", mp->teb);
11228   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
11229   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
11230 }
11231
11232 static int
11233 api_gre_tunnel_dump (vat_main_t * vam)
11234 {
11235   unformat_input_t *i = vam->input;
11236   vl_api_gre_tunnel_dump_t *mp;
11237   vl_api_control_ping_t *mp_ping;
11238   u32 sw_if_index;
11239   u8 sw_if_index_set = 0;
11240   int ret;
11241
11242   /* Parse args required to build the message */
11243   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11244     {
11245       if (unformat (i, "sw_if_index %d", &sw_if_index))
11246         sw_if_index_set = 1;
11247       else
11248         break;
11249     }
11250
11251   if (sw_if_index_set == 0)
11252     {
11253       sw_if_index = ~0;
11254     }
11255
11256   if (!vam->json_output)
11257     {
11258       print (vam->ofp, "%11s%24s%24s%6s%14s",
11259              "sw_if_index", "src_address", "dst_address", "teb",
11260              "outer_fib_id");
11261     }
11262
11263   /* Get list of gre-tunnel interfaces */
11264   M (GRE_TUNNEL_DUMP, mp);
11265
11266   mp->sw_if_index = htonl (sw_if_index);
11267
11268   S (mp);
11269
11270   /* Use a control ping for synchronization */
11271   M (CONTROL_PING, mp_ping);
11272   S (mp_ping);
11273
11274   W (ret);
11275   return ret;
11276 }
11277
11278 static int
11279 api_l2_fib_clear_table (vat_main_t * vam)
11280 {
11281 //  unformat_input_t * i = vam->input;
11282   vl_api_l2_fib_clear_table_t *mp;
11283   int ret;
11284
11285   M (L2_FIB_CLEAR_TABLE, mp);
11286
11287   S (mp);
11288   W (ret);
11289   return ret;
11290 }
11291
11292 static int
11293 api_l2_interface_efp_filter (vat_main_t * vam)
11294 {
11295   unformat_input_t *i = vam->input;
11296   vl_api_l2_interface_efp_filter_t *mp;
11297   u32 sw_if_index;
11298   u8 enable = 1;
11299   u8 sw_if_index_set = 0;
11300   int ret;
11301
11302   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11303     {
11304       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11305         sw_if_index_set = 1;
11306       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11307         sw_if_index_set = 1;
11308       else if (unformat (i, "enable"))
11309         enable = 1;
11310       else if (unformat (i, "disable"))
11311         enable = 0;
11312       else
11313         {
11314           clib_warning ("parse error '%U'", format_unformat_error, i);
11315           return -99;
11316         }
11317     }
11318
11319   if (sw_if_index_set == 0)
11320     {
11321       errmsg ("missing sw_if_index");
11322       return -99;
11323     }
11324
11325   M (L2_INTERFACE_EFP_FILTER, mp);
11326
11327   mp->sw_if_index = ntohl (sw_if_index);
11328   mp->enable_disable = enable;
11329
11330   S (mp);
11331   W (ret);
11332   return ret;
11333 }
11334
11335 #define foreach_vtr_op                          \
11336 _("disable",  L2_VTR_DISABLED)                  \
11337 _("push-1",  L2_VTR_PUSH_1)                     \
11338 _("push-2",  L2_VTR_PUSH_2)                     \
11339 _("pop-1",  L2_VTR_POP_1)                       \
11340 _("pop-2",  L2_VTR_POP_2)                       \
11341 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
11342 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
11343 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
11344 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
11345
11346 static int
11347 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
11348 {
11349   unformat_input_t *i = vam->input;
11350   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
11351   u32 sw_if_index;
11352   u8 sw_if_index_set = 0;
11353   u8 vtr_op_set = 0;
11354   u32 vtr_op = 0;
11355   u32 push_dot1q = 1;
11356   u32 tag1 = ~0;
11357   u32 tag2 = ~0;
11358   int ret;
11359
11360   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11361     {
11362       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11363         sw_if_index_set = 1;
11364       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11365         sw_if_index_set = 1;
11366       else if (unformat (i, "vtr_op %d", &vtr_op))
11367         vtr_op_set = 1;
11368 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
11369       foreach_vtr_op
11370 #undef _
11371         else if (unformat (i, "push_dot1q %d", &push_dot1q))
11372         ;
11373       else if (unformat (i, "tag1 %d", &tag1))
11374         ;
11375       else if (unformat (i, "tag2 %d", &tag2))
11376         ;
11377       else
11378         {
11379           clib_warning ("parse error '%U'", format_unformat_error, i);
11380           return -99;
11381         }
11382     }
11383
11384   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
11385     {
11386       errmsg ("missing vtr operation or sw_if_index");
11387       return -99;
11388     }
11389
11390   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
11391   mp->sw_if_index = ntohl (sw_if_index);
11392   mp->vtr_op = ntohl (vtr_op);
11393   mp->push_dot1q = ntohl (push_dot1q);
11394   mp->tag1 = ntohl (tag1);
11395   mp->tag2 = ntohl (tag2);
11396
11397   S (mp);
11398   W (ret);
11399   return ret;
11400 }
11401
11402 static int
11403 api_create_vhost_user_if (vat_main_t * vam)
11404 {
11405   unformat_input_t *i = vam->input;
11406   vl_api_create_vhost_user_if_t *mp;
11407   u8 *file_name;
11408   u8 is_server = 0;
11409   u8 file_name_set = 0;
11410   u32 custom_dev_instance = ~0;
11411   u8 hwaddr[6];
11412   u8 use_custom_mac = 0;
11413   u8 *tag = 0;
11414   int ret;
11415   u8 operation_mode = VHOST_USER_POLLING_MODE;
11416
11417   /* Shut up coverity */
11418   memset (hwaddr, 0, sizeof (hwaddr));
11419
11420   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11421     {
11422       if (unformat (i, "socket %s", &file_name))
11423         {
11424           file_name_set = 1;
11425         }
11426       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11427         ;
11428       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
11429         use_custom_mac = 1;
11430       else if (unformat (i, "server"))
11431         is_server = 1;
11432       else if (unformat (i, "tag %s", &tag))
11433         ;
11434       else if (unformat (i, "mode %U",
11435                          api_unformat_vhost_user_operation_mode,
11436                          &operation_mode))
11437         ;
11438       else
11439         break;
11440     }
11441
11442   if (file_name_set == 0)
11443     {
11444       errmsg ("missing socket file name");
11445       return -99;
11446     }
11447
11448   if (vec_len (file_name) > 255)
11449     {
11450       errmsg ("socket file name too long");
11451       return -99;
11452     }
11453   vec_add1 (file_name, 0);
11454
11455   M (CREATE_VHOST_USER_IF, mp);
11456
11457   mp->operation_mode = operation_mode;
11458   mp->is_server = is_server;
11459   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11460   vec_free (file_name);
11461   if (custom_dev_instance != ~0)
11462     {
11463       mp->renumber = 1;
11464       mp->custom_dev_instance = ntohl (custom_dev_instance);
11465     }
11466   mp->use_custom_mac = use_custom_mac;
11467   clib_memcpy (mp->mac_address, hwaddr, 6);
11468   if (tag)
11469     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
11470   vec_free (tag);
11471
11472   S (mp);
11473   W (ret);
11474   return ret;
11475 }
11476
11477 static int
11478 api_modify_vhost_user_if (vat_main_t * vam)
11479 {
11480   unformat_input_t *i = vam->input;
11481   vl_api_modify_vhost_user_if_t *mp;
11482   u8 *file_name;
11483   u8 is_server = 0;
11484   u8 file_name_set = 0;
11485   u32 custom_dev_instance = ~0;
11486   u8 sw_if_index_set = 0;
11487   u32 sw_if_index = (u32) ~ 0;
11488   int ret;
11489   u8 operation_mode = VHOST_USER_POLLING_MODE;
11490
11491   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11492     {
11493       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11494         sw_if_index_set = 1;
11495       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11496         sw_if_index_set = 1;
11497       else if (unformat (i, "socket %s", &file_name))
11498         {
11499           file_name_set = 1;
11500         }
11501       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11502         ;
11503       else if (unformat (i, "server"))
11504         is_server = 1;
11505       else if (unformat (i, "mode %U",
11506                          api_unformat_vhost_user_operation_mode,
11507                          &operation_mode))
11508         ;
11509       else
11510         break;
11511     }
11512
11513   if (sw_if_index_set == 0)
11514     {
11515       errmsg ("missing sw_if_index or interface name");
11516       return -99;
11517     }
11518
11519   if (file_name_set == 0)
11520     {
11521       errmsg ("missing socket file name");
11522       return -99;
11523     }
11524
11525   if (vec_len (file_name) > 255)
11526     {
11527       errmsg ("socket file name too long");
11528       return -99;
11529     }
11530   vec_add1 (file_name, 0);
11531
11532   M (MODIFY_VHOST_USER_IF, mp);
11533
11534   mp->operation_mode = operation_mode;
11535   mp->sw_if_index = ntohl (sw_if_index);
11536   mp->is_server = is_server;
11537   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11538   vec_free (file_name);
11539   if (custom_dev_instance != ~0)
11540     {
11541       mp->renumber = 1;
11542       mp->custom_dev_instance = ntohl (custom_dev_instance);
11543     }
11544
11545   S (mp);
11546   W (ret);
11547   return ret;
11548 }
11549
11550 static int
11551 api_delete_vhost_user_if (vat_main_t * vam)
11552 {
11553   unformat_input_t *i = vam->input;
11554   vl_api_delete_vhost_user_if_t *mp;
11555   u32 sw_if_index = ~0;
11556   u8 sw_if_index_set = 0;
11557   int ret;
11558
11559   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11560     {
11561       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11562         sw_if_index_set = 1;
11563       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11564         sw_if_index_set = 1;
11565       else
11566         break;
11567     }
11568
11569   if (sw_if_index_set == 0)
11570     {
11571       errmsg ("missing sw_if_index or interface name");
11572       return -99;
11573     }
11574
11575
11576   M (DELETE_VHOST_USER_IF, mp);
11577
11578   mp->sw_if_index = ntohl (sw_if_index);
11579
11580   S (mp);
11581   W (ret);
11582   return ret;
11583 }
11584
11585 static void vl_api_sw_interface_vhost_user_details_t_handler
11586   (vl_api_sw_interface_vhost_user_details_t * mp)
11587 {
11588   vat_main_t *vam = &vat_main;
11589
11590   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %U %s",
11591          (char *) mp->interface_name,
11592          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11593          clib_net_to_host_u64 (mp->features), mp->is_server,
11594          ntohl (mp->num_regions), api_format_vhost_user_operation_mode,
11595          mp->operation_mode, (char *) mp->sock_filename);
11596   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
11597 }
11598
11599 static void vl_api_sw_interface_vhost_user_details_t_handler_json
11600   (vl_api_sw_interface_vhost_user_details_t * mp)
11601 {
11602   vat_main_t *vam = &vat_main;
11603   vat_json_node_t *node = NULL;
11604
11605   if (VAT_JSON_ARRAY != vam->json_tree.type)
11606     {
11607       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11608       vat_json_init_array (&vam->json_tree);
11609     }
11610   node = vat_json_array_add (&vam->json_tree);
11611
11612   vat_json_init_object (node);
11613   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11614   vat_json_object_add_string_copy (node, "interface_name",
11615                                    mp->interface_name);
11616   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11617                             ntohl (mp->virtio_net_hdr_sz));
11618   vat_json_object_add_uint (node, "features",
11619                             clib_net_to_host_u64 (mp->features));
11620   vat_json_object_add_uint (node, "is_server", mp->is_server);
11621   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11622   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11623   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11624   vat_json_object_add_uint (node, "mode", mp->operation_mode);
11625 }
11626
11627 static int
11628 api_sw_interface_vhost_user_dump (vat_main_t * vam)
11629 {
11630   vl_api_sw_interface_vhost_user_dump_t *mp;
11631   vl_api_control_ping_t *mp_ping;
11632   int ret;
11633   print (vam->ofp,
11634          "Interface name            idx hdr_sz features server regions mode"
11635          "      filename");
11636
11637   /* Get list of vhost-user interfaces */
11638   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
11639   S (mp);
11640
11641   /* Use a control ping for synchronization */
11642   M (CONTROL_PING, mp_ping);
11643   S (mp_ping);
11644
11645   W (ret);
11646   return ret;
11647 }
11648
11649 static int
11650 api_show_version (vat_main_t * vam)
11651 {
11652   vl_api_show_version_t *mp;
11653   int ret;
11654
11655   M (SHOW_VERSION, mp);
11656
11657   S (mp);
11658   W (ret);
11659   return ret;
11660 }
11661
11662
11663 static int
11664 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11665 {
11666   unformat_input_t *line_input = vam->input;
11667   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11668   ip4_address_t local4, remote4;
11669   ip6_address_t local6, remote6;
11670   u8 is_add = 1;
11671   u8 ipv4_set = 0, ipv6_set = 0;
11672   u8 local_set = 0;
11673   u8 remote_set = 0;
11674   u32 encap_vrf_id = 0;
11675   u32 decap_vrf_id = 0;
11676   u8 protocol = ~0;
11677   u32 vni;
11678   u8 vni_set = 0;
11679   int ret;
11680
11681   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11682     {
11683       if (unformat (line_input, "del"))
11684         is_add = 0;
11685       else if (unformat (line_input, "local %U",
11686                          unformat_ip4_address, &local4))
11687         {
11688           local_set = 1;
11689           ipv4_set = 1;
11690         }
11691       else if (unformat (line_input, "remote %U",
11692                          unformat_ip4_address, &remote4))
11693         {
11694           remote_set = 1;
11695           ipv4_set = 1;
11696         }
11697       else if (unformat (line_input, "local %U",
11698                          unformat_ip6_address, &local6))
11699         {
11700           local_set = 1;
11701           ipv6_set = 1;
11702         }
11703       else if (unformat (line_input, "remote %U",
11704                          unformat_ip6_address, &remote6))
11705         {
11706           remote_set = 1;
11707           ipv6_set = 1;
11708         }
11709       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11710         ;
11711       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11712         ;
11713       else if (unformat (line_input, "vni %d", &vni))
11714         vni_set = 1;
11715       else if (unformat (line_input, "next-ip4"))
11716         protocol = 1;
11717       else if (unformat (line_input, "next-ip6"))
11718         protocol = 2;
11719       else if (unformat (line_input, "next-ethernet"))
11720         protocol = 3;
11721       else if (unformat (line_input, "next-nsh"))
11722         protocol = 4;
11723       else
11724         {
11725           errmsg ("parse error '%U'", format_unformat_error, line_input);
11726           return -99;
11727         }
11728     }
11729
11730   if (local_set == 0)
11731     {
11732       errmsg ("tunnel local address not specified");
11733       return -99;
11734     }
11735   if (remote_set == 0)
11736     {
11737       errmsg ("tunnel remote address not specified");
11738       return -99;
11739     }
11740   if (ipv4_set && ipv6_set)
11741     {
11742       errmsg ("both IPv4 and IPv6 addresses specified");
11743       return -99;
11744     }
11745
11746   if (vni_set == 0)
11747     {
11748       errmsg ("vni not specified");
11749       return -99;
11750     }
11751
11752   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
11753
11754
11755   if (ipv6_set)
11756     {
11757       clib_memcpy (&mp->local, &local6, sizeof (local6));
11758       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11759     }
11760   else
11761     {
11762       clib_memcpy (&mp->local, &local4, sizeof (local4));
11763       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11764     }
11765
11766   mp->encap_vrf_id = ntohl (encap_vrf_id);
11767   mp->decap_vrf_id = ntohl (decap_vrf_id);
11768   mp->protocol = protocol;
11769   mp->vni = ntohl (vni);
11770   mp->is_add = is_add;
11771   mp->is_ipv6 = ipv6_set;
11772
11773   S (mp);
11774   W (ret);
11775   return ret;
11776 }
11777
11778 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11779   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11780 {
11781   vat_main_t *vam = &vat_main;
11782
11783   print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11784          ntohl (mp->sw_if_index),
11785          format_ip46_address, &(mp->local[0]),
11786          format_ip46_address, &(mp->remote[0]),
11787          ntohl (mp->vni),
11788          ntohl (mp->protocol),
11789          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11790 }
11791
11792 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11793   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11794 {
11795   vat_main_t *vam = &vat_main;
11796   vat_json_node_t *node = NULL;
11797   struct in_addr ip4;
11798   struct in6_addr ip6;
11799
11800   if (VAT_JSON_ARRAY != vam->json_tree.type)
11801     {
11802       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11803       vat_json_init_array (&vam->json_tree);
11804     }
11805   node = vat_json_array_add (&vam->json_tree);
11806
11807   vat_json_init_object (node);
11808   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11809   if (mp->is_ipv6)
11810     {
11811       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11812       vat_json_object_add_ip6 (node, "local", ip6);
11813       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11814       vat_json_object_add_ip6 (node, "remote", ip6);
11815     }
11816   else
11817     {
11818       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11819       vat_json_object_add_ip4 (node, "local", ip4);
11820       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11821       vat_json_object_add_ip4 (node, "remote", ip4);
11822     }
11823   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11824   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11825   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11826   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11827   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11828 }
11829
11830 static int
11831 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11832 {
11833   unformat_input_t *i = vam->input;
11834   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11835   vl_api_control_ping_t *mp_ping;
11836   u32 sw_if_index;
11837   u8 sw_if_index_set = 0;
11838   int ret;
11839
11840   /* Parse args required to build the message */
11841   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11842     {
11843       if (unformat (i, "sw_if_index %d", &sw_if_index))
11844         sw_if_index_set = 1;
11845       else
11846         break;
11847     }
11848
11849   if (sw_if_index_set == 0)
11850     {
11851       sw_if_index = ~0;
11852     }
11853
11854   if (!vam->json_output)
11855     {
11856       print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11857              "sw_if_index", "local", "remote", "vni",
11858              "protocol", "encap_vrf_id", "decap_vrf_id");
11859     }
11860
11861   /* Get list of vxlan-tunnel interfaces */
11862   M (VXLAN_GPE_TUNNEL_DUMP, mp);
11863
11864   mp->sw_if_index = htonl (sw_if_index);
11865
11866   S (mp);
11867
11868   /* Use a control ping for synchronization */
11869   M (CONTROL_PING, mp_ping);
11870   S (mp_ping);
11871
11872   W (ret);
11873   return ret;
11874 }
11875
11876 u8 *
11877 format_l2_fib_mac_address (u8 * s, va_list * args)
11878 {
11879   u8 *a = va_arg (*args, u8 *);
11880
11881   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11882                  a[2], a[3], a[4], a[5], a[6], a[7]);
11883 }
11884
11885 static void vl_api_l2_fib_table_entry_t_handler
11886   (vl_api_l2_fib_table_entry_t * mp)
11887 {
11888   vat_main_t *vam = &vat_main;
11889
11890   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11891          "       %d       %d     %d",
11892          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11893          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11894          mp->bvi_mac);
11895 }
11896
11897 static void vl_api_l2_fib_table_entry_t_handler_json
11898   (vl_api_l2_fib_table_entry_t * mp)
11899 {
11900   vat_main_t *vam = &vat_main;
11901   vat_json_node_t *node = NULL;
11902
11903   if (VAT_JSON_ARRAY != vam->json_tree.type)
11904     {
11905       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11906       vat_json_init_array (&vam->json_tree);
11907     }
11908   node = vat_json_array_add (&vam->json_tree);
11909
11910   vat_json_init_object (node);
11911   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11912   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11913   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11914   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11915   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11916   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11917 }
11918
11919 static int
11920 api_l2_fib_table_dump (vat_main_t * vam)
11921 {
11922   unformat_input_t *i = vam->input;
11923   vl_api_l2_fib_table_dump_t *mp;
11924   vl_api_control_ping_t *mp_ping;
11925   u32 bd_id;
11926   u8 bd_id_set = 0;
11927   int ret;
11928
11929   /* Parse args required to build the message */
11930   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11931     {
11932       if (unformat (i, "bd_id %d", &bd_id))
11933         bd_id_set = 1;
11934       else
11935         break;
11936     }
11937
11938   if (bd_id_set == 0)
11939     {
11940       errmsg ("missing bridge domain");
11941       return -99;
11942     }
11943
11944   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
11945
11946   /* Get list of l2 fib entries */
11947   M (L2_FIB_TABLE_DUMP, mp);
11948
11949   mp->bd_id = ntohl (bd_id);
11950   S (mp);
11951
11952   /* Use a control ping for synchronization */
11953   M (CONTROL_PING, mp_ping);
11954   S (mp_ping);
11955
11956   W (ret);
11957   return ret;
11958 }
11959
11960
11961 static int
11962 api_interface_name_renumber (vat_main_t * vam)
11963 {
11964   unformat_input_t *line_input = vam->input;
11965   vl_api_interface_name_renumber_t *mp;
11966   u32 sw_if_index = ~0;
11967   u32 new_show_dev_instance = ~0;
11968   int ret;
11969
11970   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11971     {
11972       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
11973                     &sw_if_index))
11974         ;
11975       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11976         ;
11977       else if (unformat (line_input, "new_show_dev_instance %d",
11978                          &new_show_dev_instance))
11979         ;
11980       else
11981         break;
11982     }
11983
11984   if (sw_if_index == ~0)
11985     {
11986       errmsg ("missing interface name or sw_if_index");
11987       return -99;
11988     }
11989
11990   if (new_show_dev_instance == ~0)
11991     {
11992       errmsg ("missing new_show_dev_instance");
11993       return -99;
11994     }
11995
11996   M (INTERFACE_NAME_RENUMBER, mp);
11997
11998   mp->sw_if_index = ntohl (sw_if_index);
11999   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
12000
12001   S (mp);
12002   W (ret);
12003   return ret;
12004 }
12005
12006 static int
12007 api_want_ip4_arp_events (vat_main_t * vam)
12008 {
12009   unformat_input_t *line_input = vam->input;
12010   vl_api_want_ip4_arp_events_t *mp;
12011   ip4_address_t address;
12012   int address_set = 0;
12013   u32 enable_disable = 1;
12014   int ret;
12015
12016   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12017     {
12018       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
12019         address_set = 1;
12020       else if (unformat (line_input, "del"))
12021         enable_disable = 0;
12022       else
12023         break;
12024     }
12025
12026   if (address_set == 0)
12027     {
12028       errmsg ("missing addresses");
12029       return -99;
12030     }
12031
12032   M (WANT_IP4_ARP_EVENTS, mp);
12033   mp->enable_disable = enable_disable;
12034   mp->pid = htonl (getpid ());
12035   mp->address = address.as_u32;
12036
12037   S (mp);
12038   W (ret);
12039   return ret;
12040 }
12041
12042 static int
12043 api_want_ip6_nd_events (vat_main_t * vam)
12044 {
12045   unformat_input_t *line_input = vam->input;
12046   vl_api_want_ip6_nd_events_t *mp;
12047   ip6_address_t address;
12048   int address_set = 0;
12049   u32 enable_disable = 1;
12050   int ret;
12051
12052   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12053     {
12054       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
12055         address_set = 1;
12056       else if (unformat (line_input, "del"))
12057         enable_disable = 0;
12058       else
12059         break;
12060     }
12061
12062   if (address_set == 0)
12063     {
12064       errmsg ("missing addresses");
12065       return -99;
12066     }
12067
12068   M (WANT_IP6_ND_EVENTS, mp);
12069   mp->enable_disable = enable_disable;
12070   mp->pid = htonl (getpid ());
12071   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
12072
12073   S (mp);
12074   W (ret);
12075   return ret;
12076 }
12077
12078 static int
12079 api_input_acl_set_interface (vat_main_t * vam)
12080 {
12081   unformat_input_t *i = vam->input;
12082   vl_api_input_acl_set_interface_t *mp;
12083   u32 sw_if_index;
12084   int sw_if_index_set;
12085   u32 ip4_table_index = ~0;
12086   u32 ip6_table_index = ~0;
12087   u32 l2_table_index = ~0;
12088   u8 is_add = 1;
12089   int ret;
12090
12091   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12092     {
12093       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12094         sw_if_index_set = 1;
12095       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12096         sw_if_index_set = 1;
12097       else if (unformat (i, "del"))
12098         is_add = 0;
12099       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12100         ;
12101       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12102         ;
12103       else if (unformat (i, "l2-table %d", &l2_table_index))
12104         ;
12105       else
12106         {
12107           clib_warning ("parse error '%U'", format_unformat_error, i);
12108           return -99;
12109         }
12110     }
12111
12112   if (sw_if_index_set == 0)
12113     {
12114       errmsg ("missing interface name or sw_if_index");
12115       return -99;
12116     }
12117
12118   M (INPUT_ACL_SET_INTERFACE, mp);
12119
12120   mp->sw_if_index = ntohl (sw_if_index);
12121   mp->ip4_table_index = ntohl (ip4_table_index);
12122   mp->ip6_table_index = ntohl (ip6_table_index);
12123   mp->l2_table_index = ntohl (l2_table_index);
12124   mp->is_add = is_add;
12125
12126   S (mp);
12127   W (ret);
12128   return ret;
12129 }
12130
12131 static int
12132 api_ip_address_dump (vat_main_t * vam)
12133 {
12134   unformat_input_t *i = vam->input;
12135   vl_api_ip_address_dump_t *mp;
12136   vl_api_control_ping_t *mp_ping;
12137   u32 sw_if_index = ~0;
12138   u8 sw_if_index_set = 0;
12139   u8 ipv4_set = 0;
12140   u8 ipv6_set = 0;
12141   int ret;
12142
12143   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12144     {
12145       if (unformat (i, "sw_if_index %d", &sw_if_index))
12146         sw_if_index_set = 1;
12147       else
12148         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12149         sw_if_index_set = 1;
12150       else if (unformat (i, "ipv4"))
12151         ipv4_set = 1;
12152       else if (unformat (i, "ipv6"))
12153         ipv6_set = 1;
12154       else
12155         break;
12156     }
12157
12158   if (ipv4_set && ipv6_set)
12159     {
12160       errmsg ("ipv4 and ipv6 flags cannot be both set");
12161       return -99;
12162     }
12163
12164   if ((!ipv4_set) && (!ipv6_set))
12165     {
12166       errmsg ("no ipv4 nor ipv6 flag set");
12167       return -99;
12168     }
12169
12170   if (sw_if_index_set == 0)
12171     {
12172       errmsg ("missing interface name or sw_if_index");
12173       return -99;
12174     }
12175
12176   vam->current_sw_if_index = sw_if_index;
12177   vam->is_ipv6 = ipv6_set;
12178
12179   M (IP_ADDRESS_DUMP, mp);
12180   mp->sw_if_index = ntohl (sw_if_index);
12181   mp->is_ipv6 = ipv6_set;
12182   S (mp);
12183
12184   /* Use a control ping for synchronization */
12185   M (CONTROL_PING, mp_ping);
12186   S (mp_ping);
12187
12188   W (ret);
12189   return ret;
12190 }
12191
12192 static int
12193 api_ip_dump (vat_main_t * vam)
12194 {
12195   vl_api_ip_dump_t *mp;
12196   vl_api_control_ping_t *mp_ping;
12197   unformat_input_t *in = vam->input;
12198   int ipv4_set = 0;
12199   int ipv6_set = 0;
12200   int is_ipv6;
12201   int i;
12202   int ret;
12203
12204   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
12205     {
12206       if (unformat (in, "ipv4"))
12207         ipv4_set = 1;
12208       else if (unformat (in, "ipv6"))
12209         ipv6_set = 1;
12210       else
12211         break;
12212     }
12213
12214   if (ipv4_set && ipv6_set)
12215     {
12216       errmsg ("ipv4 and ipv6 flags cannot be both set");
12217       return -99;
12218     }
12219
12220   if ((!ipv4_set) && (!ipv6_set))
12221     {
12222       errmsg ("no ipv4 nor ipv6 flag set");
12223       return -99;
12224     }
12225
12226   is_ipv6 = ipv6_set;
12227   vam->is_ipv6 = is_ipv6;
12228
12229   /* free old data */
12230   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
12231     {
12232       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
12233     }
12234   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
12235
12236   M (IP_DUMP, mp);
12237   mp->is_ipv6 = ipv6_set;
12238   S (mp);
12239
12240   /* Use a control ping for synchronization */
12241   M (CONTROL_PING, mp_ping);
12242   S (mp_ping);
12243
12244   W (ret);
12245   return ret;
12246 }
12247
12248 static int
12249 api_ipsec_spd_add_del (vat_main_t * vam)
12250 {
12251   unformat_input_t *i = vam->input;
12252   vl_api_ipsec_spd_add_del_t *mp;
12253   u32 spd_id = ~0;
12254   u8 is_add = 1;
12255   int ret;
12256
12257   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12258     {
12259       if (unformat (i, "spd_id %d", &spd_id))
12260         ;
12261       else if (unformat (i, "del"))
12262         is_add = 0;
12263       else
12264         {
12265           clib_warning ("parse error '%U'", format_unformat_error, i);
12266           return -99;
12267         }
12268     }
12269   if (spd_id == ~0)
12270     {
12271       errmsg ("spd_id must be set");
12272       return -99;
12273     }
12274
12275   M (IPSEC_SPD_ADD_DEL, mp);
12276
12277   mp->spd_id = ntohl (spd_id);
12278   mp->is_add = is_add;
12279
12280   S (mp);
12281   W (ret);
12282   return ret;
12283 }
12284
12285 static int
12286 api_ipsec_interface_add_del_spd (vat_main_t * vam)
12287 {
12288   unformat_input_t *i = vam->input;
12289   vl_api_ipsec_interface_add_del_spd_t *mp;
12290   u32 sw_if_index;
12291   u8 sw_if_index_set = 0;
12292   u32 spd_id = (u32) ~ 0;
12293   u8 is_add = 1;
12294   int ret;
12295
12296   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12297     {
12298       if (unformat (i, "del"))
12299         is_add = 0;
12300       else if (unformat (i, "spd_id %d", &spd_id))
12301         ;
12302       else
12303         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12304         sw_if_index_set = 1;
12305       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12306         sw_if_index_set = 1;
12307       else
12308         {
12309           clib_warning ("parse error '%U'", format_unformat_error, i);
12310           return -99;
12311         }
12312
12313     }
12314
12315   if (spd_id == (u32) ~ 0)
12316     {
12317       errmsg ("spd_id must be set");
12318       return -99;
12319     }
12320
12321   if (sw_if_index_set == 0)
12322     {
12323       errmsg ("missing interface name or sw_if_index");
12324       return -99;
12325     }
12326
12327   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
12328
12329   mp->spd_id = ntohl (spd_id);
12330   mp->sw_if_index = ntohl (sw_if_index);
12331   mp->is_add = is_add;
12332
12333   S (mp);
12334   W (ret);
12335   return ret;
12336 }
12337
12338 static int
12339 api_ipsec_spd_add_del_entry (vat_main_t * vam)
12340 {
12341   unformat_input_t *i = vam->input;
12342   vl_api_ipsec_spd_add_del_entry_t *mp;
12343   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
12344   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
12345   i32 priority = 0;
12346   u32 rport_start = 0, rport_stop = (u32) ~ 0;
12347   u32 lport_start = 0, lport_stop = (u32) ~ 0;
12348   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
12349   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
12350   int ret;
12351
12352   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
12353   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
12354   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
12355   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
12356   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
12357   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
12358
12359   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12360     {
12361       if (unformat (i, "del"))
12362         is_add = 0;
12363       if (unformat (i, "outbound"))
12364         is_outbound = 1;
12365       if (unformat (i, "inbound"))
12366         is_outbound = 0;
12367       else if (unformat (i, "spd_id %d", &spd_id))
12368         ;
12369       else if (unformat (i, "sa_id %d", &sa_id))
12370         ;
12371       else if (unformat (i, "priority %d", &priority))
12372         ;
12373       else if (unformat (i, "protocol %d", &protocol))
12374         ;
12375       else if (unformat (i, "lport_start %d", &lport_start))
12376         ;
12377       else if (unformat (i, "lport_stop %d", &lport_stop))
12378         ;
12379       else if (unformat (i, "rport_start %d", &rport_start))
12380         ;
12381       else if (unformat (i, "rport_stop %d", &rport_stop))
12382         ;
12383       else
12384         if (unformat
12385             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
12386         {
12387           is_ipv6 = 0;
12388           is_ip_any = 0;
12389         }
12390       else
12391         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
12392         {
12393           is_ipv6 = 0;
12394           is_ip_any = 0;
12395         }
12396       else
12397         if (unformat
12398             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
12399         {
12400           is_ipv6 = 0;
12401           is_ip_any = 0;
12402         }
12403       else
12404         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
12405         {
12406           is_ipv6 = 0;
12407           is_ip_any = 0;
12408         }
12409       else
12410         if (unformat
12411             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
12412         {
12413           is_ipv6 = 1;
12414           is_ip_any = 0;
12415         }
12416       else
12417         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
12418         {
12419           is_ipv6 = 1;
12420           is_ip_any = 0;
12421         }
12422       else
12423         if (unformat
12424             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
12425         {
12426           is_ipv6 = 1;
12427           is_ip_any = 0;
12428         }
12429       else
12430         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
12431         {
12432           is_ipv6 = 1;
12433           is_ip_any = 0;
12434         }
12435       else
12436         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
12437         {
12438           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
12439             {
12440               clib_warning ("unsupported action: 'resolve'");
12441               return -99;
12442             }
12443         }
12444       else
12445         {
12446           clib_warning ("parse error '%U'", format_unformat_error, i);
12447           return -99;
12448         }
12449
12450     }
12451
12452   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
12453
12454   mp->spd_id = ntohl (spd_id);
12455   mp->priority = ntohl (priority);
12456   mp->is_outbound = is_outbound;
12457
12458   mp->is_ipv6 = is_ipv6;
12459   if (is_ipv6 || is_ip_any)
12460     {
12461       clib_memcpy (mp->remote_address_start, &raddr6_start,
12462                    sizeof (ip6_address_t));
12463       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
12464                    sizeof (ip6_address_t));
12465       clib_memcpy (mp->local_address_start, &laddr6_start,
12466                    sizeof (ip6_address_t));
12467       clib_memcpy (mp->local_address_stop, &laddr6_stop,
12468                    sizeof (ip6_address_t));
12469     }
12470   else
12471     {
12472       clib_memcpy (mp->remote_address_start, &raddr4_start,
12473                    sizeof (ip4_address_t));
12474       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
12475                    sizeof (ip4_address_t));
12476       clib_memcpy (mp->local_address_start, &laddr4_start,
12477                    sizeof (ip4_address_t));
12478       clib_memcpy (mp->local_address_stop, &laddr4_stop,
12479                    sizeof (ip4_address_t));
12480     }
12481   mp->protocol = (u8) protocol;
12482   mp->local_port_start = ntohs ((u16) lport_start);
12483   mp->local_port_stop = ntohs ((u16) lport_stop);
12484   mp->remote_port_start = ntohs ((u16) rport_start);
12485   mp->remote_port_stop = ntohs ((u16) rport_stop);
12486   mp->policy = (u8) policy;
12487   mp->sa_id = ntohl (sa_id);
12488   mp->is_add = is_add;
12489   mp->is_ip_any = is_ip_any;
12490   S (mp);
12491   W (ret);
12492   return ret;
12493 }
12494
12495 static int
12496 api_ipsec_sad_add_del_entry (vat_main_t * vam)
12497 {
12498   unformat_input_t *i = vam->input;
12499   vl_api_ipsec_sad_add_del_entry_t *mp;
12500   u32 sad_id = 0, spi = 0;
12501   u8 *ck = 0, *ik = 0;
12502   u8 is_add = 1;
12503
12504   u8 protocol = IPSEC_PROTOCOL_AH;
12505   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
12506   u32 crypto_alg = 0, integ_alg = 0;
12507   ip4_address_t tun_src4;
12508   ip4_address_t tun_dst4;
12509   ip6_address_t tun_src6;
12510   ip6_address_t tun_dst6;
12511   int ret;
12512
12513   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12514     {
12515       if (unformat (i, "del"))
12516         is_add = 0;
12517       else if (unformat (i, "sad_id %d", &sad_id))
12518         ;
12519       else if (unformat (i, "spi %d", &spi))
12520         ;
12521       else if (unformat (i, "esp"))
12522         protocol = IPSEC_PROTOCOL_ESP;
12523       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
12524         {
12525           is_tunnel = 1;
12526           is_tunnel_ipv6 = 0;
12527         }
12528       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
12529         {
12530           is_tunnel = 1;
12531           is_tunnel_ipv6 = 0;
12532         }
12533       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
12534         {
12535           is_tunnel = 1;
12536           is_tunnel_ipv6 = 1;
12537         }
12538       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
12539         {
12540           is_tunnel = 1;
12541           is_tunnel_ipv6 = 1;
12542         }
12543       else
12544         if (unformat
12545             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12546         {
12547           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12548               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12549             {
12550               clib_warning ("unsupported crypto-alg: '%U'",
12551                             format_ipsec_crypto_alg, crypto_alg);
12552               return -99;
12553             }
12554         }
12555       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12556         ;
12557       else
12558         if (unformat
12559             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12560         {
12561           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12562               integ_alg >= IPSEC_INTEG_N_ALG)
12563             {
12564               clib_warning ("unsupported integ-alg: '%U'",
12565                             format_ipsec_integ_alg, integ_alg);
12566               return -99;
12567             }
12568         }
12569       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12570         ;
12571       else
12572         {
12573           clib_warning ("parse error '%U'", format_unformat_error, i);
12574           return -99;
12575         }
12576
12577     }
12578
12579   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
12580
12581   mp->sad_id = ntohl (sad_id);
12582   mp->is_add = is_add;
12583   mp->protocol = protocol;
12584   mp->spi = ntohl (spi);
12585   mp->is_tunnel = is_tunnel;
12586   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12587   mp->crypto_algorithm = crypto_alg;
12588   mp->integrity_algorithm = integ_alg;
12589   mp->crypto_key_length = vec_len (ck);
12590   mp->integrity_key_length = vec_len (ik);
12591
12592   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12593     mp->crypto_key_length = sizeof (mp->crypto_key);
12594
12595   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12596     mp->integrity_key_length = sizeof (mp->integrity_key);
12597
12598   if (ck)
12599     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12600   if (ik)
12601     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12602
12603   if (is_tunnel)
12604     {
12605       if (is_tunnel_ipv6)
12606         {
12607           clib_memcpy (mp->tunnel_src_address, &tun_src6,
12608                        sizeof (ip6_address_t));
12609           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12610                        sizeof (ip6_address_t));
12611         }
12612       else
12613         {
12614           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12615                        sizeof (ip4_address_t));
12616           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12617                        sizeof (ip4_address_t));
12618         }
12619     }
12620
12621   S (mp);
12622   W (ret);
12623   return ret;
12624 }
12625
12626 static int
12627 api_ipsec_sa_set_key (vat_main_t * vam)
12628 {
12629   unformat_input_t *i = vam->input;
12630   vl_api_ipsec_sa_set_key_t *mp;
12631   u32 sa_id;
12632   u8 *ck = 0, *ik = 0;
12633   int ret;
12634
12635   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12636     {
12637       if (unformat (i, "sa_id %d", &sa_id))
12638         ;
12639       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12640         ;
12641       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12642         ;
12643       else
12644         {
12645           clib_warning ("parse error '%U'", format_unformat_error, i);
12646           return -99;
12647         }
12648     }
12649
12650   M (IPSEC_SA_SET_KEY, mp);
12651
12652   mp->sa_id = ntohl (sa_id);
12653   mp->crypto_key_length = vec_len (ck);
12654   mp->integrity_key_length = vec_len (ik);
12655
12656   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12657     mp->crypto_key_length = sizeof (mp->crypto_key);
12658
12659   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12660     mp->integrity_key_length = sizeof (mp->integrity_key);
12661
12662   if (ck)
12663     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12664   if (ik)
12665     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12666
12667   S (mp);
12668   W (ret);
12669   return ret;
12670 }
12671
12672 static int
12673 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
12674 {
12675   unformat_input_t *i = vam->input;
12676   vl_api_ipsec_tunnel_if_add_del_t *mp;
12677   u32 local_spi = 0, remote_spi = 0;
12678   u32 crypto_alg = 0, integ_alg = 0;
12679   u8 *lck = NULL, *rck = NULL;
12680   u8 *lik = NULL, *rik = NULL;
12681   ip4_address_t local_ip = { {0} };
12682   ip4_address_t remote_ip = { {0} };
12683   u8 is_add = 1;
12684   u8 esn = 0;
12685   u8 anti_replay = 0;
12686   int ret;
12687
12688   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12689     {
12690       if (unformat (i, "del"))
12691         is_add = 0;
12692       else if (unformat (i, "esn"))
12693         esn = 1;
12694       else if (unformat (i, "anti_replay"))
12695         anti_replay = 1;
12696       else if (unformat (i, "local_spi %d", &local_spi))
12697         ;
12698       else if (unformat (i, "remote_spi %d", &remote_spi))
12699         ;
12700       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
12701         ;
12702       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
12703         ;
12704       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
12705         ;
12706       else
12707         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
12708         ;
12709       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
12710         ;
12711       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
12712         ;
12713       else
12714         if (unformat
12715             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12716         {
12717           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12718               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12719             {
12720               errmsg ("unsupported crypto-alg: '%U'\n",
12721                       format_ipsec_crypto_alg, crypto_alg);
12722               return -99;
12723             }
12724         }
12725       else
12726         if (unformat
12727             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12728         {
12729           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12730               integ_alg >= IPSEC_INTEG_N_ALG)
12731             {
12732               errmsg ("unsupported integ-alg: '%U'\n",
12733                       format_ipsec_integ_alg, integ_alg);
12734               return -99;
12735             }
12736         }
12737       else
12738         {
12739           errmsg ("parse error '%U'\n", format_unformat_error, i);
12740           return -99;
12741         }
12742     }
12743
12744   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
12745
12746   mp->is_add = is_add;
12747   mp->esn = esn;
12748   mp->anti_replay = anti_replay;
12749
12750   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
12751   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
12752
12753   mp->local_spi = htonl (local_spi);
12754   mp->remote_spi = htonl (remote_spi);
12755   mp->crypto_alg = (u8) crypto_alg;
12756
12757   mp->local_crypto_key_len = 0;
12758   if (lck)
12759     {
12760       mp->local_crypto_key_len = vec_len (lck);
12761       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
12762         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
12763       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
12764     }
12765
12766   mp->remote_crypto_key_len = 0;
12767   if (rck)
12768     {
12769       mp->remote_crypto_key_len = vec_len (rck);
12770       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
12771         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
12772       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
12773     }
12774
12775   mp->integ_alg = (u8) integ_alg;
12776
12777   mp->local_integ_key_len = 0;
12778   if (lik)
12779     {
12780       mp->local_integ_key_len = vec_len (lik);
12781       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
12782         mp->local_integ_key_len = sizeof (mp->local_integ_key);
12783       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
12784     }
12785
12786   mp->remote_integ_key_len = 0;
12787   if (rik)
12788     {
12789       mp->remote_integ_key_len = vec_len (rik);
12790       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
12791         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
12792       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
12793     }
12794
12795   S (mp);
12796   W (ret);
12797   return ret;
12798 }
12799
12800 static int
12801 api_ikev2_profile_add_del (vat_main_t * vam)
12802 {
12803   unformat_input_t *i = vam->input;
12804   vl_api_ikev2_profile_add_del_t *mp;
12805   u8 is_add = 1;
12806   u8 *name = 0;
12807   int ret;
12808
12809   const char *valid_chars = "a-zA-Z0-9_";
12810
12811   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12812     {
12813       if (unformat (i, "del"))
12814         is_add = 0;
12815       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12816         vec_add1 (name, 0);
12817       else
12818         {
12819           errmsg ("parse error '%U'", format_unformat_error, i);
12820           return -99;
12821         }
12822     }
12823
12824   if (!vec_len (name))
12825     {
12826       errmsg ("profile name must be specified");
12827       return -99;
12828     }
12829
12830   if (vec_len (name) > 64)
12831     {
12832       errmsg ("profile name too long");
12833       return -99;
12834     }
12835
12836   M (IKEV2_PROFILE_ADD_DEL, mp);
12837
12838   clib_memcpy (mp->name, name, vec_len (name));
12839   mp->is_add = is_add;
12840   vec_free (name);
12841
12842   S (mp);
12843   W (ret);
12844   return ret;
12845 }
12846
12847 static int
12848 api_ikev2_profile_set_auth (vat_main_t * vam)
12849 {
12850   unformat_input_t *i = vam->input;
12851   vl_api_ikev2_profile_set_auth_t *mp;
12852   u8 *name = 0;
12853   u8 *data = 0;
12854   u32 auth_method = 0;
12855   u8 is_hex = 0;
12856   int ret;
12857
12858   const char *valid_chars = "a-zA-Z0-9_";
12859
12860   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12861     {
12862       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12863         vec_add1 (name, 0);
12864       else if (unformat (i, "auth_method %U",
12865                          unformat_ikev2_auth_method, &auth_method))
12866         ;
12867       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12868         is_hex = 1;
12869       else if (unformat (i, "auth_data %v", &data))
12870         ;
12871       else
12872         {
12873           errmsg ("parse error '%U'", format_unformat_error, i);
12874           return -99;
12875         }
12876     }
12877
12878   if (!vec_len (name))
12879     {
12880       errmsg ("profile name must be specified");
12881       return -99;
12882     }
12883
12884   if (vec_len (name) > 64)
12885     {
12886       errmsg ("profile name too long");
12887       return -99;
12888     }
12889
12890   if (!vec_len (data))
12891     {
12892       errmsg ("auth_data must be specified");
12893       return -99;
12894     }
12895
12896   if (!auth_method)
12897     {
12898       errmsg ("auth_method must be specified");
12899       return -99;
12900     }
12901
12902   M (IKEV2_PROFILE_SET_AUTH, mp);
12903
12904   mp->is_hex = is_hex;
12905   mp->auth_method = (u8) auth_method;
12906   mp->data_len = vec_len (data);
12907   clib_memcpy (mp->name, name, vec_len (name));
12908   clib_memcpy (mp->data, data, vec_len (data));
12909   vec_free (name);
12910   vec_free (data);
12911
12912   S (mp);
12913   W (ret);
12914   return ret;
12915 }
12916
12917 static int
12918 api_ikev2_profile_set_id (vat_main_t * vam)
12919 {
12920   unformat_input_t *i = vam->input;
12921   vl_api_ikev2_profile_set_id_t *mp;
12922   u8 *name = 0;
12923   u8 *data = 0;
12924   u8 is_local = 0;
12925   u32 id_type = 0;
12926   ip4_address_t ip4;
12927   int ret;
12928
12929   const char *valid_chars = "a-zA-Z0-9_";
12930
12931   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12932     {
12933       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12934         vec_add1 (name, 0);
12935       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12936         ;
12937       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12938         {
12939           data = vec_new (u8, 4);
12940           clib_memcpy (data, ip4.as_u8, 4);
12941         }
12942       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12943         ;
12944       else if (unformat (i, "id_data %v", &data))
12945         ;
12946       else if (unformat (i, "local"))
12947         is_local = 1;
12948       else if (unformat (i, "remote"))
12949         is_local = 0;
12950       else
12951         {
12952           errmsg ("parse error '%U'", format_unformat_error, i);
12953           return -99;
12954         }
12955     }
12956
12957   if (!vec_len (name))
12958     {
12959       errmsg ("profile name must be specified");
12960       return -99;
12961     }
12962
12963   if (vec_len (name) > 64)
12964     {
12965       errmsg ("profile name too long");
12966       return -99;
12967     }
12968
12969   if (!vec_len (data))
12970     {
12971       errmsg ("id_data must be specified");
12972       return -99;
12973     }
12974
12975   if (!id_type)
12976     {
12977       errmsg ("id_type must be specified");
12978       return -99;
12979     }
12980
12981   M (IKEV2_PROFILE_SET_ID, mp);
12982
12983   mp->is_local = is_local;
12984   mp->id_type = (u8) id_type;
12985   mp->data_len = vec_len (data);
12986   clib_memcpy (mp->name, name, vec_len (name));
12987   clib_memcpy (mp->data, data, vec_len (data));
12988   vec_free (name);
12989   vec_free (data);
12990
12991   S (mp);
12992   W (ret);
12993   return ret;
12994 }
12995
12996 static int
12997 api_ikev2_profile_set_ts (vat_main_t * vam)
12998 {
12999   unformat_input_t *i = vam->input;
13000   vl_api_ikev2_profile_set_ts_t *mp;
13001   u8 *name = 0;
13002   u8 is_local = 0;
13003   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
13004   ip4_address_t start_addr, end_addr;
13005
13006   const char *valid_chars = "a-zA-Z0-9_";
13007   int ret;
13008
13009   start_addr.as_u32 = 0;
13010   end_addr.as_u32 = (u32) ~ 0;
13011
13012   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13013     {
13014       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13015         vec_add1 (name, 0);
13016       else if (unformat (i, "protocol %d", &proto))
13017         ;
13018       else if (unformat (i, "start_port %d", &start_port))
13019         ;
13020       else if (unformat (i, "end_port %d", &end_port))
13021         ;
13022       else
13023         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
13024         ;
13025       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
13026         ;
13027       else if (unformat (i, "local"))
13028         is_local = 1;
13029       else if (unformat (i, "remote"))
13030         is_local = 0;
13031       else
13032         {
13033           errmsg ("parse error '%U'", format_unformat_error, i);
13034           return -99;
13035         }
13036     }
13037
13038   if (!vec_len (name))
13039     {
13040       errmsg ("profile name must be specified");
13041       return -99;
13042     }
13043
13044   if (vec_len (name) > 64)
13045     {
13046       errmsg ("profile name too long");
13047       return -99;
13048     }
13049
13050   M (IKEV2_PROFILE_SET_TS, mp);
13051
13052   mp->is_local = is_local;
13053   mp->proto = (u8) proto;
13054   mp->start_port = (u16) start_port;
13055   mp->end_port = (u16) end_port;
13056   mp->start_addr = start_addr.as_u32;
13057   mp->end_addr = end_addr.as_u32;
13058   clib_memcpy (mp->name, name, vec_len (name));
13059   vec_free (name);
13060
13061   S (mp);
13062   W (ret);
13063   return ret;
13064 }
13065
13066 static int
13067 api_ikev2_set_local_key (vat_main_t * vam)
13068 {
13069   unformat_input_t *i = vam->input;
13070   vl_api_ikev2_set_local_key_t *mp;
13071   u8 *file = 0;
13072   int ret;
13073
13074   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13075     {
13076       if (unformat (i, "file %v", &file))
13077         vec_add1 (file, 0);
13078       else
13079         {
13080           errmsg ("parse error '%U'", format_unformat_error, i);
13081           return -99;
13082         }
13083     }
13084
13085   if (!vec_len (file))
13086     {
13087       errmsg ("RSA key file must be specified");
13088       return -99;
13089     }
13090
13091   if (vec_len (file) > 256)
13092     {
13093       errmsg ("file name too long");
13094       return -99;
13095     }
13096
13097   M (IKEV2_SET_LOCAL_KEY, mp);
13098
13099   clib_memcpy (mp->key_file, file, vec_len (file));
13100   vec_free (file);
13101
13102   S (mp);
13103   W (ret);
13104   return ret;
13105 }
13106
13107 static int
13108 api_ikev2_set_responder (vat_main_t * vam)
13109 {
13110   unformat_input_t *i = vam->input;
13111   vl_api_ikev2_set_responder_t *mp;
13112   int ret;
13113   u8 *name = 0;
13114   u32 sw_if_index = ~0;
13115   ip4_address_t address;
13116
13117   const char *valid_chars = "a-zA-Z0-9_";
13118
13119   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13120     {
13121       if (unformat
13122           (i, "%U interface %d address %U", unformat_token, valid_chars,
13123            &name, &sw_if_index, unformat_ip4_address, &address))
13124         vec_add1 (name, 0);
13125       else
13126         {
13127           errmsg ("parse error '%U'", format_unformat_error, i);
13128           return -99;
13129         }
13130     }
13131
13132   if (!vec_len (name))
13133     {
13134       errmsg ("profile name must be specified");
13135       return -99;
13136     }
13137
13138   if (vec_len (name) > 64)
13139     {
13140       errmsg ("profile name too long");
13141       return -99;
13142     }
13143
13144   M (IKEV2_SET_RESPONDER, mp);
13145
13146   clib_memcpy (mp->name, name, vec_len (name));
13147   vec_free (name);
13148
13149   mp->sw_if_index = sw_if_index;
13150   clib_memcpy (mp->address, &address, sizeof (address));
13151
13152   S (mp);
13153   W (ret);
13154   return ret;
13155 }
13156
13157 static int
13158 api_ikev2_set_ike_transforms (vat_main_t * vam)
13159 {
13160   unformat_input_t *i = vam->input;
13161   vl_api_ikev2_set_ike_transforms_t *mp;
13162   int ret;
13163   u8 *name = 0;
13164   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13165
13166   const char *valid_chars = "a-zA-Z0-9_";
13167
13168   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13169     {
13170       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13171                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13172         vec_add1 (name, 0);
13173       else
13174         {
13175           errmsg ("parse error '%U'", format_unformat_error, i);
13176           return -99;
13177         }
13178     }
13179
13180   if (!vec_len (name))
13181     {
13182       errmsg ("profile name must be specified");
13183       return -99;
13184     }
13185
13186   if (vec_len (name) > 64)
13187     {
13188       errmsg ("profile name too long");
13189       return -99;
13190     }
13191
13192   M (IKEV2_SET_IKE_TRANSFORMS, mp);
13193
13194   clib_memcpy (mp->name, name, vec_len (name));
13195   vec_free (name);
13196   mp->crypto_alg = crypto_alg;
13197   mp->crypto_key_size = crypto_key_size;
13198   mp->integ_alg = integ_alg;
13199   mp->dh_group = dh_group;
13200
13201   S (mp);
13202   W (ret);
13203   return ret;
13204 }
13205
13206
13207 static int
13208 api_ikev2_set_esp_transforms (vat_main_t * vam)
13209 {
13210   unformat_input_t *i = vam->input;
13211   vl_api_ikev2_set_esp_transforms_t *mp;
13212   int ret;
13213   u8 *name = 0;
13214   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13215
13216   const char *valid_chars = "a-zA-Z0-9_";
13217
13218   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13219     {
13220       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13221                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13222         vec_add1 (name, 0);
13223       else
13224         {
13225           errmsg ("parse error '%U'", format_unformat_error, i);
13226           return -99;
13227         }
13228     }
13229
13230   if (!vec_len (name))
13231     {
13232       errmsg ("profile name must be specified");
13233       return -99;
13234     }
13235
13236   if (vec_len (name) > 64)
13237     {
13238       errmsg ("profile name too long");
13239       return -99;
13240     }
13241
13242   M (IKEV2_SET_ESP_TRANSFORMS, mp);
13243
13244   clib_memcpy (mp->name, name, vec_len (name));
13245   vec_free (name);
13246   mp->crypto_alg = crypto_alg;
13247   mp->crypto_key_size = crypto_key_size;
13248   mp->integ_alg = integ_alg;
13249   mp->dh_group = dh_group;
13250
13251   S (mp);
13252   W (ret);
13253   return ret;
13254 }
13255
13256 static int
13257 api_ikev2_set_sa_lifetime (vat_main_t * vam)
13258 {
13259   unformat_input_t *i = vam->input;
13260   vl_api_ikev2_set_sa_lifetime_t *mp;
13261   int ret;
13262   u8 *name = 0;
13263   u64 lifetime, lifetime_maxdata;
13264   u32 lifetime_jitter, handover;
13265
13266   const char *valid_chars = "a-zA-Z0-9_";
13267
13268   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13269     {
13270       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
13271                     &lifetime, &lifetime_jitter, &handover,
13272                     &lifetime_maxdata))
13273         vec_add1 (name, 0);
13274       else
13275         {
13276           errmsg ("parse error '%U'", format_unformat_error, i);
13277           return -99;
13278         }
13279     }
13280
13281   if (!vec_len (name))
13282     {
13283       errmsg ("profile name must be specified");
13284       return -99;
13285     }
13286
13287   if (vec_len (name) > 64)
13288     {
13289       errmsg ("profile name too long");
13290       return -99;
13291     }
13292
13293   M (IKEV2_SET_SA_LIFETIME, mp);
13294
13295   clib_memcpy (mp->name, name, vec_len (name));
13296   vec_free (name);
13297   mp->lifetime = lifetime;
13298   mp->lifetime_jitter = lifetime_jitter;
13299   mp->handover = handover;
13300   mp->lifetime_maxdata = lifetime_maxdata;
13301
13302   S (mp);
13303   W (ret);
13304   return ret;
13305 }
13306
13307 static int
13308 api_ikev2_initiate_sa_init (vat_main_t * vam)
13309 {
13310   unformat_input_t *i = vam->input;
13311   vl_api_ikev2_initiate_sa_init_t *mp;
13312   int ret;
13313   u8 *name = 0;
13314
13315   const char *valid_chars = "a-zA-Z0-9_";
13316
13317   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13318     {
13319       if (unformat (i, "%U", unformat_token, valid_chars, &name))
13320         vec_add1 (name, 0);
13321       else
13322         {
13323           errmsg ("parse error '%U'", format_unformat_error, i);
13324           return -99;
13325         }
13326     }
13327
13328   if (!vec_len (name))
13329     {
13330       errmsg ("profile name must be specified");
13331       return -99;
13332     }
13333
13334   if (vec_len (name) > 64)
13335     {
13336       errmsg ("profile name too long");
13337       return -99;
13338     }
13339
13340   M (IKEV2_INITIATE_SA_INIT, mp);
13341
13342   clib_memcpy (mp->name, name, vec_len (name));
13343   vec_free (name);
13344
13345   S (mp);
13346   W (ret);
13347   return ret;
13348 }
13349
13350 static int
13351 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
13352 {
13353   unformat_input_t *i = vam->input;
13354   vl_api_ikev2_initiate_del_ike_sa_t *mp;
13355   int ret;
13356   u64 ispi;
13357
13358
13359   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13360     {
13361       if (unformat (i, "%lx", &ispi))
13362         ;
13363       else
13364         {
13365           errmsg ("parse error '%U'", format_unformat_error, i);
13366           return -99;
13367         }
13368     }
13369
13370   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
13371
13372   mp->ispi = ispi;
13373
13374   S (mp);
13375   W (ret);
13376   return ret;
13377 }
13378
13379 static int
13380 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
13381 {
13382   unformat_input_t *i = vam->input;
13383   vl_api_ikev2_initiate_del_child_sa_t *mp;
13384   int ret;
13385   u32 ispi;
13386
13387
13388   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13389     {
13390       if (unformat (i, "%x", &ispi))
13391         ;
13392       else
13393         {
13394           errmsg ("parse error '%U'", format_unformat_error, i);
13395           return -99;
13396         }
13397     }
13398
13399   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
13400
13401   mp->ispi = ispi;
13402
13403   S (mp);
13404   W (ret);
13405   return ret;
13406 }
13407
13408 static int
13409 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
13410 {
13411   unformat_input_t *i = vam->input;
13412   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
13413   int ret;
13414   u32 ispi;
13415
13416
13417   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13418     {
13419       if (unformat (i, "%x", &ispi))
13420         ;
13421       else
13422         {
13423           errmsg ("parse error '%U'", format_unformat_error, i);
13424           return -99;
13425         }
13426     }
13427
13428   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
13429
13430   mp->ispi = ispi;
13431
13432   S (mp);
13433   W (ret);
13434   return ret;
13435 }
13436
13437 /*
13438  * MAP
13439  */
13440 static int
13441 api_map_add_domain (vat_main_t * vam)
13442 {
13443   unformat_input_t *i = vam->input;
13444   vl_api_map_add_domain_t *mp;
13445
13446   ip4_address_t ip4_prefix;
13447   ip6_address_t ip6_prefix;
13448   ip6_address_t ip6_src;
13449   u32 num_m_args = 0;
13450   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
13451     0, psid_length = 0;
13452   u8 is_translation = 0;
13453   u32 mtu = 0;
13454   u32 ip6_src_len = 128;
13455   int ret;
13456
13457   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13458     {
13459       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
13460                     &ip4_prefix, &ip4_prefix_len))
13461         num_m_args++;
13462       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
13463                          &ip6_prefix, &ip6_prefix_len))
13464         num_m_args++;
13465       else
13466         if (unformat
13467             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
13468              &ip6_src_len))
13469         num_m_args++;
13470       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
13471         num_m_args++;
13472       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
13473         num_m_args++;
13474       else if (unformat (i, "psid-offset %d", &psid_offset))
13475         num_m_args++;
13476       else if (unformat (i, "psid-len %d", &psid_length))
13477         num_m_args++;
13478       else if (unformat (i, "mtu %d", &mtu))
13479         num_m_args++;
13480       else if (unformat (i, "map-t"))
13481         is_translation = 1;
13482       else
13483         {
13484           clib_warning ("parse error '%U'", format_unformat_error, i);
13485           return -99;
13486         }
13487     }
13488
13489   if (num_m_args < 3)
13490     {
13491       errmsg ("mandatory argument(s) missing");
13492       return -99;
13493     }
13494
13495   /* Construct the API message */
13496   M (MAP_ADD_DOMAIN, mp);
13497
13498   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
13499   mp->ip4_prefix_len = ip4_prefix_len;
13500
13501   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
13502   mp->ip6_prefix_len = ip6_prefix_len;
13503
13504   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
13505   mp->ip6_src_prefix_len = ip6_src_len;
13506
13507   mp->ea_bits_len = ea_bits_len;
13508   mp->psid_offset = psid_offset;
13509   mp->psid_length = psid_length;
13510   mp->is_translation = is_translation;
13511   mp->mtu = htons (mtu);
13512
13513   /* send it... */
13514   S (mp);
13515
13516   /* Wait for a reply, return good/bad news  */
13517   W (ret);
13518   return ret;
13519 }
13520
13521 static int
13522 api_map_del_domain (vat_main_t * vam)
13523 {
13524   unformat_input_t *i = vam->input;
13525   vl_api_map_del_domain_t *mp;
13526
13527   u32 num_m_args = 0;
13528   u32 index;
13529   int ret;
13530
13531   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13532     {
13533       if (unformat (i, "index %d", &index))
13534         num_m_args++;
13535       else
13536         {
13537           clib_warning ("parse error '%U'", format_unformat_error, i);
13538           return -99;
13539         }
13540     }
13541
13542   if (num_m_args != 1)
13543     {
13544       errmsg ("mandatory argument(s) missing");
13545       return -99;
13546     }
13547
13548   /* Construct the API message */
13549   M (MAP_DEL_DOMAIN, mp);
13550
13551   mp->index = ntohl (index);
13552
13553   /* send it... */
13554   S (mp);
13555
13556   /* Wait for a reply, return good/bad news  */
13557   W (ret);
13558   return ret;
13559 }
13560
13561 static int
13562 api_map_add_del_rule (vat_main_t * vam)
13563 {
13564   unformat_input_t *i = vam->input;
13565   vl_api_map_add_del_rule_t *mp;
13566   u8 is_add = 1;
13567   ip6_address_t ip6_dst;
13568   u32 num_m_args = 0, index, psid = 0;
13569   int ret;
13570
13571   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13572     {
13573       if (unformat (i, "index %d", &index))
13574         num_m_args++;
13575       else if (unformat (i, "psid %d", &psid))
13576         num_m_args++;
13577       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
13578         num_m_args++;
13579       else if (unformat (i, "del"))
13580         {
13581           is_add = 0;
13582         }
13583       else
13584         {
13585           clib_warning ("parse error '%U'", format_unformat_error, i);
13586           return -99;
13587         }
13588     }
13589
13590   /* Construct the API message */
13591   M (MAP_ADD_DEL_RULE, mp);
13592
13593   mp->index = ntohl (index);
13594   mp->is_add = is_add;
13595   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
13596   mp->psid = ntohs (psid);
13597
13598   /* send it... */
13599   S (mp);
13600
13601   /* Wait for a reply, return good/bad news  */
13602   W (ret);
13603   return ret;
13604 }
13605
13606 static int
13607 api_map_domain_dump (vat_main_t * vam)
13608 {
13609   vl_api_map_domain_dump_t *mp;
13610   vl_api_control_ping_t *mp_ping;
13611   int ret;
13612
13613   /* Construct the API message */
13614   M (MAP_DOMAIN_DUMP, mp);
13615
13616   /* send it... */
13617   S (mp);
13618
13619   /* Use a control ping for synchronization */
13620   M (CONTROL_PING, mp_ping);
13621   S (mp_ping);
13622
13623   W (ret);
13624   return ret;
13625 }
13626
13627 static int
13628 api_map_rule_dump (vat_main_t * vam)
13629 {
13630   unformat_input_t *i = vam->input;
13631   vl_api_map_rule_dump_t *mp;
13632   vl_api_control_ping_t *mp_ping;
13633   u32 domain_index = ~0;
13634   int ret;
13635
13636   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13637     {
13638       if (unformat (i, "index %u", &domain_index))
13639         ;
13640       else
13641         break;
13642     }
13643
13644   if (domain_index == ~0)
13645     {
13646       clib_warning ("parse error: domain index expected");
13647       return -99;
13648     }
13649
13650   /* Construct the API message */
13651   M (MAP_RULE_DUMP, mp);
13652
13653   mp->domain_index = htonl (domain_index);
13654
13655   /* send it... */
13656   S (mp);
13657
13658   /* Use a control ping for synchronization */
13659   M (CONTROL_PING, mp_ping);
13660   S (mp_ping);
13661
13662   W (ret);
13663   return ret;
13664 }
13665
13666 static void vl_api_map_add_domain_reply_t_handler
13667   (vl_api_map_add_domain_reply_t * mp)
13668 {
13669   vat_main_t *vam = &vat_main;
13670   i32 retval = ntohl (mp->retval);
13671
13672   if (vam->async_mode)
13673     {
13674       vam->async_errors += (retval < 0);
13675     }
13676   else
13677     {
13678       vam->retval = retval;
13679       vam->result_ready = 1;
13680     }
13681 }
13682
13683 static void vl_api_map_add_domain_reply_t_handler_json
13684   (vl_api_map_add_domain_reply_t * mp)
13685 {
13686   vat_main_t *vam = &vat_main;
13687   vat_json_node_t node;
13688
13689   vat_json_init_object (&node);
13690   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
13691   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
13692
13693   vat_json_print (vam->ofp, &node);
13694   vat_json_free (&node);
13695
13696   vam->retval = ntohl (mp->retval);
13697   vam->result_ready = 1;
13698 }
13699
13700 static int
13701 api_get_first_msg_id (vat_main_t * vam)
13702 {
13703   vl_api_get_first_msg_id_t *mp;
13704   unformat_input_t *i = vam->input;
13705   u8 *name;
13706   u8 name_set = 0;
13707   int ret;
13708
13709   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13710     {
13711       if (unformat (i, "client %s", &name))
13712         name_set = 1;
13713       else
13714         break;
13715     }
13716
13717   if (name_set == 0)
13718     {
13719       errmsg ("missing client name");
13720       return -99;
13721     }
13722   vec_add1 (name, 0);
13723
13724   if (vec_len (name) > 63)
13725     {
13726       errmsg ("client name too long");
13727       return -99;
13728     }
13729
13730   M (GET_FIRST_MSG_ID, mp);
13731   clib_memcpy (mp->name, name, vec_len (name));
13732   S (mp);
13733   W (ret);
13734   return ret;
13735 }
13736
13737 static int
13738 api_cop_interface_enable_disable (vat_main_t * vam)
13739 {
13740   unformat_input_t *line_input = vam->input;
13741   vl_api_cop_interface_enable_disable_t *mp;
13742   u32 sw_if_index = ~0;
13743   u8 enable_disable = 1;
13744   int ret;
13745
13746   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13747     {
13748       if (unformat (line_input, "disable"))
13749         enable_disable = 0;
13750       if (unformat (line_input, "enable"))
13751         enable_disable = 1;
13752       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13753                          vam, &sw_if_index))
13754         ;
13755       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13756         ;
13757       else
13758         break;
13759     }
13760
13761   if (sw_if_index == ~0)
13762     {
13763       errmsg ("missing interface name or sw_if_index");
13764       return -99;
13765     }
13766
13767   /* Construct the API message */
13768   M (COP_INTERFACE_ENABLE_DISABLE, mp);
13769   mp->sw_if_index = ntohl (sw_if_index);
13770   mp->enable_disable = enable_disable;
13771
13772   /* send it... */
13773   S (mp);
13774   /* Wait for the reply */
13775   W (ret);
13776   return ret;
13777 }
13778
13779 static int
13780 api_cop_whitelist_enable_disable (vat_main_t * vam)
13781 {
13782   unformat_input_t *line_input = vam->input;
13783   vl_api_cop_whitelist_enable_disable_t *mp;
13784   u32 sw_if_index = ~0;
13785   u8 ip4 = 0, ip6 = 0, default_cop = 0;
13786   u32 fib_id = 0;
13787   int ret;
13788
13789   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13790     {
13791       if (unformat (line_input, "ip4"))
13792         ip4 = 1;
13793       else if (unformat (line_input, "ip6"))
13794         ip6 = 1;
13795       else if (unformat (line_input, "default"))
13796         default_cop = 1;
13797       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13798                          vam, &sw_if_index))
13799         ;
13800       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13801         ;
13802       else if (unformat (line_input, "fib-id %d", &fib_id))
13803         ;
13804       else
13805         break;
13806     }
13807
13808   if (sw_if_index == ~0)
13809     {
13810       errmsg ("missing interface name or sw_if_index");
13811       return -99;
13812     }
13813
13814   /* Construct the API message */
13815   M (COP_WHITELIST_ENABLE_DISABLE, mp);
13816   mp->sw_if_index = ntohl (sw_if_index);
13817   mp->fib_id = ntohl (fib_id);
13818   mp->ip4 = ip4;
13819   mp->ip6 = ip6;
13820   mp->default_cop = default_cop;
13821
13822   /* send it... */
13823   S (mp);
13824   /* Wait for the reply */
13825   W (ret);
13826   return ret;
13827 }
13828
13829 static int
13830 api_get_node_graph (vat_main_t * vam)
13831 {
13832   vl_api_get_node_graph_t *mp;
13833   int ret;
13834
13835   M (GET_NODE_GRAPH, mp);
13836
13837   /* send it... */
13838   S (mp);
13839   /* Wait for the reply */
13840   W (ret);
13841   return ret;
13842 }
13843
13844 /* *INDENT-OFF* */
13845 /** Used for parsing LISP eids */
13846 typedef CLIB_PACKED(struct{
13847   u8 addr[16];   /**< eid address */
13848   u32 len;       /**< prefix length if IP */
13849   u8 type;      /**< type of eid */
13850 }) lisp_eid_vat_t;
13851 /* *INDENT-ON* */
13852
13853 static uword
13854 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
13855 {
13856   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
13857
13858   memset (a, 0, sizeof (a[0]));
13859
13860   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
13861     {
13862       a->type = 0;              /* ipv4 type */
13863     }
13864   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
13865     {
13866       a->type = 1;              /* ipv6 type */
13867     }
13868   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
13869     {
13870       a->type = 2;              /* mac type */
13871     }
13872   else
13873     {
13874       return 0;
13875     }
13876
13877   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
13878     {
13879       return 0;
13880     }
13881
13882   return 1;
13883 }
13884
13885 static int
13886 lisp_eid_size_vat (u8 type)
13887 {
13888   switch (type)
13889     {
13890     case 0:
13891       return 4;
13892     case 1:
13893       return 16;
13894     case 2:
13895       return 6;
13896     }
13897   return 0;
13898 }
13899
13900 static void
13901 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
13902 {
13903   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
13904 }
13905
13906 static int
13907 api_one_add_del_locator_set (vat_main_t * vam)
13908 {
13909   unformat_input_t *input = vam->input;
13910   vl_api_one_add_del_locator_set_t *mp;
13911   u8 is_add = 1;
13912   u8 *locator_set_name = NULL;
13913   u8 locator_set_name_set = 0;
13914   vl_api_local_locator_t locator, *locators = 0;
13915   u32 sw_if_index, priority, weight;
13916   u32 data_len = 0;
13917
13918   int ret;
13919   /* Parse args required to build the message */
13920   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13921     {
13922       if (unformat (input, "del"))
13923         {
13924           is_add = 0;
13925         }
13926       else if (unformat (input, "locator-set %s", &locator_set_name))
13927         {
13928           locator_set_name_set = 1;
13929         }
13930       else if (unformat (input, "sw_if_index %u p %u w %u",
13931                          &sw_if_index, &priority, &weight))
13932         {
13933           locator.sw_if_index = htonl (sw_if_index);
13934           locator.priority = priority;
13935           locator.weight = weight;
13936           vec_add1 (locators, locator);
13937         }
13938       else
13939         if (unformat
13940             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
13941              &sw_if_index, &priority, &weight))
13942         {
13943           locator.sw_if_index = htonl (sw_if_index);
13944           locator.priority = priority;
13945           locator.weight = weight;
13946           vec_add1 (locators, locator);
13947         }
13948       else
13949         break;
13950     }
13951
13952   if (locator_set_name_set == 0)
13953     {
13954       errmsg ("missing locator-set name");
13955       vec_free (locators);
13956       return -99;
13957     }
13958
13959   if (vec_len (locator_set_name) > 64)
13960     {
13961       errmsg ("locator-set name too long");
13962       vec_free (locator_set_name);
13963       vec_free (locators);
13964       return -99;
13965     }
13966   vec_add1 (locator_set_name, 0);
13967
13968   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
13969
13970   /* Construct the API message */
13971   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
13972
13973   mp->is_add = is_add;
13974   clib_memcpy (mp->locator_set_name, locator_set_name,
13975                vec_len (locator_set_name));
13976   vec_free (locator_set_name);
13977
13978   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
13979   if (locators)
13980     clib_memcpy (mp->locators, locators, data_len);
13981   vec_free (locators);
13982
13983   /* send it... */
13984   S (mp);
13985
13986   /* Wait for a reply... */
13987   W (ret);
13988   return ret;
13989 }
13990
13991 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
13992
13993 static int
13994 api_one_add_del_locator (vat_main_t * vam)
13995 {
13996   unformat_input_t *input = vam->input;
13997   vl_api_one_add_del_locator_t *mp;
13998   u32 tmp_if_index = ~0;
13999   u32 sw_if_index = ~0;
14000   u8 sw_if_index_set = 0;
14001   u8 sw_if_index_if_name_set = 0;
14002   u32 priority = ~0;
14003   u8 priority_set = 0;
14004   u32 weight = ~0;
14005   u8 weight_set = 0;
14006   u8 is_add = 1;
14007   u8 *locator_set_name = NULL;
14008   u8 locator_set_name_set = 0;
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, "del"))
14015         {
14016           is_add = 0;
14017         }
14018       else if (unformat (input, "locator-set %s", &locator_set_name))
14019         {
14020           locator_set_name_set = 1;
14021         }
14022       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14023                          &tmp_if_index))
14024         {
14025           sw_if_index_if_name_set = 1;
14026           sw_if_index = tmp_if_index;
14027         }
14028       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14029         {
14030           sw_if_index_set = 1;
14031           sw_if_index = tmp_if_index;
14032         }
14033       else if (unformat (input, "p %d", &priority))
14034         {
14035           priority_set = 1;
14036         }
14037       else if (unformat (input, "w %d", &weight))
14038         {
14039           weight_set = 1;
14040         }
14041       else
14042         break;
14043     }
14044
14045   if (locator_set_name_set == 0)
14046     {
14047       errmsg ("missing locator-set name");
14048       return -99;
14049     }
14050
14051   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14052     {
14053       errmsg ("missing sw_if_index");
14054       vec_free (locator_set_name);
14055       return -99;
14056     }
14057
14058   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14059     {
14060       errmsg ("cannot use both params interface name and sw_if_index");
14061       vec_free (locator_set_name);
14062       return -99;
14063     }
14064
14065   if (priority_set == 0)
14066     {
14067       errmsg ("missing locator-set priority");
14068       vec_free (locator_set_name);
14069       return -99;
14070     }
14071
14072   if (weight_set == 0)
14073     {
14074       errmsg ("missing locator-set weight");
14075       vec_free (locator_set_name);
14076       return -99;
14077     }
14078
14079   if (vec_len (locator_set_name) > 64)
14080     {
14081       errmsg ("locator-set name too long");
14082       vec_free (locator_set_name);
14083       return -99;
14084     }
14085   vec_add1 (locator_set_name, 0);
14086
14087   /* Construct the API message */
14088   M (ONE_ADD_DEL_LOCATOR, mp);
14089
14090   mp->is_add = is_add;
14091   mp->sw_if_index = ntohl (sw_if_index);
14092   mp->priority = priority;
14093   mp->weight = weight;
14094   clib_memcpy (mp->locator_set_name, locator_set_name,
14095                vec_len (locator_set_name));
14096   vec_free (locator_set_name);
14097
14098   /* send it... */
14099   S (mp);
14100
14101   /* Wait for a reply... */
14102   W (ret);
14103   return ret;
14104 }
14105
14106 #define api_lisp_add_del_locator api_one_add_del_locator
14107
14108 uword
14109 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14110 {
14111   u32 *key_id = va_arg (*args, u32 *);
14112   u8 *s = 0;
14113
14114   if (unformat (input, "%s", &s))
14115     {
14116       if (!strcmp ((char *) s, "sha1"))
14117         key_id[0] = HMAC_SHA_1_96;
14118       else if (!strcmp ((char *) s, "sha256"))
14119         key_id[0] = HMAC_SHA_256_128;
14120       else
14121         {
14122           clib_warning ("invalid key_id: '%s'", s);
14123           key_id[0] = HMAC_NO_KEY;
14124         }
14125     }
14126   else
14127     return 0;
14128
14129   vec_free (s);
14130   return 1;
14131 }
14132
14133 static int
14134 api_one_add_del_local_eid (vat_main_t * vam)
14135 {
14136   unformat_input_t *input = vam->input;
14137   vl_api_one_add_del_local_eid_t *mp;
14138   u8 is_add = 1;
14139   u8 eid_set = 0;
14140   lisp_eid_vat_t _eid, *eid = &_eid;
14141   u8 *locator_set_name = 0;
14142   u8 locator_set_name_set = 0;
14143   u32 vni = 0;
14144   u16 key_id = 0;
14145   u8 *key = 0;
14146   int ret;
14147
14148   /* Parse args required to build the message */
14149   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14150     {
14151       if (unformat (input, "del"))
14152         {
14153           is_add = 0;
14154         }
14155       else if (unformat (input, "vni %d", &vni))
14156         {
14157           ;
14158         }
14159       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14160         {
14161           eid_set = 1;
14162         }
14163       else if (unformat (input, "locator-set %s", &locator_set_name))
14164         {
14165           locator_set_name_set = 1;
14166         }
14167       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14168         ;
14169       else if (unformat (input, "secret-key %_%v%_", &key))
14170         ;
14171       else
14172         break;
14173     }
14174
14175   if (locator_set_name_set == 0)
14176     {
14177       errmsg ("missing locator-set name");
14178       return -99;
14179     }
14180
14181   if (0 == eid_set)
14182     {
14183       errmsg ("EID address not set!");
14184       vec_free (locator_set_name);
14185       return -99;
14186     }
14187
14188   if (key && (0 == key_id))
14189     {
14190       errmsg ("invalid key_id!");
14191       return -99;
14192     }
14193
14194   if (vec_len (key) > 64)
14195     {
14196       errmsg ("key too long");
14197       vec_free (key);
14198       return -99;
14199     }
14200
14201   if (vec_len (locator_set_name) > 64)
14202     {
14203       errmsg ("locator-set name too long");
14204       vec_free (locator_set_name);
14205       return -99;
14206     }
14207   vec_add1 (locator_set_name, 0);
14208
14209   /* Construct the API message */
14210   M (ONE_ADD_DEL_LOCAL_EID, mp);
14211
14212   mp->is_add = is_add;
14213   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14214   mp->eid_type = eid->type;
14215   mp->prefix_len = eid->len;
14216   mp->vni = clib_host_to_net_u32 (vni);
14217   mp->key_id = clib_host_to_net_u16 (key_id);
14218   clib_memcpy (mp->locator_set_name, locator_set_name,
14219                vec_len (locator_set_name));
14220   clib_memcpy (mp->key, key, vec_len (key));
14221
14222   vec_free (locator_set_name);
14223   vec_free (key);
14224
14225   /* send it... */
14226   S (mp);
14227
14228   /* Wait for a reply... */
14229   W (ret);
14230   return ret;
14231 }
14232
14233 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14234
14235 static int
14236 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14237 {
14238   u32 dp_table = 0, vni = 0;;
14239   unformat_input_t *input = vam->input;
14240   vl_api_gpe_add_del_fwd_entry_t *mp;
14241   u8 is_add = 1;
14242   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14243   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14244   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14245   u32 action = ~0, w;
14246   ip4_address_t rmt_rloc4, lcl_rloc4;
14247   ip6_address_t rmt_rloc6, lcl_rloc6;
14248   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14249   int ret;
14250
14251   memset (&rloc, 0, sizeof (rloc));
14252
14253   /* Parse args required to build the message */
14254   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14255     {
14256       if (unformat (input, "del"))
14257         is_add = 0;
14258       else if (unformat (input, "add"))
14259         is_add = 1;
14260       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14261         {
14262           rmt_eid_set = 1;
14263         }
14264       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14265         {
14266           lcl_eid_set = 1;
14267         }
14268       else if (unformat (input, "vrf %d", &dp_table))
14269         ;
14270       else if (unformat (input, "bd %d", &dp_table))
14271         ;
14272       else if (unformat (input, "vni %d", &vni))
14273         ;
14274       else if (unformat (input, "w %d", &w))
14275         {
14276           if (!curr_rloc)
14277             {
14278               errmsg ("No RLOC configured for setting priority/weight!");
14279               return -99;
14280             }
14281           curr_rloc->weight = w;
14282         }
14283       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14284                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14285         {
14286           rloc.is_ip4 = 1;
14287
14288           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
14289           rloc.weight = 0;
14290           vec_add1 (lcl_locs, rloc);
14291
14292           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
14293           vec_add1 (rmt_locs, rloc);
14294           /* weight saved in rmt loc */
14295           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14296         }
14297       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14298                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14299         {
14300           rloc.is_ip4 = 0;
14301           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
14302           rloc.weight = 0;
14303           vec_add1 (lcl_locs, rloc);
14304
14305           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
14306           vec_add1 (rmt_locs, rloc);
14307           /* weight saved in rmt loc */
14308           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14309         }
14310       else if (unformat (input, "action %d", &action))
14311         {
14312           ;
14313         }
14314       else
14315         {
14316           clib_warning ("parse error '%U'", format_unformat_error, input);
14317           return -99;
14318         }
14319     }
14320
14321   if (!rmt_eid_set)
14322     {
14323       errmsg ("remote eid addresses not set");
14324       return -99;
14325     }
14326
14327   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14328     {
14329       errmsg ("eid types don't match");
14330       return -99;
14331     }
14332
14333   if (0 == rmt_locs && (u32) ~ 0 == action)
14334     {
14335       errmsg ("action not set for negative mapping");
14336       return -99;
14337     }
14338
14339   /* Construct the API message */
14340   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14341       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14342
14343   mp->is_add = is_add;
14344   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
14345   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
14346   mp->eid_type = rmt_eid->type;
14347   mp->dp_table = clib_host_to_net_u32 (dp_table);
14348   mp->vni = clib_host_to_net_u32 (vni);
14349   mp->rmt_len = rmt_eid->len;
14350   mp->lcl_len = lcl_eid->len;
14351   mp->action = action;
14352
14353   if (0 != rmt_locs && 0 != lcl_locs)
14354     {
14355       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14356       clib_memcpy (mp->locs, lcl_locs,
14357                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14358
14359       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14360       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14361                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14362     }
14363   vec_free (lcl_locs);
14364   vec_free (rmt_locs);
14365
14366   /* send it... */
14367   S (mp);
14368
14369   /* Wait for a reply... */
14370   W (ret);
14371   return ret;
14372 }
14373
14374 static int
14375 api_one_add_del_map_server (vat_main_t * vam)
14376 {
14377   unformat_input_t *input = vam->input;
14378   vl_api_one_add_del_map_server_t *mp;
14379   u8 is_add = 1;
14380   u8 ipv4_set = 0;
14381   u8 ipv6_set = 0;
14382   ip4_address_t ipv4;
14383   ip6_address_t ipv6;
14384   int ret;
14385
14386   /* Parse args required to build the message */
14387   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14388     {
14389       if (unformat (input, "del"))
14390         {
14391           is_add = 0;
14392         }
14393       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14394         {
14395           ipv4_set = 1;
14396         }
14397       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14398         {
14399           ipv6_set = 1;
14400         }
14401       else
14402         break;
14403     }
14404
14405   if (ipv4_set && ipv6_set)
14406     {
14407       errmsg ("both eid v4 and v6 addresses set");
14408       return -99;
14409     }
14410
14411   if (!ipv4_set && !ipv6_set)
14412     {
14413       errmsg ("eid addresses not set");
14414       return -99;
14415     }
14416
14417   /* Construct the API message */
14418   M (ONE_ADD_DEL_MAP_SERVER, mp);
14419
14420   mp->is_add = is_add;
14421   if (ipv6_set)
14422     {
14423       mp->is_ipv6 = 1;
14424       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14425     }
14426   else
14427     {
14428       mp->is_ipv6 = 0;
14429       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14430     }
14431
14432   /* send it... */
14433   S (mp);
14434
14435   /* Wait for a reply... */
14436   W (ret);
14437   return ret;
14438 }
14439
14440 #define api_lisp_add_del_map_server api_one_add_del_map_server
14441
14442 static int
14443 api_one_add_del_map_resolver (vat_main_t * vam)
14444 {
14445   unformat_input_t *input = vam->input;
14446   vl_api_one_add_del_map_resolver_t *mp;
14447   u8 is_add = 1;
14448   u8 ipv4_set = 0;
14449   u8 ipv6_set = 0;
14450   ip4_address_t ipv4;
14451   ip6_address_t ipv6;
14452   int ret;
14453
14454   /* Parse args required to build the message */
14455   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14456     {
14457       if (unformat (input, "del"))
14458         {
14459           is_add = 0;
14460         }
14461       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14462         {
14463           ipv4_set = 1;
14464         }
14465       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14466         {
14467           ipv6_set = 1;
14468         }
14469       else
14470         break;
14471     }
14472
14473   if (ipv4_set && ipv6_set)
14474     {
14475       errmsg ("both eid v4 and v6 addresses set");
14476       return -99;
14477     }
14478
14479   if (!ipv4_set && !ipv6_set)
14480     {
14481       errmsg ("eid addresses not set");
14482       return -99;
14483     }
14484
14485   /* Construct the API message */
14486   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14487
14488   mp->is_add = is_add;
14489   if (ipv6_set)
14490     {
14491       mp->is_ipv6 = 1;
14492       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14493     }
14494   else
14495     {
14496       mp->is_ipv6 = 0;
14497       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14498     }
14499
14500   /* send it... */
14501   S (mp);
14502
14503   /* Wait for a reply... */
14504   W (ret);
14505   return ret;
14506 }
14507
14508 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14509
14510 static int
14511 api_lisp_gpe_enable_disable (vat_main_t * vam)
14512 {
14513   unformat_input_t *input = vam->input;
14514   vl_api_gpe_enable_disable_t *mp;
14515   u8 is_set = 0;
14516   u8 is_en = 1;
14517   int ret;
14518
14519   /* Parse args required to build the message */
14520   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14521     {
14522       if (unformat (input, "enable"))
14523         {
14524           is_set = 1;
14525           is_en = 1;
14526         }
14527       else if (unformat (input, "disable"))
14528         {
14529           is_set = 1;
14530           is_en = 0;
14531         }
14532       else
14533         break;
14534     }
14535
14536   if (is_set == 0)
14537     {
14538       errmsg ("Value not set");
14539       return -99;
14540     }
14541
14542   /* Construct the API message */
14543   M (GPE_ENABLE_DISABLE, mp);
14544
14545   mp->is_en = is_en;
14546
14547   /* send it... */
14548   S (mp);
14549
14550   /* Wait for a reply... */
14551   W (ret);
14552   return ret;
14553 }
14554
14555 static int
14556 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14557 {
14558   unformat_input_t *input = vam->input;
14559   vl_api_one_rloc_probe_enable_disable_t *mp;
14560   u8 is_set = 0;
14561   u8 is_en = 0;
14562   int ret;
14563
14564   /* Parse args required to build the message */
14565   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14566     {
14567       if (unformat (input, "enable"))
14568         {
14569           is_set = 1;
14570           is_en = 1;
14571         }
14572       else if (unformat (input, "disable"))
14573         is_set = 1;
14574       else
14575         break;
14576     }
14577
14578   if (!is_set)
14579     {
14580       errmsg ("Value not set");
14581       return -99;
14582     }
14583
14584   /* Construct the API message */
14585   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14586
14587   mp->is_enabled = is_en;
14588
14589   /* send it... */
14590   S (mp);
14591
14592   /* Wait for a reply... */
14593   W (ret);
14594   return ret;
14595 }
14596
14597 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14598
14599 static int
14600 api_one_map_register_enable_disable (vat_main_t * vam)
14601 {
14602   unformat_input_t *input = vam->input;
14603   vl_api_one_map_register_enable_disable_t *mp;
14604   u8 is_set = 0;
14605   u8 is_en = 0;
14606   int ret;
14607
14608   /* Parse args required to build the message */
14609   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14610     {
14611       if (unformat (input, "enable"))
14612         {
14613           is_set = 1;
14614           is_en = 1;
14615         }
14616       else if (unformat (input, "disable"))
14617         is_set = 1;
14618       else
14619         break;
14620     }
14621
14622   if (!is_set)
14623     {
14624       errmsg ("Value not set");
14625       return -99;
14626     }
14627
14628   /* Construct the API message */
14629   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14630
14631   mp->is_enabled = is_en;
14632
14633   /* send it... */
14634   S (mp);
14635
14636   /* Wait for a reply... */
14637   W (ret);
14638   return ret;
14639 }
14640
14641 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14642
14643 static int
14644 api_one_enable_disable (vat_main_t * vam)
14645 {
14646   unformat_input_t *input = vam->input;
14647   vl_api_one_enable_disable_t *mp;
14648   u8 is_set = 0;
14649   u8 is_en = 0;
14650   int ret;
14651
14652   /* Parse args required to build the message */
14653   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14654     {
14655       if (unformat (input, "enable"))
14656         {
14657           is_set = 1;
14658           is_en = 1;
14659         }
14660       else if (unformat (input, "disable"))
14661         {
14662           is_set = 1;
14663         }
14664       else
14665         break;
14666     }
14667
14668   if (!is_set)
14669     {
14670       errmsg ("Value not set");
14671       return -99;
14672     }
14673
14674   /* Construct the API message */
14675   M (ONE_ENABLE_DISABLE, mp);
14676
14677   mp->is_en = is_en;
14678
14679   /* send it... */
14680   S (mp);
14681
14682   /* Wait for a reply... */
14683   W (ret);
14684   return ret;
14685 }
14686
14687 #define api_lisp_enable_disable api_one_enable_disable
14688
14689 static int
14690 api_show_one_map_register_state (vat_main_t * vam)
14691 {
14692   vl_api_show_one_map_register_state_t *mp;
14693   int ret;
14694
14695   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
14696
14697   /* send */
14698   S (mp);
14699
14700   /* wait for reply */
14701   W (ret);
14702   return ret;
14703 }
14704
14705 #define api_show_lisp_map_register_state api_show_one_map_register_state
14706
14707 static int
14708 api_show_one_rloc_probe_state (vat_main_t * vam)
14709 {
14710   vl_api_show_one_rloc_probe_state_t *mp;
14711   int ret;
14712
14713   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
14714
14715   /* send */
14716   S (mp);
14717
14718   /* wait for reply */
14719   W (ret);
14720   return ret;
14721 }
14722
14723 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
14724
14725 static int
14726 api_one_stats_enable_disable (vat_main_t * vam)
14727 {
14728   vl_api_one_stats_enable_disable_t *mp;
14729   unformat_input_t *input = vam->input;
14730   u8 is_set = 0;
14731   u8 is_en = 0;
14732   int ret;
14733
14734   /* Parse args required to build the message */
14735   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14736     {
14737       if (unformat (input, "enable"))
14738         {
14739           is_set = 1;
14740           is_en = 1;
14741         }
14742       else if (unformat (input, "disable"))
14743         {
14744           is_set = 1;
14745         }
14746       else
14747         break;
14748     }
14749
14750   if (!is_set)
14751     {
14752       errmsg ("Value not set");
14753       return -99;
14754     }
14755
14756   M (ONE_STATS_ENABLE_DISABLE, mp);
14757   mp->is_en = is_en;
14758
14759   /* send */
14760   S (mp);
14761
14762   /* wait for reply */
14763   W (ret);
14764   return ret;
14765 }
14766
14767 static int
14768 api_show_one_stats_enable_disable (vat_main_t * vam)
14769 {
14770   vl_api_show_one_stats_enable_disable_t *mp;
14771   int ret;
14772
14773   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
14774
14775   /* send */
14776   S (mp);
14777
14778   /* wait for reply */
14779   W (ret);
14780   return ret;
14781 }
14782
14783 static int
14784 api_show_one_map_request_mode (vat_main_t * vam)
14785 {
14786   vl_api_show_one_map_request_mode_t *mp;
14787   int ret;
14788
14789   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
14790
14791   /* send */
14792   S (mp);
14793
14794   /* wait for reply */
14795   W (ret);
14796   return ret;
14797 }
14798
14799 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
14800
14801 static int
14802 api_one_map_request_mode (vat_main_t * vam)
14803 {
14804   unformat_input_t *input = vam->input;
14805   vl_api_one_map_request_mode_t *mp;
14806   u8 mode = 0;
14807   int ret;
14808
14809   /* Parse args required to build the message */
14810   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14811     {
14812       if (unformat (input, "dst-only"))
14813         mode = 0;
14814       else if (unformat (input, "src-dst"))
14815         mode = 1;
14816       else
14817         {
14818           errmsg ("parse error '%U'", format_unformat_error, input);
14819           return -99;
14820         }
14821     }
14822
14823   M (ONE_MAP_REQUEST_MODE, mp);
14824
14825   mp->mode = mode;
14826
14827   /* send */
14828   S (mp);
14829
14830   /* wait for reply */
14831   W (ret);
14832   return ret;
14833 }
14834
14835 #define api_lisp_map_request_mode api_one_map_request_mode
14836
14837 /**
14838  * Enable/disable ONE proxy ITR.
14839  *
14840  * @param vam vpp API test context
14841  * @return return code
14842  */
14843 static int
14844 api_one_pitr_set_locator_set (vat_main_t * vam)
14845 {
14846   u8 ls_name_set = 0;
14847   unformat_input_t *input = vam->input;
14848   vl_api_one_pitr_set_locator_set_t *mp;
14849   u8 is_add = 1;
14850   u8 *ls_name = 0;
14851   int ret;
14852
14853   /* Parse args required to build the message */
14854   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14855     {
14856       if (unformat (input, "del"))
14857         is_add = 0;
14858       else if (unformat (input, "locator-set %s", &ls_name))
14859         ls_name_set = 1;
14860       else
14861         {
14862           errmsg ("parse error '%U'", format_unformat_error, input);
14863           return -99;
14864         }
14865     }
14866
14867   if (!ls_name_set)
14868     {
14869       errmsg ("locator-set name not set!");
14870       return -99;
14871     }
14872
14873   M (ONE_PITR_SET_LOCATOR_SET, mp);
14874
14875   mp->is_add = is_add;
14876   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
14877   vec_free (ls_name);
14878
14879   /* send */
14880   S (mp);
14881
14882   /* wait for reply */
14883   W (ret);
14884   return ret;
14885 }
14886
14887 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
14888
14889 static int
14890 api_show_one_pitr (vat_main_t * vam)
14891 {
14892   vl_api_show_one_pitr_t *mp;
14893   int ret;
14894
14895   if (!vam->json_output)
14896     {
14897       print (vam->ofp, "%=20s", "lisp status:");
14898     }
14899
14900   M (SHOW_ONE_PITR, mp);
14901   /* send it... */
14902   S (mp);
14903
14904   /* Wait for a reply... */
14905   W (ret);
14906   return ret;
14907 }
14908
14909 #define api_show_lisp_pitr api_show_one_pitr
14910
14911 static int
14912 api_one_use_petr (vat_main_t * vam)
14913 {
14914   unformat_input_t *input = vam->input;
14915   vl_api_one_use_petr_t *mp;
14916   u8 is_add = 0;
14917   ip_address_t ip;
14918   int ret;
14919
14920   memset (&ip, 0, sizeof (ip));
14921
14922   /* Parse args required to build the message */
14923   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14924     {
14925       if (unformat (input, "disable"))
14926         is_add = 0;
14927       else
14928         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
14929         {
14930           is_add = 1;
14931           ip_addr_version (&ip) = IP4;
14932         }
14933       else
14934         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
14935         {
14936           is_add = 1;
14937           ip_addr_version (&ip) = IP6;
14938         }
14939       else
14940         {
14941           errmsg ("parse error '%U'", format_unformat_error, input);
14942           return -99;
14943         }
14944     }
14945
14946   M (ONE_USE_PETR, mp);
14947
14948   mp->is_add = is_add;
14949   if (is_add)
14950     {
14951       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
14952       if (mp->is_ip4)
14953         clib_memcpy (mp->address, &ip, 4);
14954       else
14955         clib_memcpy (mp->address, &ip, 16);
14956     }
14957
14958   /* send */
14959   S (mp);
14960
14961   /* wait for reply */
14962   W (ret);
14963   return ret;
14964 }
14965
14966 #define api_lisp_use_petr api_one_use_petr
14967
14968 static int
14969 api_show_one_use_petr (vat_main_t * vam)
14970 {
14971   vl_api_show_one_use_petr_t *mp;
14972   int ret;
14973
14974   if (!vam->json_output)
14975     {
14976       print (vam->ofp, "%=20s", "Proxy-ETR status:");
14977     }
14978
14979   M (SHOW_ONE_USE_PETR, mp);
14980   /* send it... */
14981   S (mp);
14982
14983   /* Wait for a reply... */
14984   W (ret);
14985   return ret;
14986 }
14987
14988 #define api_show_lisp_use_petr api_show_one_use_petr
14989
14990 /**
14991  * Add/delete mapping between vni and vrf
14992  */
14993 static int
14994 api_one_eid_table_add_del_map (vat_main_t * vam)
14995 {
14996   unformat_input_t *input = vam->input;
14997   vl_api_one_eid_table_add_del_map_t *mp;
14998   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
14999   u32 vni, vrf, bd_index;
15000   int ret;
15001
15002   /* Parse args required to build the message */
15003   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15004     {
15005       if (unformat (input, "del"))
15006         is_add = 0;
15007       else if (unformat (input, "vrf %d", &vrf))
15008         vrf_set = 1;
15009       else if (unformat (input, "bd_index %d", &bd_index))
15010         bd_index_set = 1;
15011       else if (unformat (input, "vni %d", &vni))
15012         vni_set = 1;
15013       else
15014         break;
15015     }
15016
15017   if (!vni_set || (!vrf_set && !bd_index_set))
15018     {
15019       errmsg ("missing arguments!");
15020       return -99;
15021     }
15022
15023   if (vrf_set && bd_index_set)
15024     {
15025       errmsg ("error: both vrf and bd entered!");
15026       return -99;
15027     }
15028
15029   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15030
15031   mp->is_add = is_add;
15032   mp->vni = htonl (vni);
15033   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15034   mp->is_l2 = bd_index_set;
15035
15036   /* send */
15037   S (mp);
15038
15039   /* wait for reply */
15040   W (ret);
15041   return ret;
15042 }
15043
15044 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15045
15046 uword
15047 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15048 {
15049   u32 *action = va_arg (*args, u32 *);
15050   u8 *s = 0;
15051
15052   if (unformat (input, "%s", &s))
15053     {
15054       if (!strcmp ((char *) s, "no-action"))
15055         action[0] = 0;
15056       else if (!strcmp ((char *) s, "natively-forward"))
15057         action[0] = 1;
15058       else if (!strcmp ((char *) s, "send-map-request"))
15059         action[0] = 2;
15060       else if (!strcmp ((char *) s, "drop"))
15061         action[0] = 3;
15062       else
15063         {
15064           clib_warning ("invalid action: '%s'", s);
15065           action[0] = 3;
15066         }
15067     }
15068   else
15069     return 0;
15070
15071   vec_free (s);
15072   return 1;
15073 }
15074
15075 /**
15076  * Add/del remote mapping to/from ONE control plane
15077  *
15078  * @param vam vpp API test context
15079  * @return return code
15080  */
15081 static int
15082 api_one_add_del_remote_mapping (vat_main_t * vam)
15083 {
15084   unformat_input_t *input = vam->input;
15085   vl_api_one_add_del_remote_mapping_t *mp;
15086   u32 vni = 0;
15087   lisp_eid_vat_t _eid, *eid = &_eid;
15088   lisp_eid_vat_t _seid, *seid = &_seid;
15089   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15090   u32 action = ~0, p, w, data_len;
15091   ip4_address_t rloc4;
15092   ip6_address_t rloc6;
15093   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15094   int ret;
15095
15096   memset (&rloc, 0, sizeof (rloc));
15097
15098   /* Parse args required to build the message */
15099   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15100     {
15101       if (unformat (input, "del-all"))
15102         {
15103           del_all = 1;
15104         }
15105       else if (unformat (input, "del"))
15106         {
15107           is_add = 0;
15108         }
15109       else if (unformat (input, "add"))
15110         {
15111           is_add = 1;
15112         }
15113       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15114         {
15115           eid_set = 1;
15116         }
15117       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15118         {
15119           seid_set = 1;
15120         }
15121       else if (unformat (input, "vni %d", &vni))
15122         {
15123           ;
15124         }
15125       else if (unformat (input, "p %d w %d", &p, &w))
15126         {
15127           if (!curr_rloc)
15128             {
15129               errmsg ("No RLOC configured for setting priority/weight!");
15130               return -99;
15131             }
15132           curr_rloc->priority = p;
15133           curr_rloc->weight = w;
15134         }
15135       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15136         {
15137           rloc.is_ip4 = 1;
15138           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
15139           vec_add1 (rlocs, rloc);
15140           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15141         }
15142       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15143         {
15144           rloc.is_ip4 = 0;
15145           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
15146           vec_add1 (rlocs, rloc);
15147           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15148         }
15149       else if (unformat (input, "action %U",
15150                          unformat_negative_mapping_action, &action))
15151         {
15152           ;
15153         }
15154       else
15155         {
15156           clib_warning ("parse error '%U'", format_unformat_error, input);
15157           return -99;
15158         }
15159     }
15160
15161   if (0 == eid_set)
15162     {
15163       errmsg ("missing params!");
15164       return -99;
15165     }
15166
15167   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15168     {
15169       errmsg ("no action set for negative map-reply!");
15170       return -99;
15171     }
15172
15173   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15174
15175   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15176   mp->is_add = is_add;
15177   mp->vni = htonl (vni);
15178   mp->action = (u8) action;
15179   mp->is_src_dst = seid_set;
15180   mp->eid_len = eid->len;
15181   mp->seid_len = seid->len;
15182   mp->del_all = del_all;
15183   mp->eid_type = eid->type;
15184   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15185   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
15186
15187   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15188   clib_memcpy (mp->rlocs, rlocs, data_len);
15189   vec_free (rlocs);
15190
15191   /* send it... */
15192   S (mp);
15193
15194   /* Wait for a reply... */
15195   W (ret);
15196   return ret;
15197 }
15198
15199 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15200
15201 /**
15202  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15203  * forwarding entries in data-plane accordingly.
15204  *
15205  * @param vam vpp API test context
15206  * @return return code
15207  */
15208 static int
15209 api_one_add_del_adjacency (vat_main_t * vam)
15210 {
15211   unformat_input_t *input = vam->input;
15212   vl_api_one_add_del_adjacency_t *mp;
15213   u32 vni = 0;
15214   ip4_address_t leid4, reid4;
15215   ip6_address_t leid6, reid6;
15216   u8 reid_mac[6] = { 0 };
15217   u8 leid_mac[6] = { 0 };
15218   u8 reid_type, leid_type;
15219   u32 leid_len = 0, reid_len = 0, len;
15220   u8 is_add = 1;
15221   int ret;
15222
15223   leid_type = reid_type = (u8) ~ 0;
15224
15225   /* Parse args required to build the message */
15226   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15227     {
15228       if (unformat (input, "del"))
15229         {
15230           is_add = 0;
15231         }
15232       else if (unformat (input, "add"))
15233         {
15234           is_add = 1;
15235         }
15236       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
15237                          &reid4, &len))
15238         {
15239           reid_type = 0;        /* ipv4 */
15240           reid_len = len;
15241         }
15242       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
15243                          &reid6, &len))
15244         {
15245           reid_type = 1;        /* ipv6 */
15246           reid_len = len;
15247         }
15248       else if (unformat (input, "reid %U", unformat_ethernet_address,
15249                          reid_mac))
15250         {
15251           reid_type = 2;        /* mac */
15252         }
15253       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
15254                          &leid4, &len))
15255         {
15256           leid_type = 0;        /* ipv4 */
15257           leid_len = len;
15258         }
15259       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
15260                          &leid6, &len))
15261         {
15262           leid_type = 1;        /* ipv6 */
15263           leid_len = len;
15264         }
15265       else if (unformat (input, "leid %U", unformat_ethernet_address,
15266                          leid_mac))
15267         {
15268           leid_type = 2;        /* mac */
15269         }
15270       else if (unformat (input, "vni %d", &vni))
15271         {
15272           ;
15273         }
15274       else
15275         {
15276           errmsg ("parse error '%U'", format_unformat_error, input);
15277           return -99;
15278         }
15279     }
15280
15281   if ((u8) ~ 0 == reid_type)
15282     {
15283       errmsg ("missing params!");
15284       return -99;
15285     }
15286
15287   if (leid_type != reid_type)
15288     {
15289       errmsg ("remote and local EIDs are of different types!");
15290       return -99;
15291     }
15292
15293   M (ONE_ADD_DEL_ADJACENCY, mp);
15294   mp->is_add = is_add;
15295   mp->vni = htonl (vni);
15296   mp->leid_len = leid_len;
15297   mp->reid_len = reid_len;
15298   mp->eid_type = reid_type;
15299
15300   switch (mp->eid_type)
15301     {
15302     case 0:
15303       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
15304       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
15305       break;
15306     case 1:
15307       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
15308       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
15309       break;
15310     case 2:
15311       clib_memcpy (mp->leid, leid_mac, 6);
15312       clib_memcpy (mp->reid, reid_mac, 6);
15313       break;
15314     default:
15315       errmsg ("unknown EID type %d!", mp->eid_type);
15316       return 0;
15317     }
15318
15319   /* send it... */
15320   S (mp);
15321
15322   /* Wait for a reply... */
15323   W (ret);
15324   return ret;
15325 }
15326
15327 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
15328
15329 uword
15330 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
15331 {
15332   u32 *mode = va_arg (*args, u32 *);
15333
15334   if (unformat (input, "lisp"))
15335     *mode = 0;
15336   else if (unformat (input, "vxlan"))
15337     *mode = 1;
15338   else
15339     return 0;
15340
15341   return 1;
15342 }
15343
15344 static int
15345 api_gpe_get_encap_mode (vat_main_t * vam)
15346 {
15347   vl_api_gpe_get_encap_mode_t *mp;
15348   int ret;
15349
15350   /* Construct the API message */
15351   M (GPE_GET_ENCAP_MODE, mp);
15352
15353   /* send it... */
15354   S (mp);
15355
15356   /* Wait for a reply... */
15357   W (ret);
15358   return ret;
15359 }
15360
15361 static int
15362 api_gpe_set_encap_mode (vat_main_t * vam)
15363 {
15364   unformat_input_t *input = vam->input;
15365   vl_api_gpe_set_encap_mode_t *mp;
15366   int ret;
15367   u32 mode = 0;
15368
15369   /* Parse args required to build the message */
15370   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15371     {
15372       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
15373         ;
15374       else
15375         break;
15376     }
15377
15378   /* Construct the API message */
15379   M (GPE_SET_ENCAP_MODE, mp);
15380
15381   mp->mode = mode;
15382
15383   /* send it... */
15384   S (mp);
15385
15386   /* Wait for a reply... */
15387   W (ret);
15388   return ret;
15389 }
15390
15391 static int
15392 api_lisp_gpe_add_del_iface (vat_main_t * vam)
15393 {
15394   unformat_input_t *input = vam->input;
15395   vl_api_gpe_add_del_iface_t *mp;
15396   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
15397   u32 dp_table = 0, vni = 0;
15398   int ret;
15399
15400   /* Parse args required to build the message */
15401   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15402     {
15403       if (unformat (input, "up"))
15404         {
15405           action_set = 1;
15406           is_add = 1;
15407         }
15408       else if (unformat (input, "down"))
15409         {
15410           action_set = 1;
15411           is_add = 0;
15412         }
15413       else if (unformat (input, "table_id %d", &dp_table))
15414         {
15415           dp_table_set = 1;
15416         }
15417       else if (unformat (input, "bd_id %d", &dp_table))
15418         {
15419           dp_table_set = 1;
15420           is_l2 = 1;
15421         }
15422       else if (unformat (input, "vni %d", &vni))
15423         {
15424           vni_set = 1;
15425         }
15426       else
15427         break;
15428     }
15429
15430   if (action_set == 0)
15431     {
15432       errmsg ("Action not set");
15433       return -99;
15434     }
15435   if (dp_table_set == 0 || vni_set == 0)
15436     {
15437       errmsg ("vni and dp_table must be set");
15438       return -99;
15439     }
15440
15441   /* Construct the API message */
15442   M (GPE_ADD_DEL_IFACE, mp);
15443
15444   mp->is_add = is_add;
15445   mp->dp_table = dp_table;
15446   mp->is_l2 = is_l2;
15447   mp->vni = vni;
15448
15449   /* send it... */
15450   S (mp);
15451
15452   /* Wait for a reply... */
15453   W (ret);
15454   return ret;
15455 }
15456
15457 /**
15458  * Add/del map request itr rlocs from ONE control plane and updates
15459  *
15460  * @param vam vpp API test context
15461  * @return return code
15462  */
15463 static int
15464 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
15465 {
15466   unformat_input_t *input = vam->input;
15467   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
15468   u8 *locator_set_name = 0;
15469   u8 locator_set_name_set = 0;
15470   u8 is_add = 1;
15471   int ret;
15472
15473   /* Parse args required to build the message */
15474   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15475     {
15476       if (unformat (input, "del"))
15477         {
15478           is_add = 0;
15479         }
15480       else if (unformat (input, "%_%v%_", &locator_set_name))
15481         {
15482           locator_set_name_set = 1;
15483         }
15484       else
15485         {
15486           clib_warning ("parse error '%U'", format_unformat_error, input);
15487           return -99;
15488         }
15489     }
15490
15491   if (is_add && !locator_set_name_set)
15492     {
15493       errmsg ("itr-rloc is not set!");
15494       return -99;
15495     }
15496
15497   if (is_add && vec_len (locator_set_name) > 64)
15498     {
15499       errmsg ("itr-rloc locator-set name too long");
15500       vec_free (locator_set_name);
15501       return -99;
15502     }
15503
15504   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
15505   mp->is_add = is_add;
15506   if (is_add)
15507     {
15508       clib_memcpy (mp->locator_set_name, locator_set_name,
15509                    vec_len (locator_set_name));
15510     }
15511   else
15512     {
15513       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
15514     }
15515   vec_free (locator_set_name);
15516
15517   /* send it... */
15518   S (mp);
15519
15520   /* Wait for a reply... */
15521   W (ret);
15522   return ret;
15523 }
15524
15525 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
15526
15527 static int
15528 api_one_locator_dump (vat_main_t * vam)
15529 {
15530   unformat_input_t *input = vam->input;
15531   vl_api_one_locator_dump_t *mp;
15532   vl_api_control_ping_t *mp_ping;
15533   u8 is_index_set = 0, is_name_set = 0;
15534   u8 *ls_name = 0;
15535   u32 ls_index = ~0;
15536   int ret;
15537
15538   /* Parse args required to build the message */
15539   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15540     {
15541       if (unformat (input, "ls_name %_%v%_", &ls_name))
15542         {
15543           is_name_set = 1;
15544         }
15545       else if (unformat (input, "ls_index %d", &ls_index))
15546         {
15547           is_index_set = 1;
15548         }
15549       else
15550         {
15551           errmsg ("parse error '%U'", format_unformat_error, input);
15552           return -99;
15553         }
15554     }
15555
15556   if (!is_index_set && !is_name_set)
15557     {
15558       errmsg ("error: expected one of index or name!");
15559       return -99;
15560     }
15561
15562   if (is_index_set && is_name_set)
15563     {
15564       errmsg ("error: only one param expected!");
15565       return -99;
15566     }
15567
15568   if (vec_len (ls_name) > 62)
15569     {
15570       errmsg ("error: locator set name too long!");
15571       return -99;
15572     }
15573
15574   if (!vam->json_output)
15575     {
15576       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
15577     }
15578
15579   M (ONE_LOCATOR_DUMP, mp);
15580   mp->is_index_set = is_index_set;
15581
15582   if (is_index_set)
15583     mp->ls_index = clib_host_to_net_u32 (ls_index);
15584   else
15585     {
15586       vec_add1 (ls_name, 0);
15587       strncpy ((char *) mp->ls_name, (char *) ls_name,
15588                sizeof (mp->ls_name) - 1);
15589     }
15590
15591   /* send it... */
15592   S (mp);
15593
15594   /* Use a control ping for synchronization */
15595   M (CONTROL_PING, mp_ping);
15596   S (mp_ping);
15597
15598   /* Wait for a reply... */
15599   W (ret);
15600   return ret;
15601 }
15602
15603 #define api_lisp_locator_dump api_one_locator_dump
15604
15605 static int
15606 api_one_locator_set_dump (vat_main_t * vam)
15607 {
15608   vl_api_one_locator_set_dump_t *mp;
15609   vl_api_control_ping_t *mp_ping;
15610   unformat_input_t *input = vam->input;
15611   u8 filter = 0;
15612   int ret;
15613
15614   /* Parse args required to build the message */
15615   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15616     {
15617       if (unformat (input, "local"))
15618         {
15619           filter = 1;
15620         }
15621       else if (unformat (input, "remote"))
15622         {
15623           filter = 2;
15624         }
15625       else
15626         {
15627           errmsg ("parse error '%U'", format_unformat_error, input);
15628           return -99;
15629         }
15630     }
15631
15632   if (!vam->json_output)
15633     {
15634       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
15635     }
15636
15637   M (ONE_LOCATOR_SET_DUMP, mp);
15638
15639   mp->filter = filter;
15640
15641   /* send it... */
15642   S (mp);
15643
15644   /* Use a control ping for synchronization */
15645   M (CONTROL_PING, mp_ping);
15646   S (mp_ping);
15647
15648   /* Wait for a reply... */
15649   W (ret);
15650   return ret;
15651 }
15652
15653 #define api_lisp_locator_set_dump api_one_locator_set_dump
15654
15655 static int
15656 api_one_eid_table_map_dump (vat_main_t * vam)
15657 {
15658   u8 is_l2 = 0;
15659   u8 mode_set = 0;
15660   unformat_input_t *input = vam->input;
15661   vl_api_one_eid_table_map_dump_t *mp;
15662   vl_api_control_ping_t *mp_ping;
15663   int ret;
15664
15665   /* Parse args required to build the message */
15666   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15667     {
15668       if (unformat (input, "l2"))
15669         {
15670           is_l2 = 1;
15671           mode_set = 1;
15672         }
15673       else if (unformat (input, "l3"))
15674         {
15675           is_l2 = 0;
15676           mode_set = 1;
15677         }
15678       else
15679         {
15680           errmsg ("parse error '%U'", format_unformat_error, input);
15681           return -99;
15682         }
15683     }
15684
15685   if (!mode_set)
15686     {
15687       errmsg ("expected one of 'l2' or 'l3' parameter!");
15688       return -99;
15689     }
15690
15691   if (!vam->json_output)
15692     {
15693       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
15694     }
15695
15696   M (ONE_EID_TABLE_MAP_DUMP, mp);
15697   mp->is_l2 = is_l2;
15698
15699   /* send it... */
15700   S (mp);
15701
15702   /* Use a control ping for synchronization */
15703   M (CONTROL_PING, mp_ping);
15704   S (mp_ping);
15705
15706   /* Wait for a reply... */
15707   W (ret);
15708   return ret;
15709 }
15710
15711 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
15712
15713 static int
15714 api_one_eid_table_vni_dump (vat_main_t * vam)
15715 {
15716   vl_api_one_eid_table_vni_dump_t *mp;
15717   vl_api_control_ping_t *mp_ping;
15718   int ret;
15719
15720   if (!vam->json_output)
15721     {
15722       print (vam->ofp, "VNI");
15723     }
15724
15725   M (ONE_EID_TABLE_VNI_DUMP, mp);
15726
15727   /* send it... */
15728   S (mp);
15729
15730   /* Use a control ping for synchronization */
15731   M (CONTROL_PING, mp_ping);
15732   S (mp_ping);
15733
15734   /* Wait for a reply... */
15735   W (ret);
15736   return ret;
15737 }
15738
15739 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
15740
15741 static int
15742 api_one_eid_table_dump (vat_main_t * vam)
15743 {
15744   unformat_input_t *i = vam->input;
15745   vl_api_one_eid_table_dump_t *mp;
15746   vl_api_control_ping_t *mp_ping;
15747   struct in_addr ip4;
15748   struct in6_addr ip6;
15749   u8 mac[6];
15750   u8 eid_type = ~0, eid_set = 0;
15751   u32 prefix_length = ~0, t, vni = 0;
15752   u8 filter = 0;
15753   int ret;
15754
15755   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15756     {
15757       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
15758         {
15759           eid_set = 1;
15760           eid_type = 0;
15761           prefix_length = t;
15762         }
15763       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
15764         {
15765           eid_set = 1;
15766           eid_type = 1;
15767           prefix_length = t;
15768         }
15769       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
15770         {
15771           eid_set = 1;
15772           eid_type = 2;
15773         }
15774       else if (unformat (i, "vni %d", &t))
15775         {
15776           vni = t;
15777         }
15778       else if (unformat (i, "local"))
15779         {
15780           filter = 1;
15781         }
15782       else if (unformat (i, "remote"))
15783         {
15784           filter = 2;
15785         }
15786       else
15787         {
15788           errmsg ("parse error '%U'", format_unformat_error, i);
15789           return -99;
15790         }
15791     }
15792
15793   if (!vam->json_output)
15794     {
15795       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
15796              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
15797     }
15798
15799   M (ONE_EID_TABLE_DUMP, mp);
15800
15801   mp->filter = filter;
15802   if (eid_set)
15803     {
15804       mp->eid_set = 1;
15805       mp->vni = htonl (vni);
15806       mp->eid_type = eid_type;
15807       switch (eid_type)
15808         {
15809         case 0:
15810           mp->prefix_length = prefix_length;
15811           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
15812           break;
15813         case 1:
15814           mp->prefix_length = prefix_length;
15815           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
15816           break;
15817         case 2:
15818           clib_memcpy (mp->eid, mac, sizeof (mac));
15819           break;
15820         default:
15821           errmsg ("unknown EID type %d!", eid_type);
15822           return -99;
15823         }
15824     }
15825
15826   /* send it... */
15827   S (mp);
15828
15829   /* Use a control ping for synchronization */
15830   M (CONTROL_PING, mp_ping);
15831   S (mp_ping);
15832
15833   /* Wait for a reply... */
15834   W (ret);
15835   return ret;
15836 }
15837
15838 #define api_lisp_eid_table_dump api_one_eid_table_dump
15839
15840 static int
15841 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
15842 {
15843   unformat_input_t *i = vam->input;
15844   vl_api_gpe_fwd_entries_get_t *mp;
15845   u8 vni_set = 0;
15846   u32 vni = ~0;
15847   int ret;
15848
15849   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15850     {
15851       if (unformat (i, "vni %d", &vni))
15852         {
15853           vni_set = 1;
15854         }
15855       else
15856         {
15857           errmsg ("parse error '%U'", format_unformat_error, i);
15858           return -99;
15859         }
15860     }
15861
15862   if (!vni_set)
15863     {
15864       errmsg ("vni not set!");
15865       return -99;
15866     }
15867
15868   if (!vam->json_output)
15869     {
15870       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
15871              "leid", "reid");
15872     }
15873
15874   M (GPE_FWD_ENTRIES_GET, mp);
15875   mp->vni = clib_host_to_net_u32 (vni);
15876
15877   /* send it... */
15878   S (mp);
15879
15880   /* Wait for a reply... */
15881   W (ret);
15882   return ret;
15883 }
15884
15885 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
15886 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
15887 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
15888 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
15889
15890 static int
15891 api_one_adjacencies_get (vat_main_t * vam)
15892 {
15893   unformat_input_t *i = vam->input;
15894   vl_api_one_adjacencies_get_t *mp;
15895   u8 vni_set = 0;
15896   u32 vni = ~0;
15897   int ret;
15898
15899   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15900     {
15901       if (unformat (i, "vni %d", &vni))
15902         {
15903           vni_set = 1;
15904         }
15905       else
15906         {
15907           errmsg ("parse error '%U'", format_unformat_error, i);
15908           return -99;
15909         }
15910     }
15911
15912   if (!vni_set)
15913     {
15914       errmsg ("vni not set!");
15915       return -99;
15916     }
15917
15918   if (!vam->json_output)
15919     {
15920       print (vam->ofp, "%s %40s", "leid", "reid");
15921     }
15922
15923   M (ONE_ADJACENCIES_GET, mp);
15924   mp->vni = clib_host_to_net_u32 (vni);
15925
15926   /* send it... */
15927   S (mp);
15928
15929   /* Wait for a reply... */
15930   W (ret);
15931   return ret;
15932 }
15933
15934 #define api_lisp_adjacencies_get api_one_adjacencies_get
15935
15936 static int
15937 api_one_map_server_dump (vat_main_t * vam)
15938 {
15939   vl_api_one_map_server_dump_t *mp;
15940   vl_api_control_ping_t *mp_ping;
15941   int ret;
15942
15943   if (!vam->json_output)
15944     {
15945       print (vam->ofp, "%=20s", "Map server");
15946     }
15947
15948   M (ONE_MAP_SERVER_DUMP, mp);
15949   /* send it... */
15950   S (mp);
15951
15952   /* Use a control ping for synchronization */
15953   M (CONTROL_PING, mp_ping);
15954   S (mp_ping);
15955
15956   /* Wait for a reply... */
15957   W (ret);
15958   return ret;
15959 }
15960
15961 #define api_lisp_map_server_dump api_one_map_server_dump
15962
15963 static int
15964 api_one_map_resolver_dump (vat_main_t * vam)
15965 {
15966   vl_api_one_map_resolver_dump_t *mp;
15967   vl_api_control_ping_t *mp_ping;
15968   int ret;
15969
15970   if (!vam->json_output)
15971     {
15972       print (vam->ofp, "%=20s", "Map resolver");
15973     }
15974
15975   M (ONE_MAP_RESOLVER_DUMP, mp);
15976   /* send it... */
15977   S (mp);
15978
15979   /* Use a control ping for synchronization */
15980   M (CONTROL_PING, mp_ping);
15981   S (mp_ping);
15982
15983   /* Wait for a reply... */
15984   W (ret);
15985   return ret;
15986 }
15987
15988 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
15989
15990 static int
15991 api_one_stats_flush (vat_main_t * vam)
15992 {
15993   vl_api_one_stats_flush_t *mp;
15994   int ret = 0;
15995
15996   M (ONE_STATS_FLUSH, mp);
15997   S (mp);
15998   W (ret);
15999   return ret;
16000 }
16001
16002 static int
16003 api_one_stats_dump (vat_main_t * vam)
16004 {
16005   vl_api_one_stats_dump_t *mp;
16006   vl_api_control_ping_t *mp_ping;
16007   int ret;
16008
16009   M (ONE_STATS_DUMP, mp);
16010   /* send it... */
16011   S (mp);
16012
16013   /* Use a control ping for synchronization */
16014   M (CONTROL_PING, mp_ping);
16015   S (mp_ping);
16016
16017   /* Wait for a reply... */
16018   W (ret);
16019   return ret;
16020 }
16021
16022 static int
16023 api_show_one_status (vat_main_t * vam)
16024 {
16025   vl_api_show_one_status_t *mp;
16026   int ret;
16027
16028   if (!vam->json_output)
16029     {
16030       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
16031     }
16032
16033   M (SHOW_ONE_STATUS, mp);
16034   /* send it... */
16035   S (mp);
16036   /* Wait for a reply... */
16037   W (ret);
16038   return ret;
16039 }
16040
16041 #define api_show_lisp_status api_show_one_status
16042
16043 static int
16044 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
16045 {
16046   vl_api_gpe_fwd_entry_path_dump_t *mp;
16047   vl_api_control_ping_t *mp_ping;
16048   unformat_input_t *i = vam->input;
16049   u32 fwd_entry_index = ~0;
16050   int ret;
16051
16052   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16053     {
16054       if (unformat (i, "index %d", &fwd_entry_index))
16055         ;
16056       else
16057         break;
16058     }
16059
16060   if (~0 == fwd_entry_index)
16061     {
16062       errmsg ("no index specified!");
16063       return -99;
16064     }
16065
16066   if (!vam->json_output)
16067     {
16068       print (vam->ofp, "first line");
16069     }
16070
16071   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
16072
16073   /* send it... */
16074   S (mp);
16075   /* Use a control ping for synchronization */
16076   M (CONTROL_PING, mp_ping);
16077   S (mp_ping);
16078
16079   /* Wait for a reply... */
16080   W (ret);
16081   return ret;
16082 }
16083
16084 static int
16085 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
16086 {
16087   vl_api_one_get_map_request_itr_rlocs_t *mp;
16088   int ret;
16089
16090   if (!vam->json_output)
16091     {
16092       print (vam->ofp, "%=20s", "itr-rlocs:");
16093     }
16094
16095   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
16096   /* send it... */
16097   S (mp);
16098   /* Wait for a reply... */
16099   W (ret);
16100   return ret;
16101 }
16102
16103 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
16104
16105 static int
16106 api_af_packet_create (vat_main_t * vam)
16107 {
16108   unformat_input_t *i = vam->input;
16109   vl_api_af_packet_create_t *mp;
16110   u8 *host_if_name = 0;
16111   u8 hw_addr[6];
16112   u8 random_hw_addr = 1;
16113   int ret;
16114
16115   memset (hw_addr, 0, sizeof (hw_addr));
16116
16117   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16118     {
16119       if (unformat (i, "name %s", &host_if_name))
16120         vec_add1 (host_if_name, 0);
16121       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
16122         random_hw_addr = 0;
16123       else
16124         break;
16125     }
16126
16127   if (!vec_len (host_if_name))
16128     {
16129       errmsg ("host-interface name must be specified");
16130       return -99;
16131     }
16132
16133   if (vec_len (host_if_name) > 64)
16134     {
16135       errmsg ("host-interface name too long");
16136       return -99;
16137     }
16138
16139   M (AF_PACKET_CREATE, mp);
16140
16141   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
16142   clib_memcpy (mp->hw_addr, hw_addr, 6);
16143   mp->use_random_hw_addr = random_hw_addr;
16144   vec_free (host_if_name);
16145
16146   S (mp);
16147
16148   /* *INDENT-OFF* */
16149   W2 (ret,
16150       ({
16151         if (ret == 0)
16152           fprintf (vam->ofp ? vam->ofp : stderr,
16153                    " new sw_if_index = %d\n", vam->sw_if_index);
16154       }));
16155   /* *INDENT-ON* */
16156   return ret;
16157 }
16158
16159 static int
16160 api_af_packet_delete (vat_main_t * vam)
16161 {
16162   unformat_input_t *i = vam->input;
16163   vl_api_af_packet_delete_t *mp;
16164   u8 *host_if_name = 0;
16165   int ret;
16166
16167   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16168     {
16169       if (unformat (i, "name %s", &host_if_name))
16170         vec_add1 (host_if_name, 0);
16171       else
16172         break;
16173     }
16174
16175   if (!vec_len (host_if_name))
16176     {
16177       errmsg ("host-interface name must be specified");
16178       return -99;
16179     }
16180
16181   if (vec_len (host_if_name) > 64)
16182     {
16183       errmsg ("host-interface name too long");
16184       return -99;
16185     }
16186
16187   M (AF_PACKET_DELETE, mp);
16188
16189   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
16190   vec_free (host_if_name);
16191
16192   S (mp);
16193   W (ret);
16194   return ret;
16195 }
16196
16197 static int
16198 api_policer_add_del (vat_main_t * vam)
16199 {
16200   unformat_input_t *i = vam->input;
16201   vl_api_policer_add_del_t *mp;
16202   u8 is_add = 1;
16203   u8 *name = 0;
16204   u32 cir = 0;
16205   u32 eir = 0;
16206   u64 cb = 0;
16207   u64 eb = 0;
16208   u8 rate_type = 0;
16209   u8 round_type = 0;
16210   u8 type = 0;
16211   u8 color_aware = 0;
16212   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
16213   int ret;
16214
16215   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
16216   conform_action.dscp = 0;
16217   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
16218   exceed_action.dscp = 0;
16219   violate_action.action_type = SSE2_QOS_ACTION_DROP;
16220   violate_action.dscp = 0;
16221
16222   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16223     {
16224       if (unformat (i, "del"))
16225         is_add = 0;
16226       else if (unformat (i, "name %s", &name))
16227         vec_add1 (name, 0);
16228       else if (unformat (i, "cir %u", &cir))
16229         ;
16230       else if (unformat (i, "eir %u", &eir))
16231         ;
16232       else if (unformat (i, "cb %u", &cb))
16233         ;
16234       else if (unformat (i, "eb %u", &eb))
16235         ;
16236       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
16237                          &rate_type))
16238         ;
16239       else if (unformat (i, "round_type %U", unformat_policer_round_type,
16240                          &round_type))
16241         ;
16242       else if (unformat (i, "type %U", unformat_policer_type, &type))
16243         ;
16244       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
16245                          &conform_action))
16246         ;
16247       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
16248                          &exceed_action))
16249         ;
16250       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
16251                          &violate_action))
16252         ;
16253       else if (unformat (i, "color-aware"))
16254         color_aware = 1;
16255       else
16256         break;
16257     }
16258
16259   if (!vec_len (name))
16260     {
16261       errmsg ("policer name must be specified");
16262       return -99;
16263     }
16264
16265   if (vec_len (name) > 64)
16266     {
16267       errmsg ("policer name too long");
16268       return -99;
16269     }
16270
16271   M (POLICER_ADD_DEL, mp);
16272
16273   clib_memcpy (mp->name, name, vec_len (name));
16274   vec_free (name);
16275   mp->is_add = is_add;
16276   mp->cir = cir;
16277   mp->eir = eir;
16278   mp->cb = cb;
16279   mp->eb = eb;
16280   mp->rate_type = rate_type;
16281   mp->round_type = round_type;
16282   mp->type = type;
16283   mp->conform_action_type = conform_action.action_type;
16284   mp->conform_dscp = conform_action.dscp;
16285   mp->exceed_action_type = exceed_action.action_type;
16286   mp->exceed_dscp = exceed_action.dscp;
16287   mp->violate_action_type = violate_action.action_type;
16288   mp->violate_dscp = violate_action.dscp;
16289   mp->color_aware = color_aware;
16290
16291   S (mp);
16292   W (ret);
16293   return ret;
16294 }
16295
16296 static int
16297 api_policer_dump (vat_main_t * vam)
16298 {
16299   unformat_input_t *i = vam->input;
16300   vl_api_policer_dump_t *mp;
16301   vl_api_control_ping_t *mp_ping;
16302   u8 *match_name = 0;
16303   u8 match_name_valid = 0;
16304   int ret;
16305
16306   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16307     {
16308       if (unformat (i, "name %s", &match_name))
16309         {
16310           vec_add1 (match_name, 0);
16311           match_name_valid = 1;
16312         }
16313       else
16314         break;
16315     }
16316
16317   M (POLICER_DUMP, mp);
16318   mp->match_name_valid = match_name_valid;
16319   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
16320   vec_free (match_name);
16321   /* send it... */
16322   S (mp);
16323
16324   /* Use a control ping for synchronization */
16325   M (CONTROL_PING, mp_ping);
16326   S (mp_ping);
16327
16328   /* Wait for a reply... */
16329   W (ret);
16330   return ret;
16331 }
16332
16333 static int
16334 api_policer_classify_set_interface (vat_main_t * vam)
16335 {
16336   unformat_input_t *i = vam->input;
16337   vl_api_policer_classify_set_interface_t *mp;
16338   u32 sw_if_index;
16339   int sw_if_index_set;
16340   u32 ip4_table_index = ~0;
16341   u32 ip6_table_index = ~0;
16342   u32 l2_table_index = ~0;
16343   u8 is_add = 1;
16344   int ret;
16345
16346   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16347     {
16348       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16349         sw_if_index_set = 1;
16350       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16351         sw_if_index_set = 1;
16352       else if (unformat (i, "del"))
16353         is_add = 0;
16354       else if (unformat (i, "ip4-table %d", &ip4_table_index))
16355         ;
16356       else if (unformat (i, "ip6-table %d", &ip6_table_index))
16357         ;
16358       else if (unformat (i, "l2-table %d", &l2_table_index))
16359         ;
16360       else
16361         {
16362           clib_warning ("parse error '%U'", format_unformat_error, i);
16363           return -99;
16364         }
16365     }
16366
16367   if (sw_if_index_set == 0)
16368     {
16369       errmsg ("missing interface name or sw_if_index");
16370       return -99;
16371     }
16372
16373   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
16374
16375   mp->sw_if_index = ntohl (sw_if_index);
16376   mp->ip4_table_index = ntohl (ip4_table_index);
16377   mp->ip6_table_index = ntohl (ip6_table_index);
16378   mp->l2_table_index = ntohl (l2_table_index);
16379   mp->is_add = is_add;
16380
16381   S (mp);
16382   W (ret);
16383   return ret;
16384 }
16385
16386 static int
16387 api_policer_classify_dump (vat_main_t * vam)
16388 {
16389   unformat_input_t *i = vam->input;
16390   vl_api_policer_classify_dump_t *mp;
16391   vl_api_control_ping_t *mp_ping;
16392   u8 type = POLICER_CLASSIFY_N_TABLES;
16393   int ret;
16394
16395   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
16396     ;
16397   else
16398     {
16399       errmsg ("classify table type must be specified");
16400       return -99;
16401     }
16402
16403   if (!vam->json_output)
16404     {
16405       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
16406     }
16407
16408   M (POLICER_CLASSIFY_DUMP, mp);
16409   mp->type = type;
16410   /* send it... */
16411   S (mp);
16412
16413   /* Use a control ping for synchronization */
16414   M (CONTROL_PING, mp_ping);
16415   S (mp_ping);
16416
16417   /* Wait for a reply... */
16418   W (ret);
16419   return ret;
16420 }
16421
16422 static int
16423 api_netmap_create (vat_main_t * vam)
16424 {
16425   unformat_input_t *i = vam->input;
16426   vl_api_netmap_create_t *mp;
16427   u8 *if_name = 0;
16428   u8 hw_addr[6];
16429   u8 random_hw_addr = 1;
16430   u8 is_pipe = 0;
16431   u8 is_master = 0;
16432   int ret;
16433
16434   memset (hw_addr, 0, sizeof (hw_addr));
16435
16436   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16437     {
16438       if (unformat (i, "name %s", &if_name))
16439         vec_add1 (if_name, 0);
16440       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
16441         random_hw_addr = 0;
16442       else if (unformat (i, "pipe"))
16443         is_pipe = 1;
16444       else if (unformat (i, "master"))
16445         is_master = 1;
16446       else if (unformat (i, "slave"))
16447         is_master = 0;
16448       else
16449         break;
16450     }
16451
16452   if (!vec_len (if_name))
16453     {
16454       errmsg ("interface name must be specified");
16455       return -99;
16456     }
16457
16458   if (vec_len (if_name) > 64)
16459     {
16460       errmsg ("interface name too long");
16461       return -99;
16462     }
16463
16464   M (NETMAP_CREATE, mp);
16465
16466   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
16467   clib_memcpy (mp->hw_addr, hw_addr, 6);
16468   mp->use_random_hw_addr = random_hw_addr;
16469   mp->is_pipe = is_pipe;
16470   mp->is_master = is_master;
16471   vec_free (if_name);
16472
16473   S (mp);
16474   W (ret);
16475   return ret;
16476 }
16477
16478 static int
16479 api_netmap_delete (vat_main_t * vam)
16480 {
16481   unformat_input_t *i = vam->input;
16482   vl_api_netmap_delete_t *mp;
16483   u8 *if_name = 0;
16484   int ret;
16485
16486   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16487     {
16488       if (unformat (i, "name %s", &if_name))
16489         vec_add1 (if_name, 0);
16490       else
16491         break;
16492     }
16493
16494   if (!vec_len (if_name))
16495     {
16496       errmsg ("interface name must be specified");
16497       return -99;
16498     }
16499
16500   if (vec_len (if_name) > 64)
16501     {
16502       errmsg ("interface name too long");
16503       return -99;
16504     }
16505
16506   M (NETMAP_DELETE, mp);
16507
16508   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
16509   vec_free (if_name);
16510
16511   S (mp);
16512   W (ret);
16513   return ret;
16514 }
16515
16516 static void
16517 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
16518 {
16519   if (fp->afi == IP46_TYPE_IP6)
16520     print (vam->ofp,
16521            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16522            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16523            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16524            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16525            format_ip6_address, fp->next_hop);
16526   else if (fp->afi == IP46_TYPE_IP4)
16527     print (vam->ofp,
16528            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16529            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16530            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16531            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16532            format_ip4_address, fp->next_hop);
16533 }
16534
16535 static void
16536 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
16537                                  vl_api_fib_path2_t * fp)
16538 {
16539   struct in_addr ip4;
16540   struct in6_addr ip6;
16541
16542   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16543   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16544   vat_json_object_add_uint (node, "is_local", fp->is_local);
16545   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16546   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16547   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16548   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16549   if (fp->afi == IP46_TYPE_IP4)
16550     {
16551       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16552       vat_json_object_add_ip4 (node, "next_hop", ip4);
16553     }
16554   else if (fp->afi == IP46_TYPE_IP6)
16555     {
16556       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16557       vat_json_object_add_ip6 (node, "next_hop", ip6);
16558     }
16559 }
16560
16561 static void
16562 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
16563 {
16564   vat_main_t *vam = &vat_main;
16565   int count = ntohl (mp->mt_count);
16566   vl_api_fib_path2_t *fp;
16567   i32 i;
16568
16569   print (vam->ofp, "[%d]: sw_if_index %d via:",
16570          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
16571   fp = mp->mt_paths;
16572   for (i = 0; i < count; i++)
16573     {
16574       vl_api_mpls_fib_path_print (vam, fp);
16575       fp++;
16576     }
16577
16578   print (vam->ofp, "");
16579 }
16580
16581 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
16582 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
16583
16584 static void
16585 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
16586 {
16587   vat_main_t *vam = &vat_main;
16588   vat_json_node_t *node = NULL;
16589   int count = ntohl (mp->mt_count);
16590   vl_api_fib_path2_t *fp;
16591   i32 i;
16592
16593   if (VAT_JSON_ARRAY != vam->json_tree.type)
16594     {
16595       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16596       vat_json_init_array (&vam->json_tree);
16597     }
16598   node = vat_json_array_add (&vam->json_tree);
16599
16600   vat_json_init_object (node);
16601   vat_json_object_add_uint (node, "tunnel_index",
16602                             ntohl (mp->mt_tunnel_index));
16603   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
16604
16605   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
16606
16607   fp = mp->mt_paths;
16608   for (i = 0; i < count; i++)
16609     {
16610       vl_api_mpls_fib_path_json_print (node, fp);
16611       fp++;
16612     }
16613 }
16614
16615 static int
16616 api_mpls_tunnel_dump (vat_main_t * vam)
16617 {
16618   vl_api_mpls_tunnel_dump_t *mp;
16619   vl_api_control_ping_t *mp_ping;
16620   i32 index = -1;
16621   int ret;
16622
16623   /* Parse args required to build the message */
16624   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
16625     {
16626       if (!unformat (vam->input, "tunnel_index %d", &index))
16627         {
16628           index = -1;
16629           break;
16630         }
16631     }
16632
16633   print (vam->ofp, "  tunnel_index %d", index);
16634
16635   M (MPLS_TUNNEL_DUMP, mp);
16636   mp->tunnel_index = htonl (index);
16637   S (mp);
16638
16639   /* Use a control ping for synchronization */
16640   M (CONTROL_PING, mp_ping);
16641   S (mp_ping);
16642
16643   W (ret);
16644   return ret;
16645 }
16646
16647 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
16648 #define vl_api_mpls_fib_details_t_print vl_noop_handler
16649
16650
16651 static void
16652 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
16653 {
16654   vat_main_t *vam = &vat_main;
16655   int count = ntohl (mp->count);
16656   vl_api_fib_path2_t *fp;
16657   int i;
16658
16659   print (vam->ofp,
16660          "table-id %d, label %u, ess_bit %u",
16661          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
16662   fp = mp->path;
16663   for (i = 0; i < count; i++)
16664     {
16665       vl_api_mpls_fib_path_print (vam, fp);
16666       fp++;
16667     }
16668 }
16669
16670 static void vl_api_mpls_fib_details_t_handler_json
16671   (vl_api_mpls_fib_details_t * mp)
16672 {
16673   vat_main_t *vam = &vat_main;
16674   int count = ntohl (mp->count);
16675   vat_json_node_t *node = NULL;
16676   vl_api_fib_path2_t *fp;
16677   int i;
16678
16679   if (VAT_JSON_ARRAY != vam->json_tree.type)
16680     {
16681       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16682       vat_json_init_array (&vam->json_tree);
16683     }
16684   node = vat_json_array_add (&vam->json_tree);
16685
16686   vat_json_init_object (node);
16687   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16688   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
16689   vat_json_object_add_uint (node, "label", ntohl (mp->label));
16690   vat_json_object_add_uint (node, "path_count", count);
16691   fp = mp->path;
16692   for (i = 0; i < count; i++)
16693     {
16694       vl_api_mpls_fib_path_json_print (node, fp);
16695       fp++;
16696     }
16697 }
16698
16699 static int
16700 api_mpls_fib_dump (vat_main_t * vam)
16701 {
16702   vl_api_mpls_fib_dump_t *mp;
16703   vl_api_control_ping_t *mp_ping;
16704   int ret;
16705
16706   M (MPLS_FIB_DUMP, mp);
16707   S (mp);
16708
16709   /* Use a control ping for synchronization */
16710   M (CONTROL_PING, mp_ping);
16711   S (mp_ping);
16712
16713   W (ret);
16714   return ret;
16715 }
16716
16717 #define vl_api_ip_fib_details_t_endian vl_noop_handler
16718 #define vl_api_ip_fib_details_t_print vl_noop_handler
16719
16720 static void
16721 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
16722 {
16723   vat_main_t *vam = &vat_main;
16724   int count = ntohl (mp->count);
16725   vl_api_fib_path_t *fp;
16726   int i;
16727
16728   print (vam->ofp,
16729          "table-id %d, prefix %U/%d",
16730          ntohl (mp->table_id), format_ip4_address, mp->address,
16731          mp->address_length);
16732   fp = mp->path;
16733   for (i = 0; i < count; i++)
16734     {
16735       if (fp->afi == IP46_TYPE_IP6)
16736         print (vam->ofp,
16737                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16738                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16739                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16740                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16741                format_ip6_address, fp->next_hop);
16742       else if (fp->afi == IP46_TYPE_IP4)
16743         print (vam->ofp,
16744                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16745                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16746                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16747                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16748                format_ip4_address, fp->next_hop);
16749       fp++;
16750     }
16751 }
16752
16753 static void vl_api_ip_fib_details_t_handler_json
16754   (vl_api_ip_fib_details_t * mp)
16755 {
16756   vat_main_t *vam = &vat_main;
16757   int count = ntohl (mp->count);
16758   vat_json_node_t *node = NULL;
16759   struct in_addr ip4;
16760   struct in6_addr ip6;
16761   vl_api_fib_path_t *fp;
16762   int i;
16763
16764   if (VAT_JSON_ARRAY != vam->json_tree.type)
16765     {
16766       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16767       vat_json_init_array (&vam->json_tree);
16768     }
16769   node = vat_json_array_add (&vam->json_tree);
16770
16771   vat_json_init_object (node);
16772   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16773   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
16774   vat_json_object_add_ip4 (node, "prefix", ip4);
16775   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16776   vat_json_object_add_uint (node, "path_count", count);
16777   fp = mp->path;
16778   for (i = 0; i < count; i++)
16779     {
16780       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16781       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16782       vat_json_object_add_uint (node, "is_local", fp->is_local);
16783       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16784       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16785       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16786       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16787       if (fp->afi == IP46_TYPE_IP4)
16788         {
16789           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16790           vat_json_object_add_ip4 (node, "next_hop", ip4);
16791         }
16792       else if (fp->afi == IP46_TYPE_IP6)
16793         {
16794           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16795           vat_json_object_add_ip6 (node, "next_hop", ip6);
16796         }
16797     }
16798 }
16799
16800 static int
16801 api_ip_fib_dump (vat_main_t * vam)
16802 {
16803   vl_api_ip_fib_dump_t *mp;
16804   vl_api_control_ping_t *mp_ping;
16805   int ret;
16806
16807   M (IP_FIB_DUMP, mp);
16808   S (mp);
16809
16810   /* Use a control ping for synchronization */
16811   M (CONTROL_PING, mp_ping);
16812   S (mp_ping);
16813
16814   W (ret);
16815   return ret;
16816 }
16817
16818 static int
16819 api_ip_mfib_dump (vat_main_t * vam)
16820 {
16821   vl_api_ip_mfib_dump_t *mp;
16822   vl_api_control_ping_t *mp_ping;
16823   int ret;
16824
16825   M (IP_MFIB_DUMP, mp);
16826   S (mp);
16827
16828   /* Use a control ping for synchronization */
16829   M (CONTROL_PING, mp_ping);
16830   S (mp_ping);
16831
16832   W (ret);
16833   return ret;
16834 }
16835
16836 static void vl_api_ip_neighbor_details_t_handler
16837   (vl_api_ip_neighbor_details_t * mp)
16838 {
16839   vat_main_t *vam = &vat_main;
16840
16841   print (vam->ofp, "%c %U %U",
16842          (mp->is_static) ? 'S' : 'D',
16843          format_ethernet_address, &mp->mac_address,
16844          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
16845          &mp->ip_address);
16846 }
16847
16848 static void vl_api_ip_neighbor_details_t_handler_json
16849   (vl_api_ip_neighbor_details_t * mp)
16850 {
16851
16852   vat_main_t *vam = &vat_main;
16853   vat_json_node_t *node;
16854   struct in_addr ip4;
16855   struct in6_addr ip6;
16856
16857   if (VAT_JSON_ARRAY != vam->json_tree.type)
16858     {
16859       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16860       vat_json_init_array (&vam->json_tree);
16861     }
16862   node = vat_json_array_add (&vam->json_tree);
16863
16864   vat_json_init_object (node);
16865   vat_json_object_add_string_copy (node, "flag",
16866                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
16867                                    "dynamic");
16868
16869   vat_json_object_add_string_copy (node, "link_layer",
16870                                    format (0, "%U", format_ethernet_address,
16871                                            &mp->mac_address));
16872
16873   if (mp->is_ipv6)
16874     {
16875       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
16876       vat_json_object_add_ip6 (node, "ip_address", ip6);
16877     }
16878   else
16879     {
16880       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
16881       vat_json_object_add_ip4 (node, "ip_address", ip4);
16882     }
16883 }
16884
16885 static int
16886 api_ip_neighbor_dump (vat_main_t * vam)
16887 {
16888   unformat_input_t *i = vam->input;
16889   vl_api_ip_neighbor_dump_t *mp;
16890   vl_api_control_ping_t *mp_ping;
16891   u8 is_ipv6 = 0;
16892   u32 sw_if_index = ~0;
16893   int ret;
16894
16895   /* Parse args required to build the message */
16896   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16897     {
16898       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16899         ;
16900       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16901         ;
16902       else if (unformat (i, "ip6"))
16903         is_ipv6 = 1;
16904       else
16905         break;
16906     }
16907
16908   if (sw_if_index == ~0)
16909     {
16910       errmsg ("missing interface name or sw_if_index");
16911       return -99;
16912     }
16913
16914   M (IP_NEIGHBOR_DUMP, mp);
16915   mp->is_ipv6 = (u8) is_ipv6;
16916   mp->sw_if_index = ntohl (sw_if_index);
16917   S (mp);
16918
16919   /* Use a control ping for synchronization */
16920   M (CONTROL_PING, mp_ping);
16921   S (mp_ping);
16922
16923   W (ret);
16924   return ret;
16925 }
16926
16927 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
16928 #define vl_api_ip6_fib_details_t_print vl_noop_handler
16929
16930 static void
16931 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
16932 {
16933   vat_main_t *vam = &vat_main;
16934   int count = ntohl (mp->count);
16935   vl_api_fib_path_t *fp;
16936   int i;
16937
16938   print (vam->ofp,
16939          "table-id %d, prefix %U/%d",
16940          ntohl (mp->table_id), format_ip6_address, mp->address,
16941          mp->address_length);
16942   fp = mp->path;
16943   for (i = 0; i < count; i++)
16944     {
16945       if (fp->afi == IP46_TYPE_IP6)
16946         print (vam->ofp,
16947                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16948                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16949                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16950                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16951                format_ip6_address, fp->next_hop);
16952       else if (fp->afi == IP46_TYPE_IP4)
16953         print (vam->ofp,
16954                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16955                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16956                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16957                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16958                format_ip4_address, fp->next_hop);
16959       fp++;
16960     }
16961 }
16962
16963 static void vl_api_ip6_fib_details_t_handler_json
16964   (vl_api_ip6_fib_details_t * mp)
16965 {
16966   vat_main_t *vam = &vat_main;
16967   int count = ntohl (mp->count);
16968   vat_json_node_t *node = NULL;
16969   struct in_addr ip4;
16970   struct in6_addr ip6;
16971   vl_api_fib_path_t *fp;
16972   int i;
16973
16974   if (VAT_JSON_ARRAY != vam->json_tree.type)
16975     {
16976       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16977       vat_json_init_array (&vam->json_tree);
16978     }
16979   node = vat_json_array_add (&vam->json_tree);
16980
16981   vat_json_init_object (node);
16982   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16983   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
16984   vat_json_object_add_ip6 (node, "prefix", ip6);
16985   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16986   vat_json_object_add_uint (node, "path_count", count);
16987   fp = mp->path;
16988   for (i = 0; i < count; i++)
16989     {
16990       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16991       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16992       vat_json_object_add_uint (node, "is_local", fp->is_local);
16993       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16994       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16995       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16996       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16997       if (fp->afi == IP46_TYPE_IP4)
16998         {
16999           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
17000           vat_json_object_add_ip4 (node, "next_hop", ip4);
17001         }
17002       else if (fp->afi == IP46_TYPE_IP6)
17003         {
17004           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
17005           vat_json_object_add_ip6 (node, "next_hop", ip6);
17006         }
17007     }
17008 }
17009
17010 static int
17011 api_ip6_fib_dump (vat_main_t * vam)
17012 {
17013   vl_api_ip6_fib_dump_t *mp;
17014   vl_api_control_ping_t *mp_ping;
17015   int ret;
17016
17017   M (IP6_FIB_DUMP, mp);
17018   S (mp);
17019
17020   /* Use a control ping for synchronization */
17021   M (CONTROL_PING, mp_ping);
17022   S (mp_ping);
17023
17024   W (ret);
17025   return ret;
17026 }
17027
17028 static int
17029 api_ip6_mfib_dump (vat_main_t * vam)
17030 {
17031   vl_api_ip6_mfib_dump_t *mp;
17032   vl_api_control_ping_t *mp_ping;
17033   int ret;
17034
17035   M (IP6_MFIB_DUMP, mp);
17036   S (mp);
17037
17038   /* Use a control ping for synchronization */
17039   M (CONTROL_PING, mp_ping);
17040   S (mp_ping);
17041
17042   W (ret);
17043   return ret;
17044 }
17045
17046 int
17047 api_classify_table_ids (vat_main_t * vam)
17048 {
17049   vl_api_classify_table_ids_t *mp;
17050   int ret;
17051
17052   /* Construct the API message */
17053   M (CLASSIFY_TABLE_IDS, mp);
17054   mp->context = 0;
17055
17056   S (mp);
17057   W (ret);
17058   return ret;
17059 }
17060
17061 int
17062 api_classify_table_by_interface (vat_main_t * vam)
17063 {
17064   unformat_input_t *input = vam->input;
17065   vl_api_classify_table_by_interface_t *mp;
17066
17067   u32 sw_if_index = ~0;
17068   int ret;
17069   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17070     {
17071       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17072         ;
17073       else if (unformat (input, "sw_if_index %d", &sw_if_index))
17074         ;
17075       else
17076         break;
17077     }
17078   if (sw_if_index == ~0)
17079     {
17080       errmsg ("missing interface name or sw_if_index");
17081       return -99;
17082     }
17083
17084   /* Construct the API message */
17085   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
17086   mp->context = 0;
17087   mp->sw_if_index = ntohl (sw_if_index);
17088
17089   S (mp);
17090   W (ret);
17091   return ret;
17092 }
17093
17094 int
17095 api_classify_table_info (vat_main_t * vam)
17096 {
17097   unformat_input_t *input = vam->input;
17098   vl_api_classify_table_info_t *mp;
17099
17100   u32 table_id = ~0;
17101   int ret;
17102   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17103     {
17104       if (unformat (input, "table_id %d", &table_id))
17105         ;
17106       else
17107         break;
17108     }
17109   if (table_id == ~0)
17110     {
17111       errmsg ("missing table id");
17112       return -99;
17113     }
17114
17115   /* Construct the API message */
17116   M (CLASSIFY_TABLE_INFO, mp);
17117   mp->context = 0;
17118   mp->table_id = ntohl (table_id);
17119
17120   S (mp);
17121   W (ret);
17122   return ret;
17123 }
17124
17125 int
17126 api_classify_session_dump (vat_main_t * vam)
17127 {
17128   unformat_input_t *input = vam->input;
17129   vl_api_classify_session_dump_t *mp;
17130   vl_api_control_ping_t *mp_ping;
17131
17132   u32 table_id = ~0;
17133   int ret;
17134   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17135     {
17136       if (unformat (input, "table_id %d", &table_id))
17137         ;
17138       else
17139         break;
17140     }
17141   if (table_id == ~0)
17142     {
17143       errmsg ("missing table id");
17144       return -99;
17145     }
17146
17147   /* Construct the API message */
17148   M (CLASSIFY_SESSION_DUMP, mp);
17149   mp->context = 0;
17150   mp->table_id = ntohl (table_id);
17151   S (mp);
17152
17153   /* Use a control ping for synchronization */
17154   M (CONTROL_PING, mp_ping);
17155   S (mp_ping);
17156
17157   W (ret);
17158   return ret;
17159 }
17160
17161 static void
17162 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
17163 {
17164   vat_main_t *vam = &vat_main;
17165
17166   print (vam->ofp, "collector_address %U, collector_port %d, "
17167          "src_address %U, vrf_id %d, path_mtu %u, "
17168          "template_interval %u, udp_checksum %d",
17169          format_ip4_address, mp->collector_address,
17170          ntohs (mp->collector_port),
17171          format_ip4_address, mp->src_address,
17172          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
17173          ntohl (mp->template_interval), mp->udp_checksum);
17174
17175   vam->retval = 0;
17176   vam->result_ready = 1;
17177 }
17178
17179 static void
17180   vl_api_ipfix_exporter_details_t_handler_json
17181   (vl_api_ipfix_exporter_details_t * mp)
17182 {
17183   vat_main_t *vam = &vat_main;
17184   vat_json_node_t node;
17185   struct in_addr collector_address;
17186   struct in_addr src_address;
17187
17188   vat_json_init_object (&node);
17189   clib_memcpy (&collector_address, &mp->collector_address,
17190                sizeof (collector_address));
17191   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
17192   vat_json_object_add_uint (&node, "collector_port",
17193                             ntohs (mp->collector_port));
17194   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
17195   vat_json_object_add_ip4 (&node, "src_address", src_address);
17196   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
17197   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
17198   vat_json_object_add_uint (&node, "template_interval",
17199                             ntohl (mp->template_interval));
17200   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
17201
17202   vat_json_print (vam->ofp, &node);
17203   vat_json_free (&node);
17204   vam->retval = 0;
17205   vam->result_ready = 1;
17206 }
17207
17208 int
17209 api_ipfix_exporter_dump (vat_main_t * vam)
17210 {
17211   vl_api_ipfix_exporter_dump_t *mp;
17212   int ret;
17213
17214   /* Construct the API message */
17215   M (IPFIX_EXPORTER_DUMP, mp);
17216   mp->context = 0;
17217
17218   S (mp);
17219   W (ret);
17220   return ret;
17221 }
17222
17223 static int
17224 api_ipfix_classify_stream_dump (vat_main_t * vam)
17225 {
17226   vl_api_ipfix_classify_stream_dump_t *mp;
17227   int ret;
17228
17229   /* Construct the API message */
17230   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
17231   mp->context = 0;
17232
17233   S (mp);
17234   W (ret);
17235   return ret;
17236   /* NOTREACHED */
17237   return 0;
17238 }
17239
17240 static void
17241   vl_api_ipfix_classify_stream_details_t_handler
17242   (vl_api_ipfix_classify_stream_details_t * mp)
17243 {
17244   vat_main_t *vam = &vat_main;
17245   print (vam->ofp, "domain_id %d, src_port %d",
17246          ntohl (mp->domain_id), ntohs (mp->src_port));
17247   vam->retval = 0;
17248   vam->result_ready = 1;
17249 }
17250
17251 static void
17252   vl_api_ipfix_classify_stream_details_t_handler_json
17253   (vl_api_ipfix_classify_stream_details_t * mp)
17254 {
17255   vat_main_t *vam = &vat_main;
17256   vat_json_node_t node;
17257
17258   vat_json_init_object (&node);
17259   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
17260   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
17261
17262   vat_json_print (vam->ofp, &node);
17263   vat_json_free (&node);
17264   vam->retval = 0;
17265   vam->result_ready = 1;
17266 }
17267
17268 static int
17269 api_ipfix_classify_table_dump (vat_main_t * vam)
17270 {
17271   vl_api_ipfix_classify_table_dump_t *mp;
17272   vl_api_control_ping_t *mp_ping;
17273   int ret;
17274
17275   if (!vam->json_output)
17276     {
17277       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
17278              "transport_protocol");
17279     }
17280
17281   /* Construct the API message */
17282   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
17283
17284   /* send it... */
17285   S (mp);
17286
17287   /* Use a control ping for synchronization */
17288   M (CONTROL_PING, mp_ping);
17289   S (mp_ping);
17290
17291   W (ret);
17292   return ret;
17293 }
17294
17295 static void
17296   vl_api_ipfix_classify_table_details_t_handler
17297   (vl_api_ipfix_classify_table_details_t * mp)
17298 {
17299   vat_main_t *vam = &vat_main;
17300   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
17301          mp->transport_protocol);
17302 }
17303
17304 static void
17305   vl_api_ipfix_classify_table_details_t_handler_json
17306   (vl_api_ipfix_classify_table_details_t * mp)
17307 {
17308   vat_json_node_t *node = NULL;
17309   vat_main_t *vam = &vat_main;
17310
17311   if (VAT_JSON_ARRAY != vam->json_tree.type)
17312     {
17313       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17314       vat_json_init_array (&vam->json_tree);
17315     }
17316
17317   node = vat_json_array_add (&vam->json_tree);
17318   vat_json_init_object (node);
17319
17320   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
17321   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
17322   vat_json_object_add_uint (node, "transport_protocol",
17323                             mp->transport_protocol);
17324 }
17325
17326 static int
17327 api_sw_interface_span_enable_disable (vat_main_t * vam)
17328 {
17329   unformat_input_t *i = vam->input;
17330   vl_api_sw_interface_span_enable_disable_t *mp;
17331   u32 src_sw_if_index = ~0;
17332   u32 dst_sw_if_index = ~0;
17333   u8 state = 3;
17334   int ret;
17335
17336   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17337     {
17338       if (unformat
17339           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
17340         ;
17341       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
17342         ;
17343       else
17344         if (unformat
17345             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
17346         ;
17347       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
17348         ;
17349       else if (unformat (i, "disable"))
17350         state = 0;
17351       else if (unformat (i, "rx"))
17352         state = 1;
17353       else if (unformat (i, "tx"))
17354         state = 2;
17355       else if (unformat (i, "both"))
17356         state = 3;
17357       else
17358         break;
17359     }
17360
17361   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
17362
17363   mp->sw_if_index_from = htonl (src_sw_if_index);
17364   mp->sw_if_index_to = htonl (dst_sw_if_index);
17365   mp->state = state;
17366
17367   S (mp);
17368   W (ret);
17369   return ret;
17370 }
17371
17372 static void
17373 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
17374                                             * mp)
17375 {
17376   vat_main_t *vam = &vat_main;
17377   u8 *sw_if_from_name = 0;
17378   u8 *sw_if_to_name = 0;
17379   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
17380   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
17381   char *states[] = { "none", "rx", "tx", "both" };
17382   hash_pair_t *p;
17383
17384   /* *INDENT-OFF* */
17385   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
17386   ({
17387     if ((u32) p->value[0] == sw_if_index_from)
17388       {
17389         sw_if_from_name = (u8 *)(p->key);
17390         if (sw_if_to_name)
17391           break;
17392       }
17393     if ((u32) p->value[0] == sw_if_index_to)
17394       {
17395         sw_if_to_name = (u8 *)(p->key);
17396         if (sw_if_from_name)
17397           break;
17398       }
17399   }));
17400   /* *INDENT-ON* */
17401   print (vam->ofp, "%20s => %20s (%s)",
17402          sw_if_from_name, sw_if_to_name, states[mp->state]);
17403 }
17404
17405 static void
17406   vl_api_sw_interface_span_details_t_handler_json
17407   (vl_api_sw_interface_span_details_t * mp)
17408 {
17409   vat_main_t *vam = &vat_main;
17410   vat_json_node_t *node = NULL;
17411   u8 *sw_if_from_name = 0;
17412   u8 *sw_if_to_name = 0;
17413   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
17414   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
17415   hash_pair_t *p;
17416
17417   /* *INDENT-OFF* */
17418   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
17419   ({
17420     if ((u32) p->value[0] == sw_if_index_from)
17421       {
17422         sw_if_from_name = (u8 *)(p->key);
17423         if (sw_if_to_name)
17424           break;
17425       }
17426     if ((u32) p->value[0] == sw_if_index_to)
17427       {
17428         sw_if_to_name = (u8 *)(p->key);
17429         if (sw_if_from_name)
17430           break;
17431       }
17432   }));
17433   /* *INDENT-ON* */
17434
17435   if (VAT_JSON_ARRAY != vam->json_tree.type)
17436     {
17437       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17438       vat_json_init_array (&vam->json_tree);
17439     }
17440   node = vat_json_array_add (&vam->json_tree);
17441
17442   vat_json_init_object (node);
17443   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
17444   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
17445   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
17446   if (0 != sw_if_to_name)
17447     {
17448       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
17449     }
17450   vat_json_object_add_uint (node, "state", mp->state);
17451 }
17452
17453 static int
17454 api_sw_interface_span_dump (vat_main_t * vam)
17455 {
17456   vl_api_sw_interface_span_dump_t *mp;
17457   vl_api_control_ping_t *mp_ping;
17458   int ret;
17459
17460   M (SW_INTERFACE_SPAN_DUMP, mp);
17461   S (mp);
17462
17463   /* Use a control ping for synchronization */
17464   M (CONTROL_PING, mp_ping);
17465   S (mp_ping);
17466
17467   W (ret);
17468   return ret;
17469 }
17470
17471 int
17472 api_pg_create_interface (vat_main_t * vam)
17473 {
17474   unformat_input_t *input = vam->input;
17475   vl_api_pg_create_interface_t *mp;
17476
17477   u32 if_id = ~0;
17478   int ret;
17479   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17480     {
17481       if (unformat (input, "if_id %d", &if_id))
17482         ;
17483       else
17484         break;
17485     }
17486   if (if_id == ~0)
17487     {
17488       errmsg ("missing pg interface index");
17489       return -99;
17490     }
17491
17492   /* Construct the API message */
17493   M (PG_CREATE_INTERFACE, mp);
17494   mp->context = 0;
17495   mp->interface_id = ntohl (if_id);
17496
17497   S (mp);
17498   W (ret);
17499   return ret;
17500 }
17501
17502 int
17503 api_pg_capture (vat_main_t * vam)
17504 {
17505   unformat_input_t *input = vam->input;
17506   vl_api_pg_capture_t *mp;
17507
17508   u32 if_id = ~0;
17509   u8 enable = 1;
17510   u32 count = 1;
17511   u8 pcap_file_set = 0;
17512   u8 *pcap_file = 0;
17513   int ret;
17514   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17515     {
17516       if (unformat (input, "if_id %d", &if_id))
17517         ;
17518       else if (unformat (input, "pcap %s", &pcap_file))
17519         pcap_file_set = 1;
17520       else if (unformat (input, "count %d", &count))
17521         ;
17522       else if (unformat (input, "disable"))
17523         enable = 0;
17524       else
17525         break;
17526     }
17527   if (if_id == ~0)
17528     {
17529       errmsg ("missing pg interface index");
17530       return -99;
17531     }
17532   if (pcap_file_set > 0)
17533     {
17534       if (vec_len (pcap_file) > 255)
17535         {
17536           errmsg ("pcap file name is too long");
17537           return -99;
17538         }
17539     }
17540
17541   u32 name_len = vec_len (pcap_file);
17542   /* Construct the API message */
17543   M (PG_CAPTURE, mp);
17544   mp->context = 0;
17545   mp->interface_id = ntohl (if_id);
17546   mp->is_enabled = enable;
17547   mp->count = ntohl (count);
17548   mp->pcap_name_length = ntohl (name_len);
17549   if (pcap_file_set != 0)
17550     {
17551       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
17552     }
17553   vec_free (pcap_file);
17554
17555   S (mp);
17556   W (ret);
17557   return ret;
17558 }
17559
17560 int
17561 api_pg_enable_disable (vat_main_t * vam)
17562 {
17563   unformat_input_t *input = vam->input;
17564   vl_api_pg_enable_disable_t *mp;
17565
17566   u8 enable = 1;
17567   u8 stream_name_set = 0;
17568   u8 *stream_name = 0;
17569   int ret;
17570   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17571     {
17572       if (unformat (input, "stream %s", &stream_name))
17573         stream_name_set = 1;
17574       else if (unformat (input, "disable"))
17575         enable = 0;
17576       else
17577         break;
17578     }
17579
17580   if (stream_name_set > 0)
17581     {
17582       if (vec_len (stream_name) > 255)
17583         {
17584           errmsg ("stream name too long");
17585           return -99;
17586         }
17587     }
17588
17589   u32 name_len = vec_len (stream_name);
17590   /* Construct the API message */
17591   M (PG_ENABLE_DISABLE, mp);
17592   mp->context = 0;
17593   mp->is_enabled = enable;
17594   if (stream_name_set != 0)
17595     {
17596       mp->stream_name_length = ntohl (name_len);
17597       clib_memcpy (mp->stream_name, stream_name, name_len);
17598     }
17599   vec_free (stream_name);
17600
17601   S (mp);
17602   W (ret);
17603   return ret;
17604 }
17605
17606 int
17607 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
17608 {
17609   unformat_input_t *input = vam->input;
17610   vl_api_ip_source_and_port_range_check_add_del_t *mp;
17611
17612   u16 *low_ports = 0;
17613   u16 *high_ports = 0;
17614   u16 this_low;
17615   u16 this_hi;
17616   ip4_address_t ip4_addr;
17617   ip6_address_t ip6_addr;
17618   u32 length;
17619   u32 tmp, tmp2;
17620   u8 prefix_set = 0;
17621   u32 vrf_id = ~0;
17622   u8 is_add = 1;
17623   u8 is_ipv6 = 0;
17624   int ret;
17625
17626   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17627     {
17628       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
17629         {
17630           prefix_set = 1;
17631         }
17632       else
17633         if (unformat
17634             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
17635         {
17636           prefix_set = 1;
17637           is_ipv6 = 1;
17638         }
17639       else if (unformat (input, "vrf %d", &vrf_id))
17640         ;
17641       else if (unformat (input, "del"))
17642         is_add = 0;
17643       else if (unformat (input, "port %d", &tmp))
17644         {
17645           if (tmp == 0 || tmp > 65535)
17646             {
17647               errmsg ("port %d out of range", tmp);
17648               return -99;
17649             }
17650           this_low = tmp;
17651           this_hi = this_low + 1;
17652           vec_add1 (low_ports, this_low);
17653           vec_add1 (high_ports, this_hi);
17654         }
17655       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
17656         {
17657           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
17658             {
17659               errmsg ("incorrect range parameters");
17660               return -99;
17661             }
17662           this_low = tmp;
17663           /* Note: in debug CLI +1 is added to high before
17664              passing to real fn that does "the work"
17665              (ip_source_and_port_range_check_add_del).
17666              This fn is a wrapper around the binary API fn a
17667              control plane will call, which expects this increment
17668              to have occurred. Hence letting the binary API control
17669              plane fn do the increment for consistency between VAT
17670              and other control planes.
17671            */
17672           this_hi = tmp2;
17673           vec_add1 (low_ports, this_low);
17674           vec_add1 (high_ports, this_hi);
17675         }
17676       else
17677         break;
17678     }
17679
17680   if (prefix_set == 0)
17681     {
17682       errmsg ("<address>/<mask> not specified");
17683       return -99;
17684     }
17685
17686   if (vrf_id == ~0)
17687     {
17688       errmsg ("VRF ID required, not specified");
17689       return -99;
17690     }
17691
17692   if (vrf_id == 0)
17693     {
17694       errmsg
17695         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17696       return -99;
17697     }
17698
17699   if (vec_len (low_ports) == 0)
17700     {
17701       errmsg ("At least one port or port range required");
17702       return -99;
17703     }
17704
17705   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
17706
17707   mp->is_add = is_add;
17708
17709   if (is_ipv6)
17710     {
17711       mp->is_ipv6 = 1;
17712       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
17713     }
17714   else
17715     {
17716       mp->is_ipv6 = 0;
17717       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
17718     }
17719
17720   mp->mask_length = length;
17721   mp->number_of_ranges = vec_len (low_ports);
17722
17723   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
17724   vec_free (low_ports);
17725
17726   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
17727   vec_free (high_ports);
17728
17729   mp->vrf_id = ntohl (vrf_id);
17730
17731   S (mp);
17732   W (ret);
17733   return ret;
17734 }
17735
17736 int
17737 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
17738 {
17739   unformat_input_t *input = vam->input;
17740   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
17741   u32 sw_if_index = ~0;
17742   int vrf_set = 0;
17743   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
17744   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
17745   u8 is_add = 1;
17746   int ret;
17747
17748   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17749     {
17750       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17751         ;
17752       else if (unformat (input, "sw_if_index %d", &sw_if_index))
17753         ;
17754       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
17755         vrf_set = 1;
17756       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
17757         vrf_set = 1;
17758       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
17759         vrf_set = 1;
17760       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
17761         vrf_set = 1;
17762       else if (unformat (input, "del"))
17763         is_add = 0;
17764       else
17765         break;
17766     }
17767
17768   if (sw_if_index == ~0)
17769     {
17770       errmsg ("Interface required but not specified");
17771       return -99;
17772     }
17773
17774   if (vrf_set == 0)
17775     {
17776       errmsg ("VRF ID required but not specified");
17777       return -99;
17778     }
17779
17780   if (tcp_out_vrf_id == 0
17781       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
17782     {
17783       errmsg
17784         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17785       return -99;
17786     }
17787
17788   /* Construct the API message */
17789   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
17790
17791   mp->sw_if_index = ntohl (sw_if_index);
17792   mp->is_add = is_add;
17793   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
17794   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
17795   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
17796   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
17797
17798   /* send it... */
17799   S (mp);
17800
17801   /* Wait for a reply... */
17802   W (ret);
17803   return ret;
17804 }
17805
17806 static int
17807 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
17808 {
17809   unformat_input_t *i = vam->input;
17810   vl_api_ipsec_gre_add_del_tunnel_t *mp;
17811   u32 local_sa_id = 0;
17812   u32 remote_sa_id = 0;
17813   ip4_address_t src_address;
17814   ip4_address_t dst_address;
17815   u8 is_add = 1;
17816   int ret;
17817
17818   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17819     {
17820       if (unformat (i, "local_sa %d", &local_sa_id))
17821         ;
17822       else if (unformat (i, "remote_sa %d", &remote_sa_id))
17823         ;
17824       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
17825         ;
17826       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
17827         ;
17828       else if (unformat (i, "del"))
17829         is_add = 0;
17830       else
17831         {
17832           clib_warning ("parse error '%U'", format_unformat_error, i);
17833           return -99;
17834         }
17835     }
17836
17837   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
17838
17839   mp->local_sa_id = ntohl (local_sa_id);
17840   mp->remote_sa_id = ntohl (remote_sa_id);
17841   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
17842   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
17843   mp->is_add = is_add;
17844
17845   S (mp);
17846   W (ret);
17847   return ret;
17848 }
17849
17850 static int
17851 api_punt (vat_main_t * vam)
17852 {
17853   unformat_input_t *i = vam->input;
17854   vl_api_punt_t *mp;
17855   u32 ipv = ~0;
17856   u32 protocol = ~0;
17857   u32 port = ~0;
17858   int is_add = 1;
17859   int ret;
17860
17861   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17862     {
17863       if (unformat (i, "ip %d", &ipv))
17864         ;
17865       else if (unformat (i, "protocol %d", &protocol))
17866         ;
17867       else if (unformat (i, "port %d", &port))
17868         ;
17869       else if (unformat (i, "del"))
17870         is_add = 0;
17871       else
17872         {
17873           clib_warning ("parse error '%U'", format_unformat_error, i);
17874           return -99;
17875         }
17876     }
17877
17878   M (PUNT, mp);
17879
17880   mp->is_add = (u8) is_add;
17881   mp->ipv = (u8) ipv;
17882   mp->l4_protocol = (u8) protocol;
17883   mp->l4_port = htons ((u16) port);
17884
17885   S (mp);
17886   W (ret);
17887   return ret;
17888 }
17889
17890 static void vl_api_ipsec_gre_tunnel_details_t_handler
17891   (vl_api_ipsec_gre_tunnel_details_t * mp)
17892 {
17893   vat_main_t *vam = &vat_main;
17894
17895   print (vam->ofp, "%11d%15U%15U%14d%14d",
17896          ntohl (mp->sw_if_index),
17897          format_ip4_address, &mp->src_address,
17898          format_ip4_address, &mp->dst_address,
17899          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
17900 }
17901
17902 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
17903   (vl_api_ipsec_gre_tunnel_details_t * mp)
17904 {
17905   vat_main_t *vam = &vat_main;
17906   vat_json_node_t *node = NULL;
17907   struct in_addr ip4;
17908
17909   if (VAT_JSON_ARRAY != vam->json_tree.type)
17910     {
17911       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17912       vat_json_init_array (&vam->json_tree);
17913     }
17914   node = vat_json_array_add (&vam->json_tree);
17915
17916   vat_json_init_object (node);
17917   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17918   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
17919   vat_json_object_add_ip4 (node, "src_address", ip4);
17920   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
17921   vat_json_object_add_ip4 (node, "dst_address", ip4);
17922   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
17923   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
17924 }
17925
17926 static int
17927 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
17928 {
17929   unformat_input_t *i = vam->input;
17930   vl_api_ipsec_gre_tunnel_dump_t *mp;
17931   vl_api_control_ping_t *mp_ping;
17932   u32 sw_if_index;
17933   u8 sw_if_index_set = 0;
17934   int ret;
17935
17936   /* Parse args required to build the message */
17937   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17938     {
17939       if (unformat (i, "sw_if_index %d", &sw_if_index))
17940         sw_if_index_set = 1;
17941       else
17942         break;
17943     }
17944
17945   if (sw_if_index_set == 0)
17946     {
17947       sw_if_index = ~0;
17948     }
17949
17950   if (!vam->json_output)
17951     {
17952       print (vam->ofp, "%11s%15s%15s%14s%14s",
17953              "sw_if_index", "src_address", "dst_address",
17954              "local_sa_id", "remote_sa_id");
17955     }
17956
17957   /* Get list of gre-tunnel interfaces */
17958   M (IPSEC_GRE_TUNNEL_DUMP, mp);
17959
17960   mp->sw_if_index = htonl (sw_if_index);
17961
17962   S (mp);
17963
17964   /* Use a control ping for synchronization */
17965   M (CONTROL_PING, mp_ping);
17966   S (mp_ping);
17967
17968   W (ret);
17969   return ret;
17970 }
17971
17972 static int
17973 api_delete_subif (vat_main_t * vam)
17974 {
17975   unformat_input_t *i = vam->input;
17976   vl_api_delete_subif_t *mp;
17977   u32 sw_if_index = ~0;
17978   int ret;
17979
17980   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17981     {
17982       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17983         ;
17984       if (unformat (i, "sw_if_index %d", &sw_if_index))
17985         ;
17986       else
17987         break;
17988     }
17989
17990   if (sw_if_index == ~0)
17991     {
17992       errmsg ("missing sw_if_index");
17993       return -99;
17994     }
17995
17996   /* Construct the API message */
17997   M (DELETE_SUBIF, mp);
17998   mp->sw_if_index = ntohl (sw_if_index);
17999
18000   S (mp);
18001   W (ret);
18002   return ret;
18003 }
18004
18005 #define foreach_pbb_vtr_op      \
18006 _("disable",  L2_VTR_DISABLED)  \
18007 _("pop",  L2_VTR_POP_2)         \
18008 _("push",  L2_VTR_PUSH_2)
18009
18010 static int
18011 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
18012 {
18013   unformat_input_t *i = vam->input;
18014   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
18015   u32 sw_if_index = ~0, vtr_op = ~0;
18016   u16 outer_tag = ~0;
18017   u8 dmac[6], smac[6];
18018   u8 dmac_set = 0, smac_set = 0;
18019   u16 vlanid = 0;
18020   u32 sid = ~0;
18021   u32 tmp;
18022   int ret;
18023
18024   /* Shut up coverity */
18025   memset (dmac, 0, sizeof (dmac));
18026   memset (smac, 0, sizeof (smac));
18027
18028   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18029     {
18030       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18031         ;
18032       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18033         ;
18034       else if (unformat (i, "vtr_op %d", &vtr_op))
18035         ;
18036 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
18037       foreach_pbb_vtr_op
18038 #undef _
18039         else if (unformat (i, "translate_pbb_stag"))
18040         {
18041           if (unformat (i, "%d", &tmp))
18042             {
18043               vtr_op = L2_VTR_TRANSLATE_2_1;
18044               outer_tag = tmp;
18045             }
18046           else
18047             {
18048               errmsg
18049                 ("translate_pbb_stag operation requires outer tag definition");
18050               return -99;
18051             }
18052         }
18053       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
18054         dmac_set++;
18055       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
18056         smac_set++;
18057       else if (unformat (i, "sid %d", &sid))
18058         ;
18059       else if (unformat (i, "vlanid %d", &tmp))
18060         vlanid = tmp;
18061       else
18062         {
18063           clib_warning ("parse error '%U'", format_unformat_error, i);
18064           return -99;
18065         }
18066     }
18067
18068   if ((sw_if_index == ~0) || (vtr_op == ~0))
18069     {
18070       errmsg ("missing sw_if_index or vtr operation");
18071       return -99;
18072     }
18073   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
18074       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
18075     {
18076       errmsg
18077         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
18078       return -99;
18079     }
18080
18081   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
18082   mp->sw_if_index = ntohl (sw_if_index);
18083   mp->vtr_op = ntohl (vtr_op);
18084   mp->outer_tag = ntohs (outer_tag);
18085   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
18086   clib_memcpy (mp->b_smac, smac, sizeof (smac));
18087   mp->b_vlanid = ntohs (vlanid);
18088   mp->i_sid = ntohl (sid);
18089
18090   S (mp);
18091   W (ret);
18092   return ret;
18093 }
18094
18095 static int
18096 api_flow_classify_set_interface (vat_main_t * vam)
18097 {
18098   unformat_input_t *i = vam->input;
18099   vl_api_flow_classify_set_interface_t *mp;
18100   u32 sw_if_index;
18101   int sw_if_index_set;
18102   u32 ip4_table_index = ~0;
18103   u32 ip6_table_index = ~0;
18104   u8 is_add = 1;
18105   int ret;
18106
18107   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18108     {
18109       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18110         sw_if_index_set = 1;
18111       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18112         sw_if_index_set = 1;
18113       else if (unformat (i, "del"))
18114         is_add = 0;
18115       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18116         ;
18117       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18118         ;
18119       else
18120         {
18121           clib_warning ("parse error '%U'", format_unformat_error, i);
18122           return -99;
18123         }
18124     }
18125
18126   if (sw_if_index_set == 0)
18127     {
18128       errmsg ("missing interface name or sw_if_index");
18129       return -99;
18130     }
18131
18132   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
18133
18134   mp->sw_if_index = ntohl (sw_if_index);
18135   mp->ip4_table_index = ntohl (ip4_table_index);
18136   mp->ip6_table_index = ntohl (ip6_table_index);
18137   mp->is_add = is_add;
18138
18139   S (mp);
18140   W (ret);
18141   return ret;
18142 }
18143
18144 static int
18145 api_flow_classify_dump (vat_main_t * vam)
18146 {
18147   unformat_input_t *i = vam->input;
18148   vl_api_flow_classify_dump_t *mp;
18149   vl_api_control_ping_t *mp_ping;
18150   u8 type = FLOW_CLASSIFY_N_TABLES;
18151   int ret;
18152
18153   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
18154     ;
18155   else
18156     {
18157       errmsg ("classify table type must be specified");
18158       return -99;
18159     }
18160
18161   if (!vam->json_output)
18162     {
18163       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18164     }
18165
18166   M (FLOW_CLASSIFY_DUMP, mp);
18167   mp->type = type;
18168   /* send it... */
18169   S (mp);
18170
18171   /* Use a control ping for synchronization */
18172   M (CONTROL_PING, mp_ping);
18173   S (mp_ping);
18174
18175   /* Wait for a reply... */
18176   W (ret);
18177   return ret;
18178 }
18179
18180 static int
18181 api_feature_enable_disable (vat_main_t * vam)
18182 {
18183   unformat_input_t *i = vam->input;
18184   vl_api_feature_enable_disable_t *mp;
18185   u8 *arc_name = 0;
18186   u8 *feature_name = 0;
18187   u32 sw_if_index = ~0;
18188   u8 enable = 1;
18189   int ret;
18190
18191   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18192     {
18193       if (unformat (i, "arc_name %s", &arc_name))
18194         ;
18195       else if (unformat (i, "feature_name %s", &feature_name))
18196         ;
18197       else
18198         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18199         ;
18200       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18201         ;
18202       else if (unformat (i, "disable"))
18203         enable = 0;
18204       else
18205         break;
18206     }
18207
18208   if (arc_name == 0)
18209     {
18210       errmsg ("missing arc name");
18211       return -99;
18212     }
18213   if (vec_len (arc_name) > 63)
18214     {
18215       errmsg ("arc name too long");
18216     }
18217
18218   if (feature_name == 0)
18219     {
18220       errmsg ("missing feature name");
18221       return -99;
18222     }
18223   if (vec_len (feature_name) > 63)
18224     {
18225       errmsg ("feature name too long");
18226     }
18227
18228   if (sw_if_index == ~0)
18229     {
18230       errmsg ("missing interface name or sw_if_index");
18231       return -99;
18232     }
18233
18234   /* Construct the API message */
18235   M (FEATURE_ENABLE_DISABLE, mp);
18236   mp->sw_if_index = ntohl (sw_if_index);
18237   mp->enable = enable;
18238   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
18239   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
18240   vec_free (arc_name);
18241   vec_free (feature_name);
18242
18243   S (mp);
18244   W (ret);
18245   return ret;
18246 }
18247
18248 static int
18249 api_sw_interface_tag_add_del (vat_main_t * vam)
18250 {
18251   unformat_input_t *i = vam->input;
18252   vl_api_sw_interface_tag_add_del_t *mp;
18253   u32 sw_if_index = ~0;
18254   u8 *tag = 0;
18255   u8 enable = 1;
18256   int ret;
18257
18258   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18259     {
18260       if (unformat (i, "tag %s", &tag))
18261         ;
18262       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18263         ;
18264       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18265         ;
18266       else if (unformat (i, "del"))
18267         enable = 0;
18268       else
18269         break;
18270     }
18271
18272   if (sw_if_index == ~0)
18273     {
18274       errmsg ("missing interface name or sw_if_index");
18275       return -99;
18276     }
18277
18278   if (enable && (tag == 0))
18279     {
18280       errmsg ("no tag specified");
18281       return -99;
18282     }
18283
18284   /* Construct the API message */
18285   M (SW_INTERFACE_TAG_ADD_DEL, mp);
18286   mp->sw_if_index = ntohl (sw_if_index);
18287   mp->is_add = enable;
18288   if (enable)
18289     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
18290   vec_free (tag);
18291
18292   S (mp);
18293   W (ret);
18294   return ret;
18295 }
18296
18297 static void vl_api_l2_xconnect_details_t_handler
18298   (vl_api_l2_xconnect_details_t * mp)
18299 {
18300   vat_main_t *vam = &vat_main;
18301
18302   print (vam->ofp, "%15d%15d",
18303          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
18304 }
18305
18306 static void vl_api_l2_xconnect_details_t_handler_json
18307   (vl_api_l2_xconnect_details_t * mp)
18308 {
18309   vat_main_t *vam = &vat_main;
18310   vat_json_node_t *node = NULL;
18311
18312   if (VAT_JSON_ARRAY != vam->json_tree.type)
18313     {
18314       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18315       vat_json_init_array (&vam->json_tree);
18316     }
18317   node = vat_json_array_add (&vam->json_tree);
18318
18319   vat_json_init_object (node);
18320   vat_json_object_add_uint (node, "rx_sw_if_index",
18321                             ntohl (mp->rx_sw_if_index));
18322   vat_json_object_add_uint (node, "tx_sw_if_index",
18323                             ntohl (mp->tx_sw_if_index));
18324 }
18325
18326 static int
18327 api_l2_xconnect_dump (vat_main_t * vam)
18328 {
18329   vl_api_l2_xconnect_dump_t *mp;
18330   vl_api_control_ping_t *mp_ping;
18331   int ret;
18332
18333   if (!vam->json_output)
18334     {
18335       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
18336     }
18337
18338   M (L2_XCONNECT_DUMP, mp);
18339
18340   S (mp);
18341
18342   /* Use a control ping for synchronization */
18343   M (CONTROL_PING, mp_ping);
18344   S (mp_ping);
18345
18346   W (ret);
18347   return ret;
18348 }
18349
18350 static int
18351 api_sw_interface_set_mtu (vat_main_t * vam)
18352 {
18353   unformat_input_t *i = vam->input;
18354   vl_api_sw_interface_set_mtu_t *mp;
18355   u32 sw_if_index = ~0;
18356   u32 mtu = 0;
18357   int ret;
18358
18359   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18360     {
18361       if (unformat (i, "mtu %d", &mtu))
18362         ;
18363       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18364         ;
18365       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18366         ;
18367       else
18368         break;
18369     }
18370
18371   if (sw_if_index == ~0)
18372     {
18373       errmsg ("missing interface name or sw_if_index");
18374       return -99;
18375     }
18376
18377   if (mtu == 0)
18378     {
18379       errmsg ("no mtu specified");
18380       return -99;
18381     }
18382
18383   /* Construct the API message */
18384   M (SW_INTERFACE_SET_MTU, mp);
18385   mp->sw_if_index = ntohl (sw_if_index);
18386   mp->mtu = ntohs ((u16) mtu);
18387
18388   S (mp);
18389   W (ret);
18390   return ret;
18391 }
18392
18393
18394 static int
18395 q_or_quit (vat_main_t * vam)
18396 {
18397 #if VPP_API_TEST_BUILTIN == 0
18398   longjmp (vam->jump_buf, 1);
18399 #endif
18400   return 0;                     /* not so much */
18401 }
18402
18403 static int
18404 q (vat_main_t * vam)
18405 {
18406   return q_or_quit (vam);
18407 }
18408
18409 static int
18410 quit (vat_main_t * vam)
18411 {
18412   return q_or_quit (vam);
18413 }
18414
18415 static int
18416 comment (vat_main_t * vam)
18417 {
18418   return 0;
18419 }
18420
18421 static int
18422 cmd_cmp (void *a1, void *a2)
18423 {
18424   u8 **c1 = a1;
18425   u8 **c2 = a2;
18426
18427   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
18428 }
18429
18430 static int
18431 help (vat_main_t * vam)
18432 {
18433   u8 **cmds = 0;
18434   u8 *name = 0;
18435   hash_pair_t *p;
18436   unformat_input_t *i = vam->input;
18437   int j;
18438
18439   if (unformat (i, "%s", &name))
18440     {
18441       uword *hs;
18442
18443       vec_add1 (name, 0);
18444
18445       hs = hash_get_mem (vam->help_by_name, name);
18446       if (hs)
18447         print (vam->ofp, "usage: %s %s", name, hs[0]);
18448       else
18449         print (vam->ofp, "No such msg / command '%s'", name);
18450       vec_free (name);
18451       return 0;
18452     }
18453
18454   print (vam->ofp, "Help is available for the following:");
18455
18456     /* *INDENT-OFF* */
18457     hash_foreach_pair (p, vam->function_by_name,
18458     ({
18459       vec_add1 (cmds, (u8 *)(p->key));
18460     }));
18461     /* *INDENT-ON* */
18462
18463   vec_sort_with_function (cmds, cmd_cmp);
18464
18465   for (j = 0; j < vec_len (cmds); j++)
18466     print (vam->ofp, "%s", cmds[j]);
18467
18468   vec_free (cmds);
18469   return 0;
18470 }
18471
18472 static int
18473 set (vat_main_t * vam)
18474 {
18475   u8 *name = 0, *value = 0;
18476   unformat_input_t *i = vam->input;
18477
18478   if (unformat (i, "%s", &name))
18479     {
18480       /* The input buffer is a vector, not a string. */
18481       value = vec_dup (i->buffer);
18482       vec_delete (value, i->index, 0);
18483       /* Almost certainly has a trailing newline */
18484       if (value[vec_len (value) - 1] == '\n')
18485         value[vec_len (value) - 1] = 0;
18486       /* Make sure it's a proper string, one way or the other */
18487       vec_add1 (value, 0);
18488       (void) clib_macro_set_value (&vam->macro_main,
18489                                    (char *) name, (char *) value);
18490     }
18491   else
18492     errmsg ("usage: set <name> <value>");
18493
18494   vec_free (name);
18495   vec_free (value);
18496   return 0;
18497 }
18498
18499 static int
18500 unset (vat_main_t * vam)
18501 {
18502   u8 *name = 0;
18503
18504   if (unformat (vam->input, "%s", &name))
18505     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
18506       errmsg ("unset: %s wasn't set", name);
18507   vec_free (name);
18508   return 0;
18509 }
18510
18511 typedef struct
18512 {
18513   u8 *name;
18514   u8 *value;
18515 } macro_sort_t;
18516
18517
18518 static int
18519 macro_sort_cmp (void *a1, void *a2)
18520 {
18521   macro_sort_t *s1 = a1;
18522   macro_sort_t *s2 = a2;
18523
18524   return strcmp ((char *) (s1->name), (char *) (s2->name));
18525 }
18526
18527 static int
18528 dump_macro_table (vat_main_t * vam)
18529 {
18530   macro_sort_t *sort_me = 0, *sm;
18531   int i;
18532   hash_pair_t *p;
18533
18534     /* *INDENT-OFF* */
18535     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
18536     ({
18537       vec_add2 (sort_me, sm, 1);
18538       sm->name = (u8 *)(p->key);
18539       sm->value = (u8 *) (p->value[0]);
18540     }));
18541     /* *INDENT-ON* */
18542
18543   vec_sort_with_function (sort_me, macro_sort_cmp);
18544
18545   if (vec_len (sort_me))
18546     print (vam->ofp, "%-15s%s", "Name", "Value");
18547   else
18548     print (vam->ofp, "The macro table is empty...");
18549
18550   for (i = 0; i < vec_len (sort_me); i++)
18551     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
18552   return 0;
18553 }
18554
18555 static int
18556 dump_node_table (vat_main_t * vam)
18557 {
18558   int i, j;
18559   vlib_node_t *node, *next_node;
18560
18561   if (vec_len (vam->graph_nodes) == 0)
18562     {
18563       print (vam->ofp, "Node table empty, issue get_node_graph...");
18564       return 0;
18565     }
18566
18567   for (i = 0; i < vec_len (vam->graph_nodes); i++)
18568     {
18569       node = vam->graph_nodes[i];
18570       print (vam->ofp, "[%d] %s", i, node->name);
18571       for (j = 0; j < vec_len (node->next_nodes); j++)
18572         {
18573           if (node->next_nodes[j] != ~0)
18574             {
18575               next_node = vam->graph_nodes[node->next_nodes[j]];
18576               print (vam->ofp, "  [%d] %s", j, next_node->name);
18577             }
18578         }
18579     }
18580   return 0;
18581 }
18582
18583 static int
18584 value_sort_cmp (void *a1, void *a2)
18585 {
18586   name_sort_t *n1 = a1;
18587   name_sort_t *n2 = a2;
18588
18589   if (n1->value < n2->value)
18590     return -1;
18591   if (n1->value > n2->value)
18592     return 1;
18593   return 0;
18594 }
18595
18596
18597 static int
18598 dump_msg_api_table (vat_main_t * vam)
18599 {
18600   api_main_t *am = &api_main;
18601   name_sort_t *nses = 0, *ns;
18602   hash_pair_t *hp;
18603   int i;
18604
18605   /* *INDENT-OFF* */
18606   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
18607   ({
18608     vec_add2 (nses, ns, 1);
18609     ns->name = (u8 *)(hp->key);
18610     ns->value = (u32) hp->value[0];
18611   }));
18612   /* *INDENT-ON* */
18613
18614   vec_sort_with_function (nses, value_sort_cmp);
18615
18616   for (i = 0; i < vec_len (nses); i++)
18617     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
18618   vec_free (nses);
18619   return 0;
18620 }
18621
18622 static int
18623 get_msg_id (vat_main_t * vam)
18624 {
18625   u8 *name_and_crc;
18626   u32 message_index;
18627
18628   if (unformat (vam->input, "%s", &name_and_crc))
18629     {
18630       message_index = vl_api_get_msg_index (name_and_crc);
18631       if (message_index == ~0)
18632         {
18633           print (vam->ofp, " '%s' not found", name_and_crc);
18634           return 0;
18635         }
18636       print (vam->ofp, " '%s' has message index %d",
18637              name_and_crc, message_index);
18638       return 0;
18639     }
18640   errmsg ("name_and_crc required...");
18641   return 0;
18642 }
18643
18644 static int
18645 search_node_table (vat_main_t * vam)
18646 {
18647   unformat_input_t *line_input = vam->input;
18648   u8 *node_to_find;
18649   int j;
18650   vlib_node_t *node, *next_node;
18651   uword *p;
18652
18653   if (vam->graph_node_index_by_name == 0)
18654     {
18655       print (vam->ofp, "Node table empty, issue get_node_graph...");
18656       return 0;
18657     }
18658
18659   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
18660     {
18661       if (unformat (line_input, "%s", &node_to_find))
18662         {
18663           vec_add1 (node_to_find, 0);
18664           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
18665           if (p == 0)
18666             {
18667               print (vam->ofp, "%s not found...", node_to_find);
18668               goto out;
18669             }
18670           node = vam->graph_nodes[p[0]];
18671           print (vam->ofp, "[%d] %s", p[0], node->name);
18672           for (j = 0; j < vec_len (node->next_nodes); j++)
18673             {
18674               if (node->next_nodes[j] != ~0)
18675                 {
18676                   next_node = vam->graph_nodes[node->next_nodes[j]];
18677                   print (vam->ofp, "  [%d] %s", j, next_node->name);
18678                 }
18679             }
18680         }
18681
18682       else
18683         {
18684           clib_warning ("parse error '%U'", format_unformat_error,
18685                         line_input);
18686           return -99;
18687         }
18688
18689     out:
18690       vec_free (node_to_find);
18691
18692     }
18693
18694   return 0;
18695 }
18696
18697
18698 static int
18699 script (vat_main_t * vam)
18700 {
18701 #if (VPP_API_TEST_BUILTIN==0)
18702   u8 *s = 0;
18703   char *save_current_file;
18704   unformat_input_t save_input;
18705   jmp_buf save_jump_buf;
18706   u32 save_line_number;
18707
18708   FILE *new_fp, *save_ifp;
18709
18710   if (unformat (vam->input, "%s", &s))
18711     {
18712       new_fp = fopen ((char *) s, "r");
18713       if (new_fp == 0)
18714         {
18715           errmsg ("Couldn't open script file %s", s);
18716           vec_free (s);
18717           return -99;
18718         }
18719     }
18720   else
18721     {
18722       errmsg ("Missing script name");
18723       return -99;
18724     }
18725
18726   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
18727   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
18728   save_ifp = vam->ifp;
18729   save_line_number = vam->input_line_number;
18730   save_current_file = (char *) vam->current_file;
18731
18732   vam->input_line_number = 0;
18733   vam->ifp = new_fp;
18734   vam->current_file = s;
18735   do_one_file (vam);
18736
18737   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
18738   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
18739   vam->ifp = save_ifp;
18740   vam->input_line_number = save_line_number;
18741   vam->current_file = (u8 *) save_current_file;
18742   vec_free (s);
18743
18744   return 0;
18745 #else
18746   clib_warning ("use the exec command...");
18747   return -99;
18748 #endif
18749 }
18750
18751 static int
18752 echo (vat_main_t * vam)
18753 {
18754   print (vam->ofp, "%v", vam->input->buffer);
18755   return 0;
18756 }
18757
18758 /* List of API message constructors, CLI names map to api_xxx */
18759 #define foreach_vpe_api_msg                                             \
18760 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
18761 _(sw_interface_dump,"")                                                 \
18762 _(sw_interface_set_flags,                                               \
18763   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
18764 _(sw_interface_add_del_address,                                         \
18765   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
18766 _(sw_interface_set_table,                                               \
18767   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
18768 _(sw_interface_set_mpls_enable,                                         \
18769   "<intfc> | sw_if_index [disable | dis]")                              \
18770 _(sw_interface_set_vpath,                                               \
18771   "<intfc> | sw_if_index <id> enable | disable")                        \
18772 _(sw_interface_set_vxlan_bypass,                                        \
18773   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
18774 _(sw_interface_set_l2_xconnect,                                         \
18775   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18776   "enable | disable")                                                   \
18777 _(sw_interface_set_l2_bridge,                                           \
18778   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
18779   "[shg <split-horizon-group>] [bvi]\n"                                 \
18780   "enable | disable")                                                   \
18781 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
18782 _(bridge_domain_add_del,                                                \
18783   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [mac-age 0-255] [del]\n") \
18784 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
18785 _(l2fib_add_del,                                                        \
18786   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
18787 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
18788 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
18789 _(l2_flags,                                                             \
18790   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
18791 _(bridge_flags,                                                         \
18792   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
18793 _(tap_connect,                                                          \
18794   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
18795 _(tap_modify,                                                           \
18796   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
18797 _(tap_delete,                                                           \
18798   "<vpp-if-name> | sw_if_index <id>")                                   \
18799 _(sw_interface_tap_dump, "")                                            \
18800 _(ip_add_del_route,                                                     \
18801   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
18802   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
18803   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
18804   "[multipath] [count <n>]")                                            \
18805 _(ip_mroute_add_del,                                                    \
18806   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
18807   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
18808 _(mpls_route_add_del,                                                   \
18809   "<label> <eos> via <addr> [table-id <n>]\n"                           \
18810   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
18811   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
18812   "[multipath] [count <n>]")                                            \
18813 _(mpls_ip_bind_unbind,                                                  \
18814   "<label> <addr/len>")                                                 \
18815 _(mpls_tunnel_add_del,                                                  \
18816   " via <addr> [table-id <n>]\n"                                        \
18817   "sw_if_index <id>] [l2]  [del]")                                      \
18818 _(proxy_arp_add_del,                                                    \
18819   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
18820 _(proxy_arp_intfc_enable_disable,                                       \
18821   "<intfc> | sw_if_index <id> enable | disable")                        \
18822 _(sw_interface_set_unnumbered,                                          \
18823   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
18824 _(ip_neighbor_add_del,                                                  \
18825   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
18826   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
18827 _(reset_vrf, "vrf <id> [ipv6]")                                         \
18828 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
18829 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
18830   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
18831   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
18832   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
18833 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
18834 _(reset_fib, "vrf <n> [ipv6]")                                          \
18835 _(dhcp_proxy_config,                                                    \
18836   "svr <v46-address> src <v46-address>\n"                               \
18837    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
18838 _(dhcp_proxy_set_vss,                                                   \
18839   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
18840 _(dhcp_proxy_dump, "ip6")                                               \
18841 _(dhcp_client_config,                                                   \
18842   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
18843 _(set_ip_flow_hash,                                                     \
18844   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
18845 _(sw_interface_ip6_enable_disable,                                      \
18846   "<intfc> | sw_if_index <id> enable | disable")                        \
18847 _(sw_interface_ip6_set_link_local_address,                              \
18848   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
18849 _(ip6nd_proxy_add_del,                                                  \
18850   "<intfc> | sw_if_index <id> <ip6-address>")                           \
18851 _(ip6nd_proxy_dump, "")                                                 \
18852 _(sw_interface_ip6nd_ra_prefix,                                         \
18853   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
18854   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
18855   "[nolink] [isno]")                                                    \
18856 _(sw_interface_ip6nd_ra_config,                                         \
18857   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
18858   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
18859   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
18860 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
18861 _(l2_patch_add_del,                                                     \
18862   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18863   "enable | disable")                                                   \
18864 _(sr_localsid_add_del,                                                  \
18865   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
18866   "fib-table <num> (end.psp) sw_if_index <num>")                        \
18867 _(classify_add_del_table,                                               \
18868   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
18869   " [del] [del-chain] mask <mask-value>\n"                              \
18870   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
18871   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
18872 _(classify_add_del_session,                                             \
18873   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
18874   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
18875   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
18876   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
18877 _(classify_set_interface_ip_table,                                      \
18878   "<intfc> | sw_if_index <nn> table <nn>")                              \
18879 _(classify_set_interface_l2_tables,                                     \
18880   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18881   "  [other-table <nn>]")                                               \
18882 _(get_node_index, "node <node-name")                                    \
18883 _(add_node_next, "node <node-name> next <next-node-name>")              \
18884 _(l2tpv3_create_tunnel,                                                 \
18885   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
18886   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
18887   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
18888 _(l2tpv3_set_tunnel_cookies,                                            \
18889   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
18890   "[new_remote_cookie <nn>]\n")                                         \
18891 _(l2tpv3_interface_enable_disable,                                      \
18892   "<intfc> | sw_if_index <nn> enable | disable")                        \
18893 _(l2tpv3_set_lookup_key,                                                \
18894   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
18895 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
18896 _(vxlan_add_del_tunnel,                                                 \
18897   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
18898   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
18899   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
18900 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
18901 _(gre_add_del_tunnel,                                                   \
18902   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
18903 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
18904 _(l2_fib_clear_table, "")                                               \
18905 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
18906 _(l2_interface_vlan_tag_rewrite,                                        \
18907   "<intfc> | sw_if_index <nn> \n"                                       \
18908   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
18909   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
18910 _(create_vhost_user_if,                                                 \
18911         "socket <filename> [server] [renumber <dev_instance>] "         \
18912         "[mac <mac_address>] "                                          \
18913         "[mode <interrupt | polling>]")                                 \
18914 _(modify_vhost_user_if,                                                 \
18915         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
18916         "[server] [renumber <dev_instance>] "                           \
18917         "[mode <interrupt | polling>]")                                 \
18918 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
18919 _(sw_interface_vhost_user_dump, "")                                     \
18920 _(show_version, "")                                                     \
18921 _(vxlan_gpe_add_del_tunnel,                                             \
18922   "local <addr> remote <addr> vni <nn>\n"                               \
18923     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
18924   "[next-ethernet] [next-nsh]\n")                                       \
18925 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
18926 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
18927 _(interface_name_renumber,                                              \
18928   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
18929 _(input_acl_set_interface,                                              \
18930   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18931   "  [l2-table <nn>] [del]")                                            \
18932 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
18933 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
18934 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
18935 _(ip_dump, "ipv4 | ipv6")                                               \
18936 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
18937 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
18938   "  spid_id <n> ")                                                     \
18939 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
18940   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
18941   "  integ_alg <alg> integ_key <hex>")                                  \
18942 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
18943   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
18944   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
18945   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
18946 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
18947 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
18948   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
18949   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
18950   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
18951 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
18952 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
18953   "(auth_data 0x<data> | auth_data <data>)")                            \
18954 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
18955   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
18956 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
18957   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
18958   "(local|remote)")                                                     \
18959 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
18960 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
18961 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18962 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18963 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
18964 _(ikev2_initiate_sa_init, "<profile_name>")                             \
18965 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
18966 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
18967 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
18968 _(delete_loopback,"sw_if_index <nn>")                                   \
18969 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
18970 _(map_add_domain,                                                       \
18971   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
18972   "ip6-src <ip6addr> "                                                  \
18973   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
18974 _(map_del_domain, "index <n>")                                          \
18975 _(map_add_del_rule,                                                     \
18976   "index <n> psid <n> dst <ip6addr> [del]")                             \
18977 _(map_domain_dump, "")                                                  \
18978 _(map_rule_dump, "index <map-domain>")                                  \
18979 _(want_interface_events,  "enable|disable")                             \
18980 _(want_stats,"enable|disable")                                          \
18981 _(get_first_msg_id, "client <name>")                                    \
18982 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
18983 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
18984   "fib-id <nn> [ip4][ip6][default]")                                    \
18985 _(get_node_graph, " ")                                                  \
18986 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
18987 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
18988 _(ioam_disable, "")                                                     \
18989 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
18990                             " sw_if_index <sw_if_index> p <priority> "  \
18991                             "w <weight>] [del]")                        \
18992 _(one_add_del_locator, "locator-set <locator_name> "                    \
18993                         "iface <intf> | sw_if_index <sw_if_index> "     \
18994                         "p <priority> w <weight> [del]")                \
18995 _(one_add_del_local_eid,"vni <vni> eid "                                \
18996                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
18997                          "locator-set <locator_name> [del]"             \
18998                          "[key-id sha1|sha256 secret-key <secret-key>]")\
18999 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
19000 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
19001 _(one_enable_disable, "enable|disable")                                 \
19002 _(one_map_register_enable_disable, "enable|disable")                    \
19003 _(one_rloc_probe_enable_disable, "enable|disable")                      \
19004 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
19005                                "[seid <seid>] "                         \
19006                                "rloc <locator> p <prio> "               \
19007                                "w <weight> [rloc <loc> ... ] "          \
19008                                "action <action> [del-all]")             \
19009 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
19010                           "<local-eid>")                                \
19011 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
19012 _(one_use_petr, "ip-address> | disable")                                \
19013 _(one_map_request_mode, "src-dst|dst-only")                             \
19014 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
19015 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
19016 _(one_locator_set_dump, "[local | remote]")                             \
19017 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
19018 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
19019                        "[local] | [remote]")                            \
19020 _(one_stats_enable_disable, "enable|disalbe")                           \
19021 _(show_one_stats_enable_disable, "")                                    \
19022 _(one_eid_table_vni_dump, "")                                           \
19023 _(one_eid_table_map_dump, "l2|l3")                                      \
19024 _(one_map_resolver_dump, "")                                            \
19025 _(one_map_server_dump, "")                                              \
19026 _(one_adjacencies_get, "vni <vni>")                                     \
19027 _(show_one_rloc_probe_state, "")                                        \
19028 _(show_one_map_register_state, "")                                      \
19029 _(show_one_status, "")                                                  \
19030 _(one_stats_dump, "")                                                   \
19031 _(one_stats_flush, "")                                                  \
19032 _(one_get_map_request_itr_rlocs, "")                                    \
19033 _(show_one_pitr, "")                                                    \
19034 _(show_one_use_petr, "")                                                \
19035 _(show_one_map_request_mode, "")                                        \
19036 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
19037                             " sw_if_index <sw_if_index> p <priority> "  \
19038                             "w <weight>] [del]")                        \
19039 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
19040                         "iface <intf> | sw_if_index <sw_if_index> "     \
19041                         "p <priority> w <weight> [del]")                \
19042 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
19043                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
19044                          "locator-set <locator_name> [del]"             \
19045                          "[key-id sha1|sha256 secret-key <secret-key>]") \
19046 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
19047 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
19048 _(lisp_enable_disable, "enable|disable")                                \
19049 _(lisp_map_register_enable_disable, "enable|disable")                   \
19050 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
19051 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
19052                                "[seid <seid>] "                         \
19053                                "rloc <locator> p <prio> "               \
19054                                "w <weight> [rloc <loc> ... ] "          \
19055                                "action <action> [del-all]")             \
19056 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
19057                           "<local-eid>")                                \
19058 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
19059 _(lisp_use_petr, "<ip-address> | disable")                              \
19060 _(lisp_map_request_mode, "src-dst|dst-only")                            \
19061 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
19062 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
19063 _(lisp_locator_set_dump, "[local | remote]")                            \
19064 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
19065 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
19066                        "[local] | [remote]")                            \
19067 _(lisp_eid_table_vni_dump, "")                                          \
19068 _(lisp_eid_table_map_dump, "l2|l3")                                     \
19069 _(lisp_map_resolver_dump, "")                                           \
19070 _(lisp_map_server_dump, "")                                             \
19071 _(lisp_adjacencies_get, "vni <vni>")                                    \
19072 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
19073 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
19074 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
19075 _(gpe_get_encap_mode, "")                                               \
19076 _(lisp_gpe_add_del_iface, "up|down")                                    \
19077 _(lisp_gpe_enable_disable, "enable|disable")                            \
19078 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
19079   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
19080 _(show_lisp_rloc_probe_state, "")                                       \
19081 _(show_lisp_map_register_state, "")                                     \
19082 _(show_lisp_status, "")                                                 \
19083 _(lisp_get_map_request_itr_rlocs, "")                                   \
19084 _(show_lisp_pitr, "")                                                   \
19085 _(show_lisp_use_petr, "")                                               \
19086 _(show_lisp_map_request_mode, "")                                       \
19087 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
19088 _(af_packet_delete, "name <host interface name>")                       \
19089 _(policer_add_del, "name <policer name> <params> [del]")                \
19090 _(policer_dump, "[name <policer name>]")                                \
19091 _(policer_classify_set_interface,                                       \
19092   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
19093   "  [l2-table <nn>] [del]")                                            \
19094 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
19095 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
19096     "[master|slave]")                                                   \
19097 _(netmap_delete, "name <interface name>")                               \
19098 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
19099 _(mpls_fib_dump, "")                                                    \
19100 _(classify_table_ids, "")                                               \
19101 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
19102 _(classify_table_info, "table_id <nn>")                                 \
19103 _(classify_session_dump, "table_id <nn>")                               \
19104 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
19105     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
19106     "[template_interval <nn>] [udp_checksum]")                          \
19107 _(ipfix_exporter_dump, "")                                              \
19108 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
19109 _(ipfix_classify_stream_dump, "")                                       \
19110 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
19111 _(ipfix_classify_table_dump, "")                                        \
19112 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
19113 _(sw_interface_span_dump, "")                                           \
19114 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
19115 _(pg_create_interface, "if_id <nn>")                                    \
19116 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
19117 _(pg_enable_disable, "[stream <id>] disable")                           \
19118 _(ip_source_and_port_range_check_add_del,                               \
19119   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
19120 _(ip_source_and_port_range_check_interface_add_del,                     \
19121   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
19122   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
19123 _(ipsec_gre_add_del_tunnel,                                             \
19124   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
19125 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
19126 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
19127 _(l2_interface_pbb_tag_rewrite,                                         \
19128   "<intfc> | sw_if_index <nn> \n"                                       \
19129   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
19130   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
19131 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
19132 _(flow_classify_set_interface,                                          \
19133   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
19134 _(flow_classify_dump, "type [ip4|ip6]")                                 \
19135 _(ip_fib_dump, "")                                                      \
19136 _(ip_mfib_dump, "")                                                     \
19137 _(ip6_fib_dump, "")                                                     \
19138 _(ip6_mfib_dump, "")                                                    \
19139 _(feature_enable_disable, "arc_name <arc_name> "                        \
19140   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
19141 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
19142 "[disable]")                                                            \
19143 _(l2_xconnect_dump, "")                                                 \
19144 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
19145 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
19146 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
19147
19148 /* List of command functions, CLI names map directly to functions */
19149 #define foreach_cli_function                                    \
19150 _(comment, "usage: comment <ignore-rest-of-line>")              \
19151 _(dump_interface_table, "usage: dump_interface_table")          \
19152 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
19153 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
19154 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
19155 _(dump_stats_table, "usage: dump_stats_table")                  \
19156 _(dump_macro_table, "usage: dump_macro_table ")                 \
19157 _(dump_node_table, "usage: dump_node_table")                    \
19158 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
19159 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
19160 _(echo, "usage: echo <message>")                                \
19161 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
19162 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
19163 _(help, "usage: help")                                          \
19164 _(q, "usage: quit")                                             \
19165 _(quit, "usage: quit")                                          \
19166 _(search_node_table, "usage: search_node_table <name>...")      \
19167 _(set, "usage: set <variable-name> <value>")                    \
19168 _(script, "usage: script <file-name>")                          \
19169 _(unset, "usage: unset <variable-name>")
19170
19171 #define _(N,n)                                  \
19172     static void vl_api_##n##_t_handler_uni      \
19173     (vl_api_##n##_t * mp)                       \
19174     {                                           \
19175         vat_main_t * vam = &vat_main;           \
19176         if (vam->json_output) {                 \
19177             vl_api_##n##_t_handler_json(mp);    \
19178         } else {                                \
19179             vl_api_##n##_t_handler(mp);         \
19180         }                                       \
19181     }
19182 foreach_vpe_api_reply_msg;
19183 #if VPP_API_TEST_BUILTIN == 0
19184 foreach_standalone_reply_msg;
19185 #endif
19186 #undef _
19187
19188 void
19189 vat_api_hookup (vat_main_t * vam)
19190 {
19191 #define _(N,n)                                                  \
19192     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
19193                            vl_api_##n##_t_handler_uni,          \
19194                            vl_noop_handler,                     \
19195                            vl_api_##n##_t_endian,               \
19196                            vl_api_##n##_t_print,                \
19197                            sizeof(vl_api_##n##_t), 1);
19198   foreach_vpe_api_reply_msg;
19199 #if VPP_API_TEST_BUILTIN == 0
19200   foreach_standalone_reply_msg;
19201 #endif
19202 #undef _
19203
19204 #if (VPP_API_TEST_BUILTIN==0)
19205   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
19206
19207   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
19208
19209   vam->function_by_name = hash_create_string (0, sizeof (uword));
19210
19211   vam->help_by_name = hash_create_string (0, sizeof (uword));
19212 #endif
19213
19214   /* API messages we can send */
19215 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
19216   foreach_vpe_api_msg;
19217 #undef _
19218
19219   /* Help strings */
19220 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
19221   foreach_vpe_api_msg;
19222 #undef _
19223
19224   /* CLI functions */
19225 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
19226   foreach_cli_function;
19227 #undef _
19228
19229   /* Help strings */
19230 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
19231   foreach_cli_function;
19232 #undef _
19233 }
19234
19235 #if VPP_API_TEST_BUILTIN
19236 static clib_error_t *
19237 vat_api_hookup_shim (vlib_main_t * vm)
19238 {
19239   vat_api_hookup (&vat_main);
19240   return 0;
19241 }
19242
19243 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
19244 #endif
19245
19246 /*
19247  * fd.io coding-style-patch-verification: ON
19248  *
19249  * Local Variables:
19250  * eval: (c-set-style "gnu")
19251  * End:
19252  */