MPLS Mcast
[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 = (u8 *) mp->reply_in_shmem;
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 = (u8 *) (mp->reply_in_shmem);
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 = (u8 *) (mp->reply_in_shmem);
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 = (u8 *) (mp->reply_in_shmem);
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 _(ikev2_profile_add_del_reply)                          \
4203 _(ikev2_profile_set_auth_reply)                         \
4204 _(ikev2_profile_set_id_reply)                           \
4205 _(ikev2_profile_set_ts_reply)                           \
4206 _(ikev2_set_local_key_reply)                            \
4207 _(ikev2_set_responder_reply)                            \
4208 _(ikev2_set_ike_transforms_reply)                       \
4209 _(ikev2_set_esp_transforms_reply)                       \
4210 _(ikev2_set_sa_lifetime_reply)                          \
4211 _(ikev2_initiate_sa_init_reply)                         \
4212 _(ikev2_initiate_del_ike_sa_reply)                      \
4213 _(ikev2_initiate_del_child_sa_reply)                    \
4214 _(ikev2_initiate_rekey_child_sa_reply)                  \
4215 _(delete_loopback_reply)                                \
4216 _(bd_ip_mac_add_del_reply)                              \
4217 _(map_del_domain_reply)                                 \
4218 _(map_add_del_rule_reply)                               \
4219 _(want_interface_events_reply)                          \
4220 _(want_stats_reply)                                     \
4221 _(cop_interface_enable_disable_reply)                   \
4222 _(cop_whitelist_enable_disable_reply)                   \
4223 _(sw_interface_clear_stats_reply)                       \
4224 _(ioam_enable_reply)                              \
4225 _(ioam_disable_reply)                              \
4226 _(one_add_del_locator_reply)                            \
4227 _(one_add_del_local_eid_reply)                          \
4228 _(one_add_del_remote_mapping_reply)                     \
4229 _(one_add_del_adjacency_reply)                          \
4230 _(one_add_del_map_resolver_reply)                       \
4231 _(one_add_del_map_server_reply)                         \
4232 _(one_enable_disable_reply)                             \
4233 _(one_rloc_probe_enable_disable_reply)                  \
4234 _(one_map_register_enable_disable_reply)                \
4235 _(one_pitr_set_locator_set_reply)                       \
4236 _(one_map_request_mode_reply)                           \
4237 _(one_add_del_map_request_itr_rlocs_reply)              \
4238 _(one_eid_table_add_del_map_reply)                      \
4239 _(one_use_petr_reply)                                   \
4240 _(one_stats_enable_disable_reply)                       \
4241 _(gpe_add_del_fwd_entry_reply)                          \
4242 _(gpe_enable_disable_reply)                             \
4243 _(gpe_set_encap_mode_reply)                             \
4244 _(gpe_add_del_iface_reply)                              \
4245 _(vxlan_gpe_add_del_tunnel_reply)                       \
4246 _(af_packet_delete_reply)                               \
4247 _(policer_classify_set_interface_reply)                 \
4248 _(netmap_create_reply)                                  \
4249 _(netmap_delete_reply)                                  \
4250 _(set_ipfix_exporter_reply)                             \
4251 _(set_ipfix_classify_stream_reply)                      \
4252 _(ipfix_classify_table_add_del_reply)                   \
4253 _(flow_classify_set_interface_reply)                    \
4254 _(sw_interface_span_enable_disable_reply)               \
4255 _(pg_capture_reply)                                     \
4256 _(pg_enable_disable_reply)                              \
4257 _(ip_source_and_port_range_check_add_del_reply)         \
4258 _(ip_source_and_port_range_check_interface_add_del_reply)\
4259 _(delete_subif_reply)                                   \
4260 _(l2_interface_pbb_tag_rewrite_reply)                   \
4261 _(punt_reply)                                           \
4262 _(feature_enable_disable_reply)                         \
4263 _(sw_interface_tag_add_del_reply)                       \
4264 _(sw_interface_set_mtu_reply)
4265
4266 #define _(n)                                    \
4267     static void vl_api_##n##_t_handler          \
4268     (vl_api_##n##_t * mp)                       \
4269     {                                           \
4270         vat_main_t * vam = &vat_main;           \
4271         i32 retval = ntohl(mp->retval);         \
4272         if (vam->async_mode) {                  \
4273             vam->async_errors += (retval < 0);  \
4274         } else {                                \
4275             vam->retval = retval;               \
4276             vam->result_ready = 1;              \
4277         }                                       \
4278     }
4279 foreach_standard_reply_retval_handler;
4280 #undef _
4281
4282 #define _(n)                                    \
4283     static void vl_api_##n##_t_handler_json     \
4284     (vl_api_##n##_t * mp)                       \
4285     {                                           \
4286         vat_main_t * vam = &vat_main;           \
4287         vat_json_node_t node;                   \
4288         vat_json_init_object(&node);            \
4289         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
4290         vat_json_print(vam->ofp, &node);        \
4291         vam->retval = ntohl(mp->retval);        \
4292         vam->result_ready = 1;                  \
4293     }
4294 foreach_standard_reply_retval_handler;
4295 #undef _
4296
4297 /*
4298  * Table of message reply handlers, must include boilerplate handlers
4299  * we just generated
4300  */
4301
4302 #define foreach_vpe_api_reply_msg                                       \
4303 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
4304 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
4305 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
4306 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
4307 _(CONTROL_PING_REPLY, control_ping_reply)                               \
4308 _(CLI_REPLY, cli_reply)                                                 \
4309 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
4310 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
4311   sw_interface_add_del_address_reply)                                   \
4312 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
4313 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
4314 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
4315 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
4316 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
4317   sw_interface_set_l2_xconnect_reply)                                   \
4318 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
4319   sw_interface_set_l2_bridge_reply)                                     \
4320 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
4321 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
4322 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
4323 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
4324 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
4325 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
4326 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
4327 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
4328 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
4329 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
4330 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
4331 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
4332 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
4333 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
4334 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
4335 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
4336 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
4337 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
4338 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
4339   proxy_arp_intfc_enable_disable_reply)                                 \
4340 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
4341 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
4342   sw_interface_set_unnumbered_reply)                                    \
4343 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
4344 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
4345 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
4346 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
4347 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
4348 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
4349 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
4350 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
4351 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
4352 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
4353 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
4354 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
4355   sw_interface_ip6_enable_disable_reply)                                \
4356 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
4357   sw_interface_ip6_set_link_local_address_reply)                        \
4358 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
4359 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
4360 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
4361   sw_interface_ip6nd_ra_prefix_reply)                                   \
4362 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
4363   sw_interface_ip6nd_ra_config_reply)                                   \
4364 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
4365 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
4366 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
4367 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
4368 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
4369 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
4370 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
4371 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
4372 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
4373 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
4374 classify_set_interface_ip_table_reply)                                  \
4375 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
4376   classify_set_interface_l2_tables_reply)                               \
4377 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
4378 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
4379 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
4380 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
4381 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
4382   l2tpv3_interface_enable_disable_reply)                                \
4383 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
4384 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
4385 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
4386 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
4387 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
4388 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
4389 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
4390 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
4391 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4392 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
4393 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
4394 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
4395 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
4396 _(SHOW_VERSION_REPLY, show_version_reply)                               \
4397 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
4398 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
4399 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
4400 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
4401 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
4402 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
4403 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
4404 _(IP6_ND_EVENT, ip6_nd_event)                                           \
4405 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
4406 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
4407 _(IP_DETAILS, ip_details)                                               \
4408 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
4409 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4410 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
4411 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
4412 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
4413 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
4414 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
4415 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
4416 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
4417 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
4418 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
4419 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
4420 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
4421 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
4422 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
4423 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
4424 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
4425 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
4426 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
4427 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
4428 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
4429 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
4430 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
4431 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
4432 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
4433 _(MAP_RULE_DETAILS, map_rule_details)                                   \
4434 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
4435 _(WANT_STATS_REPLY, want_stats_reply)                                   \
4436 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
4437 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4438 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4439 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
4440 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
4441 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
4442 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
4443 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
4444 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
4445 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
4446 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
4447 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
4448 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
4449 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
4450 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
4451 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
4452   one_map_register_enable_disable_reply)                                \
4453 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
4454   one_rloc_probe_enable_disable_reply)                                  \
4455 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
4456 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
4457 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
4458 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
4459 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
4460 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
4461 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
4462 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
4463 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
4464 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
4465 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
4466 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
4467 _(ONE_STATS_DETAILS, one_stats_details)                                 \
4468 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
4469 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
4470   show_one_stats_enable_disable_reply)                                  \
4471 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
4472 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
4473 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
4474 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
4475 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
4476 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
4477 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
4478   gpe_fwd_entry_path_details)                                           \
4479 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
4480 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
4481   one_add_del_map_request_itr_rlocs_reply)                              \
4482 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
4483   one_get_map_request_itr_rlocs_reply)                                  \
4484 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
4485 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
4486 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
4487 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
4488 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
4489   show_one_map_register_state_reply)                                    \
4490 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
4491 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
4492 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
4493 _(POLICER_DETAILS, policer_details)                                     \
4494 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4495 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
4496 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
4497 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
4498 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
4499 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
4500 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
4501 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4502 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
4503 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
4504 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
4505 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
4506 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
4507 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
4508 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4509 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
4510 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4511 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
4512 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
4513 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
4514 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
4515 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
4516 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
4517 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
4518 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
4519  ip_source_and_port_range_check_add_del_reply)                          \
4520 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
4521  ip_source_and_port_range_check_interface_add_del_reply)                \
4522 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
4523 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
4524 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
4525 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
4526 _(PUNT_REPLY, punt_reply)                                               \
4527 _(IP_FIB_DETAILS, ip_fib_details)                                       \
4528 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
4529 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
4530 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
4531 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
4532 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
4533 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
4534 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
4535
4536 #define foreach_standalone_reply_msg                                    \
4537 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
4538 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
4539 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
4540 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
4541 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
4542 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
4543
4544 typedef struct
4545 {
4546   u8 *name;
4547   u32 value;
4548 } name_sort_t;
4549
4550
4551 #define STR_VTR_OP_CASE(op)     \
4552     case L2_VTR_ ## op:         \
4553         return "" # op;
4554
4555 static const char *
4556 str_vtr_op (u32 vtr_op)
4557 {
4558   switch (vtr_op)
4559     {
4560       STR_VTR_OP_CASE (DISABLED);
4561       STR_VTR_OP_CASE (PUSH_1);
4562       STR_VTR_OP_CASE (PUSH_2);
4563       STR_VTR_OP_CASE (POP_1);
4564       STR_VTR_OP_CASE (POP_2);
4565       STR_VTR_OP_CASE (TRANSLATE_1_1);
4566       STR_VTR_OP_CASE (TRANSLATE_1_2);
4567       STR_VTR_OP_CASE (TRANSLATE_2_1);
4568       STR_VTR_OP_CASE (TRANSLATE_2_2);
4569     }
4570
4571   return "UNKNOWN";
4572 }
4573
4574 static int
4575 dump_sub_interface_table (vat_main_t * vam)
4576 {
4577   const sw_interface_subif_t *sub = NULL;
4578
4579   if (vam->json_output)
4580     {
4581       clib_warning
4582         ("JSON output supported only for VPE API calls and dump_stats_table");
4583       return -99;
4584     }
4585
4586   print (vam->ofp,
4587          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4588          "Interface", "sw_if_index",
4589          "sub id", "dot1ad", "tags", "outer id",
4590          "inner id", "exact", "default", "outer any", "inner any");
4591
4592   vec_foreach (sub, vam->sw_if_subif_table)
4593   {
4594     print (vam->ofp,
4595            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4596            sub->interface_name,
4597            sub->sw_if_index,
4598            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4599            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4600            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4601            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4602     if (sub->vtr_op != L2_VTR_DISABLED)
4603       {
4604         print (vam->ofp,
4605                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4606                "tag1: %d tag2: %d ]",
4607                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4608                sub->vtr_tag1, sub->vtr_tag2);
4609       }
4610   }
4611
4612   return 0;
4613 }
4614
4615 static int
4616 name_sort_cmp (void *a1, void *a2)
4617 {
4618   name_sort_t *n1 = a1;
4619   name_sort_t *n2 = a2;
4620
4621   return strcmp ((char *) n1->name, (char *) n2->name);
4622 }
4623
4624 static int
4625 dump_interface_table (vat_main_t * vam)
4626 {
4627   hash_pair_t *p;
4628   name_sort_t *nses = 0, *ns;
4629
4630   if (vam->json_output)
4631     {
4632       clib_warning
4633         ("JSON output supported only for VPE API calls and dump_stats_table");
4634       return -99;
4635     }
4636
4637   /* *INDENT-OFF* */
4638   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4639   ({
4640     vec_add2 (nses, ns, 1);
4641     ns->name = (u8 *)(p->key);
4642     ns->value = (u32) p->value[0];
4643   }));
4644   /* *INDENT-ON* */
4645
4646   vec_sort_with_function (nses, name_sort_cmp);
4647
4648   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4649   vec_foreach (ns, nses)
4650   {
4651     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4652   }
4653   vec_free (nses);
4654   return 0;
4655 }
4656
4657 static int
4658 dump_ip_table (vat_main_t * vam, int is_ipv6)
4659 {
4660   const ip_details_t *det = NULL;
4661   const ip_address_details_t *address = NULL;
4662   u32 i = ~0;
4663
4664   print (vam->ofp, "%-12s", "sw_if_index");
4665
4666   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4667   {
4668     i++;
4669     if (!det->present)
4670       {
4671         continue;
4672       }
4673     print (vam->ofp, "%-12d", i);
4674     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
4675     if (!det->addr)
4676       {
4677         continue;
4678       }
4679     vec_foreach (address, det->addr)
4680     {
4681       print (vam->ofp,
4682              "            %-30U%-13d",
4683              is_ipv6 ? format_ip6_address : format_ip4_address,
4684              address->ip, address->prefix_length);
4685     }
4686   }
4687
4688   return 0;
4689 }
4690
4691 static int
4692 dump_ipv4_table (vat_main_t * vam)
4693 {
4694   if (vam->json_output)
4695     {
4696       clib_warning
4697         ("JSON output supported only for VPE API calls and dump_stats_table");
4698       return -99;
4699     }
4700
4701   return dump_ip_table (vam, 0);
4702 }
4703
4704 static int
4705 dump_ipv6_table (vat_main_t * vam)
4706 {
4707   if (vam->json_output)
4708     {
4709       clib_warning
4710         ("JSON output supported only for VPE API calls and dump_stats_table");
4711       return -99;
4712     }
4713
4714   return dump_ip_table (vam, 1);
4715 }
4716
4717 static char *
4718 counter_type_to_str (u8 counter_type, u8 is_combined)
4719 {
4720   if (!is_combined)
4721     {
4722       switch (counter_type)
4723         {
4724         case VNET_INTERFACE_COUNTER_DROP:
4725           return "drop";
4726         case VNET_INTERFACE_COUNTER_PUNT:
4727           return "punt";
4728         case VNET_INTERFACE_COUNTER_IP4:
4729           return "ip4";
4730         case VNET_INTERFACE_COUNTER_IP6:
4731           return "ip6";
4732         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4733           return "rx-no-buf";
4734         case VNET_INTERFACE_COUNTER_RX_MISS:
4735           return "rx-miss";
4736         case VNET_INTERFACE_COUNTER_RX_ERROR:
4737           return "rx-error";
4738         case VNET_INTERFACE_COUNTER_TX_ERROR:
4739           return "tx-error";
4740         default:
4741           return "INVALID-COUNTER-TYPE";
4742         }
4743     }
4744   else
4745     {
4746       switch (counter_type)
4747         {
4748         case VNET_INTERFACE_COUNTER_RX:
4749           return "rx";
4750         case VNET_INTERFACE_COUNTER_TX:
4751           return "tx";
4752         default:
4753           return "INVALID-COUNTER-TYPE";
4754         }
4755     }
4756 }
4757
4758 static int
4759 dump_stats_table (vat_main_t * vam)
4760 {
4761   vat_json_node_t node;
4762   vat_json_node_t *msg_array;
4763   vat_json_node_t *msg;
4764   vat_json_node_t *counter_array;
4765   vat_json_node_t *counter;
4766   interface_counter_t c;
4767   u64 packets;
4768   ip4_fib_counter_t *c4;
4769   ip6_fib_counter_t *c6;
4770   ip4_nbr_counter_t *n4;
4771   ip6_nbr_counter_t *n6;
4772   int i, j;
4773
4774   if (!vam->json_output)
4775     {
4776       clib_warning ("dump_stats_table supported only in JSON format");
4777       return -99;
4778     }
4779
4780   vat_json_init_object (&node);
4781
4782   /* interface counters */
4783   msg_array = vat_json_object_add (&node, "interface_counters");
4784   vat_json_init_array (msg_array);
4785   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4786     {
4787       msg = vat_json_array_add (msg_array);
4788       vat_json_init_object (msg);
4789       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4790                                        (u8 *) counter_type_to_str (i, 0));
4791       vat_json_object_add_int (msg, "is_combined", 0);
4792       counter_array = vat_json_object_add (msg, "data");
4793       vat_json_init_array (counter_array);
4794       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4795         {
4796           packets = vam->simple_interface_counters[i][j];
4797           vat_json_array_add_uint (counter_array, packets);
4798         }
4799     }
4800   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4801     {
4802       msg = vat_json_array_add (msg_array);
4803       vat_json_init_object (msg);
4804       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4805                                        (u8 *) counter_type_to_str (i, 1));
4806       vat_json_object_add_int (msg, "is_combined", 1);
4807       counter_array = vat_json_object_add (msg, "data");
4808       vat_json_init_array (counter_array);
4809       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4810         {
4811           c = vam->combined_interface_counters[i][j];
4812           counter = vat_json_array_add (counter_array);
4813           vat_json_init_object (counter);
4814           vat_json_object_add_uint (counter, "packets", c.packets);
4815           vat_json_object_add_uint (counter, "bytes", c.bytes);
4816         }
4817     }
4818
4819   /* ip4 fib counters */
4820   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4821   vat_json_init_array (msg_array);
4822   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4823     {
4824       msg = vat_json_array_add (msg_array);
4825       vat_json_init_object (msg);
4826       vat_json_object_add_uint (msg, "vrf_id",
4827                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4828       counter_array = vat_json_object_add (msg, "c");
4829       vat_json_init_array (counter_array);
4830       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4831         {
4832           counter = vat_json_array_add (counter_array);
4833           vat_json_init_object (counter);
4834           c4 = &vam->ip4_fib_counters[i][j];
4835           vat_json_object_add_ip4 (counter, "address", c4->address);
4836           vat_json_object_add_uint (counter, "address_length",
4837                                     c4->address_length);
4838           vat_json_object_add_uint (counter, "packets", c4->packets);
4839           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4840         }
4841     }
4842
4843   /* ip6 fib counters */
4844   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4845   vat_json_init_array (msg_array);
4846   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4847     {
4848       msg = vat_json_array_add (msg_array);
4849       vat_json_init_object (msg);
4850       vat_json_object_add_uint (msg, "vrf_id",
4851                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4852       counter_array = vat_json_object_add (msg, "c");
4853       vat_json_init_array (counter_array);
4854       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4855         {
4856           counter = vat_json_array_add (counter_array);
4857           vat_json_init_object (counter);
4858           c6 = &vam->ip6_fib_counters[i][j];
4859           vat_json_object_add_ip6 (counter, "address", c6->address);
4860           vat_json_object_add_uint (counter, "address_length",
4861                                     c6->address_length);
4862           vat_json_object_add_uint (counter, "packets", c6->packets);
4863           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4864         }
4865     }
4866
4867   /* ip4 nbr counters */
4868   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
4869   vat_json_init_array (msg_array);
4870   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
4871     {
4872       msg = vat_json_array_add (msg_array);
4873       vat_json_init_object (msg);
4874       vat_json_object_add_uint (msg, "sw_if_index", i);
4875       counter_array = vat_json_object_add (msg, "c");
4876       vat_json_init_array (counter_array);
4877       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
4878         {
4879           counter = vat_json_array_add (counter_array);
4880           vat_json_init_object (counter);
4881           n4 = &vam->ip4_nbr_counters[i][j];
4882           vat_json_object_add_ip4 (counter, "address", n4->address);
4883           vat_json_object_add_uint (counter, "link-type", n4->linkt);
4884           vat_json_object_add_uint (counter, "packets", n4->packets);
4885           vat_json_object_add_uint (counter, "bytes", n4->bytes);
4886         }
4887     }
4888
4889   /* ip6 nbr counters */
4890   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
4891   vat_json_init_array (msg_array);
4892   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
4893     {
4894       msg = vat_json_array_add (msg_array);
4895       vat_json_init_object (msg);
4896       vat_json_object_add_uint (msg, "sw_if_index", i);
4897       counter_array = vat_json_object_add (msg, "c");
4898       vat_json_init_array (counter_array);
4899       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
4900         {
4901           counter = vat_json_array_add (counter_array);
4902           vat_json_init_object (counter);
4903           n6 = &vam->ip6_nbr_counters[i][j];
4904           vat_json_object_add_ip6 (counter, "address", n6->address);
4905           vat_json_object_add_uint (counter, "packets", n6->packets);
4906           vat_json_object_add_uint (counter, "bytes", n6->bytes);
4907         }
4908     }
4909
4910   vat_json_print (vam->ofp, &node);
4911   vat_json_free (&node);
4912
4913   return 0;
4914 }
4915
4916 int
4917 exec (vat_main_t * vam)
4918 {
4919   api_main_t *am = &api_main;
4920   vl_api_cli_request_t *mp;
4921   f64 timeout;
4922   void *oldheap;
4923   u8 *cmd = 0;
4924   unformat_input_t *i = vam->input;
4925
4926   if (vec_len (i->buffer) == 0)
4927     return -1;
4928
4929   if (vam->exec_mode == 0 && unformat (i, "mode"))
4930     {
4931       vam->exec_mode = 1;
4932       return 0;
4933     }
4934   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4935     {
4936       vam->exec_mode = 0;
4937       return 0;
4938     }
4939
4940
4941   M (CLI_REQUEST, mp);
4942
4943   /*
4944    * Copy cmd into shared memory.
4945    * In order for the CLI command to work, it
4946    * must be a vector ending in \n, not a C-string ending
4947    * in \n\0.
4948    */
4949   pthread_mutex_lock (&am->vlib_rp->mutex);
4950   oldheap = svm_push_data_heap (am->vlib_rp);
4951
4952   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4953   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4954
4955   svm_pop_heap (oldheap);
4956   pthread_mutex_unlock (&am->vlib_rp->mutex);
4957
4958   mp->cmd_in_shmem = (u64) cmd;
4959   S (mp);
4960   timeout = vat_time_now (vam) + 10.0;
4961
4962   while (vat_time_now (vam) < timeout)
4963     {
4964       if (vam->result_ready == 1)
4965         {
4966           u8 *free_me;
4967           if (vam->shmem_result != NULL)
4968             print (vam->ofp, "%s", vam->shmem_result);
4969           pthread_mutex_lock (&am->vlib_rp->mutex);
4970           oldheap = svm_push_data_heap (am->vlib_rp);
4971
4972           free_me = (u8 *) vam->shmem_result;
4973           vec_free (free_me);
4974
4975           svm_pop_heap (oldheap);
4976           pthread_mutex_unlock (&am->vlib_rp->mutex);
4977           return 0;
4978         }
4979     }
4980   return -99;
4981 }
4982
4983 /*
4984  * Future replacement of exec() that passes CLI buffers directly in
4985  * the API messages instead of an additional shared memory area.
4986  */
4987 static int
4988 exec_inband (vat_main_t * vam)
4989 {
4990   vl_api_cli_inband_t *mp;
4991   unformat_input_t *i = vam->input;
4992   int ret;
4993
4994   if (vec_len (i->buffer) == 0)
4995     return -1;
4996
4997   if (vam->exec_mode == 0 && unformat (i, "mode"))
4998     {
4999       vam->exec_mode = 1;
5000       return 0;
5001     }
5002   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5003     {
5004       vam->exec_mode = 0;
5005       return 0;
5006     }
5007
5008   /*
5009    * In order for the CLI command to work, it
5010    * must be a vector ending in \n, not a C-string ending
5011    * in \n\0.
5012    */
5013   u32 len = vec_len (vam->input->buffer);
5014   M2 (CLI_INBAND, mp, len);
5015   clib_memcpy (mp->cmd, vam->input->buffer, len);
5016   mp->length = htonl (len);
5017
5018   S (mp);
5019   W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
5020   return ret;
5021 }
5022
5023 static int
5024 api_create_loopback (vat_main_t * vam)
5025 {
5026   unformat_input_t *i = vam->input;
5027   vl_api_create_loopback_t *mp;
5028   vl_api_create_loopback_instance_t *mp_lbi;
5029   u8 mac_address[6];
5030   u8 mac_set = 0;
5031   u8 is_specified = 0;
5032   u32 user_instance = 0;
5033   int ret;
5034
5035   memset (mac_address, 0, sizeof (mac_address));
5036
5037   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5038     {
5039       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5040         mac_set = 1;
5041       if (unformat (i, "instance %d", &user_instance))
5042         is_specified = 1;
5043       else
5044         break;
5045     }
5046
5047   if (is_specified)
5048     {
5049       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5050       mp_lbi->is_specified = is_specified;
5051       if (is_specified)
5052         mp_lbi->user_instance = htonl (user_instance);
5053       if (mac_set)
5054         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5055       S (mp_lbi);
5056     }
5057   else
5058     {
5059       /* Construct the API message */
5060       M (CREATE_LOOPBACK, mp);
5061       if (mac_set)
5062         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5063       S (mp);
5064     }
5065
5066   W (ret);
5067   return ret;
5068 }
5069
5070 static int
5071 api_delete_loopback (vat_main_t * vam)
5072 {
5073   unformat_input_t *i = vam->input;
5074   vl_api_delete_loopback_t *mp;
5075   u32 sw_if_index = ~0;
5076   int ret;
5077
5078   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5079     {
5080       if (unformat (i, "sw_if_index %d", &sw_if_index))
5081         ;
5082       else
5083         break;
5084     }
5085
5086   if (sw_if_index == ~0)
5087     {
5088       errmsg ("missing sw_if_index");
5089       return -99;
5090     }
5091
5092   /* Construct the API message */
5093   M (DELETE_LOOPBACK, mp);
5094   mp->sw_if_index = ntohl (sw_if_index);
5095
5096   S (mp);
5097   W (ret);
5098   return ret;
5099 }
5100
5101 static int
5102 api_want_stats (vat_main_t * vam)
5103 {
5104   unformat_input_t *i = vam->input;
5105   vl_api_want_stats_t *mp;
5106   int enable = -1;
5107   int ret;
5108
5109   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5110     {
5111       if (unformat (i, "enable"))
5112         enable = 1;
5113       else if (unformat (i, "disable"))
5114         enable = 0;
5115       else
5116         break;
5117     }
5118
5119   if (enable == -1)
5120     {
5121       errmsg ("missing enable|disable");
5122       return -99;
5123     }
5124
5125   M (WANT_STATS, mp);
5126   mp->enable_disable = enable;
5127
5128   S (mp);
5129   W (ret);
5130   return ret;
5131 }
5132
5133 static int
5134 api_want_interface_events (vat_main_t * vam)
5135 {
5136   unformat_input_t *i = vam->input;
5137   vl_api_want_interface_events_t *mp;
5138   int enable = -1;
5139   int ret;
5140
5141   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5142     {
5143       if (unformat (i, "enable"))
5144         enable = 1;
5145       else if (unformat (i, "disable"))
5146         enable = 0;
5147       else
5148         break;
5149     }
5150
5151   if (enable == -1)
5152     {
5153       errmsg ("missing enable|disable");
5154       return -99;
5155     }
5156
5157   M (WANT_INTERFACE_EVENTS, mp);
5158   mp->enable_disable = enable;
5159
5160   vam->interface_event_display = enable;
5161
5162   S (mp);
5163   W (ret);
5164   return ret;
5165 }
5166
5167
5168 /* Note: non-static, called once to set up the initial intfc table */
5169 int
5170 api_sw_interface_dump (vat_main_t * vam)
5171 {
5172   vl_api_sw_interface_dump_t *mp;
5173   vl_api_control_ping_t *mp_ping;
5174   hash_pair_t *p;
5175   name_sort_t *nses = 0, *ns;
5176   sw_interface_subif_t *sub = NULL;
5177   int ret;
5178
5179   /* Toss the old name table */
5180   /* *INDENT-OFF* */
5181   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5182   ({
5183     vec_add2 (nses, ns, 1);
5184     ns->name = (u8 *)(p->key);
5185     ns->value = (u32) p->value[0];
5186   }));
5187   /* *INDENT-ON* */
5188
5189   hash_free (vam->sw_if_index_by_interface_name);
5190
5191   vec_foreach (ns, nses) vec_free (ns->name);
5192
5193   vec_free (nses);
5194
5195   vec_foreach (sub, vam->sw_if_subif_table)
5196   {
5197     vec_free (sub->interface_name);
5198   }
5199   vec_free (vam->sw_if_subif_table);
5200
5201   /* recreate the interface name hash table */
5202   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5203
5204   /* Get list of ethernets */
5205   M (SW_INTERFACE_DUMP, mp);
5206   mp->name_filter_valid = 1;
5207   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
5208   S (mp);
5209
5210   /* and local / loopback interfaces */
5211   M (SW_INTERFACE_DUMP, mp);
5212   mp->name_filter_valid = 1;
5213   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
5214   S (mp);
5215
5216   /* and packet-generator interfaces */
5217   M (SW_INTERFACE_DUMP, mp);
5218   mp->name_filter_valid = 1;
5219   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
5220   S (mp);
5221
5222   /* and vxlan-gpe tunnel interfaces */
5223   M (SW_INTERFACE_DUMP, mp);
5224   mp->name_filter_valid = 1;
5225   strncpy ((char *) mp->name_filter, "vxlan_gpe",
5226            sizeof (mp->name_filter) - 1);
5227   S (mp);
5228
5229   /* and vxlan tunnel interfaces */
5230   M (SW_INTERFACE_DUMP, mp);
5231   mp->name_filter_valid = 1;
5232   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
5233   S (mp);
5234
5235   /* and host (af_packet) interfaces */
5236   M (SW_INTERFACE_DUMP, mp);
5237   mp->name_filter_valid = 1;
5238   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
5239   S (mp);
5240
5241   /* and l2tpv3 tunnel interfaces */
5242   M (SW_INTERFACE_DUMP, mp);
5243   mp->name_filter_valid = 1;
5244   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
5245            sizeof (mp->name_filter) - 1);
5246   S (mp);
5247
5248   /* and GRE tunnel interfaces */
5249   M (SW_INTERFACE_DUMP, mp);
5250   mp->name_filter_valid = 1;
5251   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
5252   S (mp);
5253
5254   /* and LISP-GPE interfaces */
5255   M (SW_INTERFACE_DUMP, mp);
5256   mp->name_filter_valid = 1;
5257   strncpy ((char *) mp->name_filter, "lisp_gpe",
5258            sizeof (mp->name_filter) - 1);
5259   S (mp);
5260
5261   /* and IPSEC tunnel interfaces */
5262   M (SW_INTERFACE_DUMP, mp);
5263   mp->name_filter_valid = 1;
5264   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
5265   S (mp);
5266
5267   /* Use a control ping for synchronization */
5268   M (CONTROL_PING, mp_ping);
5269   S (mp_ping);
5270
5271   W (ret);
5272   return ret;
5273 }
5274
5275 static int
5276 api_sw_interface_set_flags (vat_main_t * vam)
5277 {
5278   unformat_input_t *i = vam->input;
5279   vl_api_sw_interface_set_flags_t *mp;
5280   u32 sw_if_index;
5281   u8 sw_if_index_set = 0;
5282   u8 admin_up = 0, link_up = 0;
5283   int ret;
5284
5285   /* Parse args required to build the message */
5286   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5287     {
5288       if (unformat (i, "admin-up"))
5289         admin_up = 1;
5290       else if (unformat (i, "admin-down"))
5291         admin_up = 0;
5292       else if (unformat (i, "link-up"))
5293         link_up = 1;
5294       else if (unformat (i, "link-down"))
5295         link_up = 0;
5296       else
5297         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5298         sw_if_index_set = 1;
5299       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5300         sw_if_index_set = 1;
5301       else
5302         break;
5303     }
5304
5305   if (sw_if_index_set == 0)
5306     {
5307       errmsg ("missing interface name or sw_if_index");
5308       return -99;
5309     }
5310
5311   /* Construct the API message */
5312   M (SW_INTERFACE_SET_FLAGS, mp);
5313   mp->sw_if_index = ntohl (sw_if_index);
5314   mp->admin_up_down = admin_up;
5315   mp->link_up_down = link_up;
5316
5317   /* send it... */
5318   S (mp);
5319
5320   /* Wait for a reply, return the good/bad news... */
5321   W (ret);
5322   return ret;
5323 }
5324
5325 static int
5326 api_sw_interface_clear_stats (vat_main_t * vam)
5327 {
5328   unformat_input_t *i = vam->input;
5329   vl_api_sw_interface_clear_stats_t *mp;
5330   u32 sw_if_index;
5331   u8 sw_if_index_set = 0;
5332   int ret;
5333
5334   /* Parse args required to build the message */
5335   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5336     {
5337       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5338         sw_if_index_set = 1;
5339       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5340         sw_if_index_set = 1;
5341       else
5342         break;
5343     }
5344
5345   /* Construct the API message */
5346   M (SW_INTERFACE_CLEAR_STATS, mp);
5347
5348   if (sw_if_index_set == 1)
5349     mp->sw_if_index = ntohl (sw_if_index);
5350   else
5351     mp->sw_if_index = ~0;
5352
5353   /* send it... */
5354   S (mp);
5355
5356   /* Wait for a reply, return the good/bad news... */
5357   W (ret);
5358   return ret;
5359 }
5360
5361 static int
5362 api_sw_interface_add_del_address (vat_main_t * vam)
5363 {
5364   unformat_input_t *i = vam->input;
5365   vl_api_sw_interface_add_del_address_t *mp;
5366   u32 sw_if_index;
5367   u8 sw_if_index_set = 0;
5368   u8 is_add = 1, del_all = 0;
5369   u32 address_length = 0;
5370   u8 v4_address_set = 0;
5371   u8 v6_address_set = 0;
5372   ip4_address_t v4address;
5373   ip6_address_t v6address;
5374   int ret;
5375
5376   /* Parse args required to build the message */
5377   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5378     {
5379       if (unformat (i, "del-all"))
5380         del_all = 1;
5381       else if (unformat (i, "del"))
5382         is_add = 0;
5383       else
5384         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5385         sw_if_index_set = 1;
5386       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5387         sw_if_index_set = 1;
5388       else if (unformat (i, "%U/%d",
5389                          unformat_ip4_address, &v4address, &address_length))
5390         v4_address_set = 1;
5391       else if (unformat (i, "%U/%d",
5392                          unformat_ip6_address, &v6address, &address_length))
5393         v6_address_set = 1;
5394       else
5395         break;
5396     }
5397
5398   if (sw_if_index_set == 0)
5399     {
5400       errmsg ("missing interface name or sw_if_index");
5401       return -99;
5402     }
5403   if (v4_address_set && v6_address_set)
5404     {
5405       errmsg ("both v4 and v6 addresses set");
5406       return -99;
5407     }
5408   if (!v4_address_set && !v6_address_set && !del_all)
5409     {
5410       errmsg ("no addresses set");
5411       return -99;
5412     }
5413
5414   /* Construct the API message */
5415   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
5416
5417   mp->sw_if_index = ntohl (sw_if_index);
5418   mp->is_add = is_add;
5419   mp->del_all = del_all;
5420   if (v6_address_set)
5421     {
5422       mp->is_ipv6 = 1;
5423       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5424     }
5425   else
5426     {
5427       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5428     }
5429   mp->address_length = address_length;
5430
5431   /* send it... */
5432   S (mp);
5433
5434   /* Wait for a reply, return good/bad news  */
5435   W (ret);
5436   return ret;
5437 }
5438
5439 static int
5440 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5441 {
5442   unformat_input_t *i = vam->input;
5443   vl_api_sw_interface_set_mpls_enable_t *mp;
5444   u32 sw_if_index;
5445   u8 sw_if_index_set = 0;
5446   u8 enable = 1;
5447   int ret;
5448
5449   /* Parse args required to build the message */
5450   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5451     {
5452       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5453         sw_if_index_set = 1;
5454       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5455         sw_if_index_set = 1;
5456       else if (unformat (i, "disable"))
5457         enable = 0;
5458       else if (unformat (i, "dis"))
5459         enable = 0;
5460       else
5461         break;
5462     }
5463
5464   if (sw_if_index_set == 0)
5465     {
5466       errmsg ("missing interface name or sw_if_index");
5467       return -99;
5468     }
5469
5470   /* Construct the API message */
5471   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
5472
5473   mp->sw_if_index = ntohl (sw_if_index);
5474   mp->enable = enable;
5475
5476   /* send it... */
5477   S (mp);
5478
5479   /* Wait for a reply... */
5480   W (ret);
5481   return ret;
5482 }
5483
5484 static int
5485 api_sw_interface_set_table (vat_main_t * vam)
5486 {
5487   unformat_input_t *i = vam->input;
5488   vl_api_sw_interface_set_table_t *mp;
5489   u32 sw_if_index, vrf_id = 0;
5490   u8 sw_if_index_set = 0;
5491   u8 is_ipv6 = 0;
5492   int ret;
5493
5494   /* Parse args required to build the message */
5495   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5496     {
5497       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5498         sw_if_index_set = 1;
5499       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5500         sw_if_index_set = 1;
5501       else if (unformat (i, "vrf %d", &vrf_id))
5502         ;
5503       else if (unformat (i, "ipv6"))
5504         is_ipv6 = 1;
5505       else
5506         break;
5507     }
5508
5509   if (sw_if_index_set == 0)
5510     {
5511       errmsg ("missing interface name or sw_if_index");
5512       return -99;
5513     }
5514
5515   /* Construct the API message */
5516   M (SW_INTERFACE_SET_TABLE, mp);
5517
5518   mp->sw_if_index = ntohl (sw_if_index);
5519   mp->is_ipv6 = is_ipv6;
5520   mp->vrf_id = ntohl (vrf_id);
5521
5522   /* send it... */
5523   S (mp);
5524
5525   /* Wait for a reply... */
5526   W (ret);
5527   return ret;
5528 }
5529
5530 static void vl_api_sw_interface_get_table_reply_t_handler
5531   (vl_api_sw_interface_get_table_reply_t * mp)
5532 {
5533   vat_main_t *vam = &vat_main;
5534
5535   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5536
5537   vam->retval = ntohl (mp->retval);
5538   vam->result_ready = 1;
5539
5540 }
5541
5542 static void vl_api_sw_interface_get_table_reply_t_handler_json
5543   (vl_api_sw_interface_get_table_reply_t * mp)
5544 {
5545   vat_main_t *vam = &vat_main;
5546   vat_json_node_t node;
5547
5548   vat_json_init_object (&node);
5549   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5550   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5551
5552   vat_json_print (vam->ofp, &node);
5553   vat_json_free (&node);
5554
5555   vam->retval = ntohl (mp->retval);
5556   vam->result_ready = 1;
5557 }
5558
5559 static int
5560 api_sw_interface_get_table (vat_main_t * vam)
5561 {
5562   unformat_input_t *i = vam->input;
5563   vl_api_sw_interface_get_table_t *mp;
5564   u32 sw_if_index;
5565   u8 sw_if_index_set = 0;
5566   u8 is_ipv6 = 0;
5567   int ret;
5568
5569   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5570     {
5571       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5572         sw_if_index_set = 1;
5573       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5574         sw_if_index_set = 1;
5575       else if (unformat (i, "ipv6"))
5576         is_ipv6 = 1;
5577       else
5578         break;
5579     }
5580
5581   if (sw_if_index_set == 0)
5582     {
5583       errmsg ("missing interface name or sw_if_index");
5584       return -99;
5585     }
5586
5587   M (SW_INTERFACE_GET_TABLE, mp);
5588   mp->sw_if_index = htonl (sw_if_index);
5589   mp->is_ipv6 = is_ipv6;
5590
5591   S (mp);
5592   W (ret);
5593   return ret;
5594 }
5595
5596 static int
5597 api_sw_interface_set_vpath (vat_main_t * vam)
5598 {
5599   unformat_input_t *i = vam->input;
5600   vl_api_sw_interface_set_vpath_t *mp;
5601   u32 sw_if_index = 0;
5602   u8 sw_if_index_set = 0;
5603   u8 is_enable = 0;
5604   int ret;
5605
5606   /* Parse args required to build the message */
5607   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5608     {
5609       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5610         sw_if_index_set = 1;
5611       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5612         sw_if_index_set = 1;
5613       else if (unformat (i, "enable"))
5614         is_enable = 1;
5615       else if (unformat (i, "disable"))
5616         is_enable = 0;
5617       else
5618         break;
5619     }
5620
5621   if (sw_if_index_set == 0)
5622     {
5623       errmsg ("missing interface name or sw_if_index");
5624       return -99;
5625     }
5626
5627   /* Construct the API message */
5628   M (SW_INTERFACE_SET_VPATH, mp);
5629
5630   mp->sw_if_index = ntohl (sw_if_index);
5631   mp->enable = is_enable;
5632
5633   /* send it... */
5634   S (mp);
5635
5636   /* Wait for a reply... */
5637   W (ret);
5638   return ret;
5639 }
5640
5641 static int
5642 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5643 {
5644   unformat_input_t *i = vam->input;
5645   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5646   u32 sw_if_index = 0;
5647   u8 sw_if_index_set = 0;
5648   u8 is_enable = 1;
5649   u8 is_ipv6 = 0;
5650   int ret;
5651
5652   /* Parse args required to build the message */
5653   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5654     {
5655       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5656         sw_if_index_set = 1;
5657       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5658         sw_if_index_set = 1;
5659       else if (unformat (i, "enable"))
5660         is_enable = 1;
5661       else if (unformat (i, "disable"))
5662         is_enable = 0;
5663       else if (unformat (i, "ip4"))
5664         is_ipv6 = 0;
5665       else if (unformat (i, "ip6"))
5666         is_ipv6 = 1;
5667       else
5668         break;
5669     }
5670
5671   if (sw_if_index_set == 0)
5672     {
5673       errmsg ("missing interface name or sw_if_index");
5674       return -99;
5675     }
5676
5677   /* Construct the API message */
5678   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
5679
5680   mp->sw_if_index = ntohl (sw_if_index);
5681   mp->enable = is_enable;
5682   mp->is_ipv6 = is_ipv6;
5683
5684   /* send it... */
5685   S (mp);
5686
5687   /* Wait for a reply... */
5688   W (ret);
5689   return ret;
5690 }
5691
5692 static int
5693 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5694 {
5695   unformat_input_t *i = vam->input;
5696   vl_api_sw_interface_set_l2_xconnect_t *mp;
5697   u32 rx_sw_if_index;
5698   u8 rx_sw_if_index_set = 0;
5699   u32 tx_sw_if_index;
5700   u8 tx_sw_if_index_set = 0;
5701   u8 enable = 1;
5702   int ret;
5703
5704   /* Parse args required to build the message */
5705   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5706     {
5707       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5708         rx_sw_if_index_set = 1;
5709       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5710         tx_sw_if_index_set = 1;
5711       else if (unformat (i, "rx"))
5712         {
5713           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5714             {
5715               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5716                             &rx_sw_if_index))
5717                 rx_sw_if_index_set = 1;
5718             }
5719           else
5720             break;
5721         }
5722       else if (unformat (i, "tx"))
5723         {
5724           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5725             {
5726               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5727                             &tx_sw_if_index))
5728                 tx_sw_if_index_set = 1;
5729             }
5730           else
5731             break;
5732         }
5733       else if (unformat (i, "enable"))
5734         enable = 1;
5735       else if (unformat (i, "disable"))
5736         enable = 0;
5737       else
5738         break;
5739     }
5740
5741   if (rx_sw_if_index_set == 0)
5742     {
5743       errmsg ("missing rx interface name or rx_sw_if_index");
5744       return -99;
5745     }
5746
5747   if (enable && (tx_sw_if_index_set == 0))
5748     {
5749       errmsg ("missing tx interface name or tx_sw_if_index");
5750       return -99;
5751     }
5752
5753   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
5754
5755   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5756   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5757   mp->enable = enable;
5758
5759   S (mp);
5760   W (ret);
5761   return ret;
5762 }
5763
5764 static int
5765 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5766 {
5767   unformat_input_t *i = vam->input;
5768   vl_api_sw_interface_set_l2_bridge_t *mp;
5769   u32 rx_sw_if_index;
5770   u8 rx_sw_if_index_set = 0;
5771   u32 bd_id;
5772   u8 bd_id_set = 0;
5773   u8 bvi = 0;
5774   u32 shg = 0;
5775   u8 enable = 1;
5776   int ret;
5777
5778   /* Parse args required to build the message */
5779   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5780     {
5781       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5782         rx_sw_if_index_set = 1;
5783       else if (unformat (i, "bd_id %d", &bd_id))
5784         bd_id_set = 1;
5785       else
5786         if (unformat
5787             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5788         rx_sw_if_index_set = 1;
5789       else if (unformat (i, "shg %d", &shg))
5790         ;
5791       else if (unformat (i, "bvi"))
5792         bvi = 1;
5793       else if (unformat (i, "enable"))
5794         enable = 1;
5795       else if (unformat (i, "disable"))
5796         enable = 0;
5797       else
5798         break;
5799     }
5800
5801   if (rx_sw_if_index_set == 0)
5802     {
5803       errmsg ("missing rx interface name or sw_if_index");
5804       return -99;
5805     }
5806
5807   if (enable && (bd_id_set == 0))
5808     {
5809       errmsg ("missing bridge domain");
5810       return -99;
5811     }
5812
5813   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
5814
5815   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5816   mp->bd_id = ntohl (bd_id);
5817   mp->shg = (u8) shg;
5818   mp->bvi = bvi;
5819   mp->enable = enable;
5820
5821   S (mp);
5822   W (ret);
5823   return ret;
5824 }
5825
5826 static int
5827 api_bridge_domain_dump (vat_main_t * vam)
5828 {
5829   unformat_input_t *i = vam->input;
5830   vl_api_bridge_domain_dump_t *mp;
5831   vl_api_control_ping_t *mp_ping;
5832   u32 bd_id = ~0;
5833   int ret;
5834
5835   /* Parse args required to build the message */
5836   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5837     {
5838       if (unformat (i, "bd_id %d", &bd_id))
5839         ;
5840       else
5841         break;
5842     }
5843
5844   M (BRIDGE_DOMAIN_DUMP, mp);
5845   mp->bd_id = ntohl (bd_id);
5846   S (mp);
5847
5848   /* Use a control ping for synchronization */
5849   M (CONTROL_PING, mp_ping);
5850   S (mp_ping);
5851
5852   W (ret);
5853   return ret;
5854 }
5855
5856 static int
5857 api_bridge_domain_add_del (vat_main_t * vam)
5858 {
5859   unformat_input_t *i = vam->input;
5860   vl_api_bridge_domain_add_del_t *mp;
5861   u32 bd_id = ~0;
5862   u8 is_add = 1;
5863   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5864   u32 mac_age = 0;
5865   int ret;
5866
5867   /* Parse args required to build the message */
5868   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5869     {
5870       if (unformat (i, "bd_id %d", &bd_id))
5871         ;
5872       else if (unformat (i, "flood %d", &flood))
5873         ;
5874       else if (unformat (i, "uu-flood %d", &uu_flood))
5875         ;
5876       else if (unformat (i, "forward %d", &forward))
5877         ;
5878       else if (unformat (i, "learn %d", &learn))
5879         ;
5880       else if (unformat (i, "arp-term %d", &arp_term))
5881         ;
5882       else if (unformat (i, "mac-age %d", &mac_age))
5883         ;
5884       else if (unformat (i, "del"))
5885         {
5886           is_add = 0;
5887           flood = uu_flood = forward = learn = 0;
5888         }
5889       else
5890         break;
5891     }
5892
5893   if (bd_id == ~0)
5894     {
5895       errmsg ("missing bridge domain");
5896       return -99;
5897     }
5898
5899   if (mac_age > 255)
5900     {
5901       errmsg ("mac age must be less than 256 ");
5902       return -99;
5903     }
5904
5905   M (BRIDGE_DOMAIN_ADD_DEL, mp);
5906
5907   mp->bd_id = ntohl (bd_id);
5908   mp->flood = flood;
5909   mp->uu_flood = uu_flood;
5910   mp->forward = forward;
5911   mp->learn = learn;
5912   mp->arp_term = arp_term;
5913   mp->is_add = is_add;
5914   mp->mac_age = (u8) mac_age;
5915
5916   S (mp);
5917   W (ret);
5918   return ret;
5919 }
5920
5921 static int
5922 api_l2fib_flush_bd (vat_main_t * vam)
5923 {
5924   unformat_input_t *i = vam->input;
5925   vl_api_l2fib_flush_bd_t *mp;
5926   u32 bd_id = ~0;
5927   int ret;
5928
5929   /* Parse args required to build the message */
5930   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5931     {
5932       if (unformat (i, "bd_id %d", &bd_id));
5933       else
5934         break;
5935     }
5936
5937   if (bd_id == ~0)
5938     {
5939       errmsg ("missing bridge domain");
5940       return -99;
5941     }
5942
5943   M (L2FIB_FLUSH_BD, mp);
5944
5945   mp->bd_id = htonl (bd_id);
5946
5947   S (mp);
5948   W (ret);
5949   return ret;
5950 }
5951
5952 static int
5953 api_l2fib_flush_int (vat_main_t * vam)
5954 {
5955   unformat_input_t *i = vam->input;
5956   vl_api_l2fib_flush_int_t *mp;
5957   u32 sw_if_index = ~0;
5958   int ret;
5959
5960   /* Parse args required to build the message */
5961   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5962     {
5963       if (unformat (i, "sw_if_index %d", &sw_if_index));
5964       else
5965         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
5966       else
5967         break;
5968     }
5969
5970   if (sw_if_index == ~0)
5971     {
5972       errmsg ("missing interface name or sw_if_index");
5973       return -99;
5974     }
5975
5976   M (L2FIB_FLUSH_INT, mp);
5977
5978   mp->sw_if_index = ntohl (sw_if_index);
5979
5980   S (mp);
5981   W (ret);
5982   return ret;
5983 }
5984
5985 static int
5986 api_l2fib_add_del (vat_main_t * vam)
5987 {
5988   unformat_input_t *i = vam->input;
5989   vl_api_l2fib_add_del_t *mp;
5990   f64 timeout;
5991   u64 mac = 0;
5992   u8 mac_set = 0;
5993   u32 bd_id;
5994   u8 bd_id_set = 0;
5995   u32 sw_if_index = ~0;
5996   u8 sw_if_index_set = 0;
5997   u8 is_add = 1;
5998   u8 static_mac = 0;
5999   u8 filter_mac = 0;
6000   u8 bvi_mac = 0;
6001   int count = 1;
6002   f64 before = 0;
6003   int j;
6004
6005   /* Parse args required to build the message */
6006   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6007     {
6008       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
6009         mac_set = 1;
6010       else if (unformat (i, "bd_id %d", &bd_id))
6011         bd_id_set = 1;
6012       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6013         sw_if_index_set = 1;
6014       else if (unformat (i, "sw_if"))
6015         {
6016           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6017             {
6018               if (unformat
6019                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6020                 sw_if_index_set = 1;
6021             }
6022           else
6023             break;
6024         }
6025       else if (unformat (i, "static"))
6026         static_mac = 1;
6027       else if (unformat (i, "filter"))
6028         {
6029           filter_mac = 1;
6030           static_mac = 1;
6031         }
6032       else if (unformat (i, "bvi"))
6033         {
6034           bvi_mac = 1;
6035           static_mac = 1;
6036         }
6037       else if (unformat (i, "del"))
6038         is_add = 0;
6039       else if (unformat (i, "count %d", &count))
6040         ;
6041       else
6042         break;
6043     }
6044
6045   if (mac_set == 0)
6046     {
6047       errmsg ("missing mac address");
6048       return -99;
6049     }
6050
6051   if (bd_id_set == 0)
6052     {
6053       errmsg ("missing bridge domain");
6054       return -99;
6055     }
6056
6057   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6058     {
6059       errmsg ("missing interface name or sw_if_index");
6060       return -99;
6061     }
6062
6063   if (count > 1)
6064     {
6065       /* Turn on async mode */
6066       vam->async_mode = 1;
6067       vam->async_errors = 0;
6068       before = vat_time_now (vam);
6069     }
6070
6071   for (j = 0; j < count; j++)
6072     {
6073       M (L2FIB_ADD_DEL, mp);
6074
6075       mp->mac = mac;
6076       mp->bd_id = ntohl (bd_id);
6077       mp->is_add = is_add;
6078
6079       if (is_add)
6080         {
6081           mp->sw_if_index = ntohl (sw_if_index);
6082           mp->static_mac = static_mac;
6083           mp->filter_mac = filter_mac;
6084           mp->bvi_mac = bvi_mac;
6085         }
6086       increment_mac_address (&mac);
6087       /* send it... */
6088       S (mp);
6089     }
6090
6091   if (count > 1)
6092     {
6093       vl_api_control_ping_t *mp_ping;
6094       f64 after;
6095
6096       /* Shut off async mode */
6097       vam->async_mode = 0;
6098
6099       M (CONTROL_PING, mp_ping);
6100       S (mp_ping);
6101
6102       timeout = vat_time_now (vam) + 1.0;
6103       while (vat_time_now (vam) < timeout)
6104         if (vam->result_ready == 1)
6105           goto out;
6106       vam->retval = -99;
6107
6108     out:
6109       if (vam->retval == -99)
6110         errmsg ("timeout");
6111
6112       if (vam->async_errors > 0)
6113         {
6114           errmsg ("%d asynchronous errors", vam->async_errors);
6115           vam->retval = -98;
6116         }
6117       vam->async_errors = 0;
6118       after = vat_time_now (vam);
6119
6120       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6121              count, after - before, count / (after - before));
6122     }
6123   else
6124     {
6125       int ret;
6126
6127       /* Wait for a reply... */
6128       W (ret);
6129       return ret;
6130     }
6131   /* Return the good/bad news */
6132   return (vam->retval);
6133 }
6134
6135 static int
6136 api_bridge_domain_set_mac_age (vat_main_t * vam)
6137 {
6138   unformat_input_t *i = vam->input;
6139   vl_api_bridge_domain_set_mac_age_t *mp;
6140   u32 bd_id = ~0;
6141   u32 mac_age = 0;
6142   int ret;
6143
6144   /* Parse args required to build the message */
6145   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6146     {
6147       if (unformat (i, "bd_id %d", &bd_id));
6148       else if (unformat (i, "mac-age %d", &mac_age));
6149       else
6150         break;
6151     }
6152
6153   if (bd_id == ~0)
6154     {
6155       errmsg ("missing bridge domain");
6156       return -99;
6157     }
6158
6159   if (mac_age > 255)
6160     {
6161       errmsg ("mac age must be less than 256 ");
6162       return -99;
6163     }
6164
6165   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6166
6167   mp->bd_id = htonl (bd_id);
6168   mp->mac_age = (u8) mac_age;
6169
6170   S (mp);
6171   W (ret);
6172   return ret;
6173 }
6174
6175 static int
6176 api_l2_flags (vat_main_t * vam)
6177 {
6178   unformat_input_t *i = vam->input;
6179   vl_api_l2_flags_t *mp;
6180   u32 sw_if_index;
6181   u32 feature_bitmap = 0;
6182   u8 sw_if_index_set = 0;
6183   int ret;
6184
6185   /* Parse args required to build the message */
6186   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6187     {
6188       if (unformat (i, "sw_if_index %d", &sw_if_index))
6189         sw_if_index_set = 1;
6190       else if (unformat (i, "sw_if"))
6191         {
6192           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6193             {
6194               if (unformat
6195                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6196                 sw_if_index_set = 1;
6197             }
6198           else
6199             break;
6200         }
6201       else if (unformat (i, "learn"))
6202         feature_bitmap |= L2INPUT_FEAT_LEARN;
6203       else if (unformat (i, "forward"))
6204         feature_bitmap |= L2INPUT_FEAT_FWD;
6205       else if (unformat (i, "flood"))
6206         feature_bitmap |= L2INPUT_FEAT_FLOOD;
6207       else if (unformat (i, "uu-flood"))
6208         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
6209       else
6210         break;
6211     }
6212
6213   if (sw_if_index_set == 0)
6214     {
6215       errmsg ("missing interface name or sw_if_index");
6216       return -99;
6217     }
6218
6219   M (L2_FLAGS, mp);
6220
6221   mp->sw_if_index = ntohl (sw_if_index);
6222   mp->feature_bitmap = ntohl (feature_bitmap);
6223
6224   S (mp);
6225   W (ret);
6226   return ret;
6227 }
6228
6229 static int
6230 api_bridge_flags (vat_main_t * vam)
6231 {
6232   unformat_input_t *i = vam->input;
6233   vl_api_bridge_flags_t *mp;
6234   u32 bd_id;
6235   u8 bd_id_set = 0;
6236   u8 is_set = 1;
6237   u32 flags = 0;
6238   int ret;
6239
6240   /* Parse args required to build the message */
6241   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6242     {
6243       if (unformat (i, "bd_id %d", &bd_id))
6244         bd_id_set = 1;
6245       else if (unformat (i, "learn"))
6246         flags |= L2_LEARN;
6247       else if (unformat (i, "forward"))
6248         flags |= L2_FWD;
6249       else if (unformat (i, "flood"))
6250         flags |= L2_FLOOD;
6251       else if (unformat (i, "uu-flood"))
6252         flags |= L2_UU_FLOOD;
6253       else if (unformat (i, "arp-term"))
6254         flags |= L2_ARP_TERM;
6255       else if (unformat (i, "off"))
6256         is_set = 0;
6257       else if (unformat (i, "disable"))
6258         is_set = 0;
6259       else
6260         break;
6261     }
6262
6263   if (bd_id_set == 0)
6264     {
6265       errmsg ("missing bridge domain");
6266       return -99;
6267     }
6268
6269   M (BRIDGE_FLAGS, mp);
6270
6271   mp->bd_id = ntohl (bd_id);
6272   mp->feature_bitmap = ntohl (flags);
6273   mp->is_set = is_set;
6274
6275   S (mp);
6276   W (ret);
6277   return ret;
6278 }
6279
6280 static int
6281 api_bd_ip_mac_add_del (vat_main_t * vam)
6282 {
6283   unformat_input_t *i = vam->input;
6284   vl_api_bd_ip_mac_add_del_t *mp;
6285   u32 bd_id;
6286   u8 is_ipv6 = 0;
6287   u8 is_add = 1;
6288   u8 bd_id_set = 0;
6289   u8 ip_set = 0;
6290   u8 mac_set = 0;
6291   ip4_address_t v4addr;
6292   ip6_address_t v6addr;
6293   u8 macaddr[6];
6294   int ret;
6295
6296
6297   /* Parse args required to build the message */
6298   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6299     {
6300       if (unformat (i, "bd_id %d", &bd_id))
6301         {
6302           bd_id_set++;
6303         }
6304       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
6305         {
6306           ip_set++;
6307         }
6308       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
6309         {
6310           ip_set++;
6311           is_ipv6++;
6312         }
6313       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
6314         {
6315           mac_set++;
6316         }
6317       else if (unformat (i, "del"))
6318         is_add = 0;
6319       else
6320         break;
6321     }
6322
6323   if (bd_id_set == 0)
6324     {
6325       errmsg ("missing bridge domain");
6326       return -99;
6327     }
6328   else if (ip_set == 0)
6329     {
6330       errmsg ("missing IP address");
6331       return -99;
6332     }
6333   else if (mac_set == 0)
6334     {
6335       errmsg ("missing MAC address");
6336       return -99;
6337     }
6338
6339   M (BD_IP_MAC_ADD_DEL, mp);
6340
6341   mp->bd_id = ntohl (bd_id);
6342   mp->is_ipv6 = is_ipv6;
6343   mp->is_add = is_add;
6344   if (is_ipv6)
6345     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
6346   else
6347     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
6348   clib_memcpy (mp->mac_address, macaddr, 6);
6349   S (mp);
6350   W (ret);
6351   return ret;
6352 }
6353
6354 static int
6355 api_tap_connect (vat_main_t * vam)
6356 {
6357   unformat_input_t *i = vam->input;
6358   vl_api_tap_connect_t *mp;
6359   u8 mac_address[6];
6360   u8 random_mac = 1;
6361   u8 name_set = 0;
6362   u8 *tap_name;
6363   u8 *tag = 0;
6364   ip4_address_t ip4_address;
6365   u32 ip4_mask_width;
6366   int ip4_address_set = 0;
6367   ip6_address_t ip6_address;
6368   u32 ip6_mask_width;
6369   int ip6_address_set = 0;
6370   int ret;
6371
6372   memset (mac_address, 0, sizeof (mac_address));
6373
6374   /* Parse args required to build the message */
6375   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6376     {
6377       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6378         {
6379           random_mac = 0;
6380         }
6381       else if (unformat (i, "random-mac"))
6382         random_mac = 1;
6383       else if (unformat (i, "tapname %s", &tap_name))
6384         name_set = 1;
6385       else if (unformat (i, "tag %s", &tag))
6386         ;
6387       else if (unformat (i, "address %U/%d",
6388                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
6389         ip4_address_set = 1;
6390       else if (unformat (i, "address %U/%d",
6391                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
6392         ip6_address_set = 1;
6393       else
6394         break;
6395     }
6396
6397   if (name_set == 0)
6398     {
6399       errmsg ("missing tap name");
6400       return -99;
6401     }
6402   if (vec_len (tap_name) > 63)
6403     {
6404       errmsg ("tap name too long");
6405       return -99;
6406     }
6407   vec_add1 (tap_name, 0);
6408
6409   if (vec_len (tag) > 63)
6410     {
6411       errmsg ("tag too long");
6412       return -99;
6413     }
6414
6415   /* Construct the API message */
6416   M (TAP_CONNECT, mp);
6417
6418   mp->use_random_mac = random_mac;
6419   clib_memcpy (mp->mac_address, mac_address, 6);
6420   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6421   if (tag)
6422     clib_memcpy (mp->tag, tag, vec_len (tag));
6423
6424   if (ip4_address_set)
6425     {
6426       mp->ip4_address_set = 1;
6427       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6428       mp->ip4_mask_width = ip4_mask_width;
6429     }
6430   if (ip6_address_set)
6431     {
6432       mp->ip6_address_set = 1;
6433       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6434       mp->ip6_mask_width = ip6_mask_width;
6435     }
6436
6437   vec_free (tap_name);
6438   vec_free (tag);
6439
6440   /* send it... */
6441   S (mp);
6442
6443   /* Wait for a reply... */
6444   W (ret);
6445   return ret;
6446 }
6447
6448 static int
6449 api_tap_modify (vat_main_t * vam)
6450 {
6451   unformat_input_t *i = vam->input;
6452   vl_api_tap_modify_t *mp;
6453   u8 mac_address[6];
6454   u8 random_mac = 1;
6455   u8 name_set = 0;
6456   u8 *tap_name;
6457   u32 sw_if_index = ~0;
6458   u8 sw_if_index_set = 0;
6459   int ret;
6460
6461   memset (mac_address, 0, sizeof (mac_address));
6462
6463   /* Parse args required to build the message */
6464   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6465     {
6466       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6467         sw_if_index_set = 1;
6468       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6469         sw_if_index_set = 1;
6470       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6471         {
6472           random_mac = 0;
6473         }
6474       else if (unformat (i, "random-mac"))
6475         random_mac = 1;
6476       else if (unformat (i, "tapname %s", &tap_name))
6477         name_set = 1;
6478       else
6479         break;
6480     }
6481
6482   if (sw_if_index_set == 0)
6483     {
6484       errmsg ("missing vpp interface name");
6485       return -99;
6486     }
6487   if (name_set == 0)
6488     {
6489       errmsg ("missing tap name");
6490       return -99;
6491     }
6492   if (vec_len (tap_name) > 63)
6493     {
6494       errmsg ("tap name too long");
6495     }
6496   vec_add1 (tap_name, 0);
6497
6498   /* Construct the API message */
6499   M (TAP_MODIFY, mp);
6500
6501   mp->use_random_mac = random_mac;
6502   mp->sw_if_index = ntohl (sw_if_index);
6503   clib_memcpy (mp->mac_address, mac_address, 6);
6504   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6505   vec_free (tap_name);
6506
6507   /* send it... */
6508   S (mp);
6509
6510   /* Wait for a reply... */
6511   W (ret);
6512   return ret;
6513 }
6514
6515 static int
6516 api_tap_delete (vat_main_t * vam)
6517 {
6518   unformat_input_t *i = vam->input;
6519   vl_api_tap_delete_t *mp;
6520   u32 sw_if_index = ~0;
6521   u8 sw_if_index_set = 0;
6522   int ret;
6523
6524   /* Parse args required to build the message */
6525   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6526     {
6527       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6528         sw_if_index_set = 1;
6529       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6530         sw_if_index_set = 1;
6531       else
6532         break;
6533     }
6534
6535   if (sw_if_index_set == 0)
6536     {
6537       errmsg ("missing vpp interface name");
6538       return -99;
6539     }
6540
6541   /* Construct the API message */
6542   M (TAP_DELETE, mp);
6543
6544   mp->sw_if_index = ntohl (sw_if_index);
6545
6546   /* send it... */
6547   S (mp);
6548
6549   /* Wait for a reply... */
6550   W (ret);
6551   return ret;
6552 }
6553
6554 static int
6555 api_ip_add_del_route (vat_main_t * vam)
6556 {
6557   unformat_input_t *i = vam->input;
6558   vl_api_ip_add_del_route_t *mp;
6559   u32 sw_if_index = ~0, vrf_id = 0;
6560   u8 is_ipv6 = 0;
6561   u8 is_local = 0, is_drop = 0;
6562   u8 is_unreach = 0, is_prohibit = 0;
6563   u8 create_vrf_if_needed = 0;
6564   u8 is_add = 1;
6565   u32 next_hop_weight = 1;
6566   u8 not_last = 0;
6567   u8 is_multipath = 0;
6568   u8 address_set = 0;
6569   u8 address_length_set = 0;
6570   u32 next_hop_table_id = 0;
6571   u32 resolve_attempts = 0;
6572   u32 dst_address_length = 0;
6573   u8 next_hop_set = 0;
6574   ip4_address_t v4_dst_address, v4_next_hop_address;
6575   ip6_address_t v6_dst_address, v6_next_hop_address;
6576   int count = 1;
6577   int j;
6578   f64 before = 0;
6579   u32 random_add_del = 0;
6580   u32 *random_vector = 0;
6581   uword *random_hash;
6582   u32 random_seed = 0xdeaddabe;
6583   u32 classify_table_index = ~0;
6584   u8 is_classify = 0;
6585   u8 resolve_host = 0, resolve_attached = 0;
6586   mpls_label_t *next_hop_out_label_stack = NULL;
6587   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6588   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6589
6590   /* Parse args required to build the message */
6591   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6592     {
6593       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6594         ;
6595       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6596         ;
6597       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6598         {
6599           address_set = 1;
6600           is_ipv6 = 0;
6601         }
6602       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6603         {
6604           address_set = 1;
6605           is_ipv6 = 1;
6606         }
6607       else if (unformat (i, "/%d", &dst_address_length))
6608         {
6609           address_length_set = 1;
6610         }
6611
6612       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6613                                          &v4_next_hop_address))
6614         {
6615           next_hop_set = 1;
6616         }
6617       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6618                                          &v6_next_hop_address))
6619         {
6620           next_hop_set = 1;
6621         }
6622       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6623         ;
6624       else if (unformat (i, "weight %d", &next_hop_weight))
6625         ;
6626       else if (unformat (i, "drop"))
6627         {
6628           is_drop = 1;
6629         }
6630       else if (unformat (i, "null-send-unreach"))
6631         {
6632           is_unreach = 1;
6633         }
6634       else if (unformat (i, "null-send-prohibit"))
6635         {
6636           is_prohibit = 1;
6637         }
6638       else if (unformat (i, "local"))
6639         {
6640           is_local = 1;
6641         }
6642       else if (unformat (i, "classify %d", &classify_table_index))
6643         {
6644           is_classify = 1;
6645         }
6646       else if (unformat (i, "del"))
6647         is_add = 0;
6648       else if (unformat (i, "add"))
6649         is_add = 1;
6650       else if (unformat (i, "not-last"))
6651         not_last = 1;
6652       else if (unformat (i, "resolve-via-host"))
6653         resolve_host = 1;
6654       else if (unformat (i, "resolve-via-attached"))
6655         resolve_attached = 1;
6656       else if (unformat (i, "multipath"))
6657         is_multipath = 1;
6658       else if (unformat (i, "vrf %d", &vrf_id))
6659         ;
6660       else if (unformat (i, "create-vrf"))
6661         create_vrf_if_needed = 1;
6662       else if (unformat (i, "count %d", &count))
6663         ;
6664       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6665         ;
6666       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6667         ;
6668       else if (unformat (i, "out-label %d", &next_hop_out_label))
6669         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6670       else if (unformat (i, "via-label %d", &next_hop_via_label))
6671         ;
6672       else if (unformat (i, "random"))
6673         random_add_del = 1;
6674       else if (unformat (i, "seed %d", &random_seed))
6675         ;
6676       else
6677         {
6678           clib_warning ("parse error '%U'", format_unformat_error, i);
6679           return -99;
6680         }
6681     }
6682
6683   if (!next_hop_set && !is_drop && !is_local &&
6684       !is_classify && !is_unreach && !is_prohibit &&
6685       MPLS_LABEL_INVALID == next_hop_via_label)
6686     {
6687       errmsg
6688         ("next hop / local / drop / unreach / prohibit / classify not set");
6689       return -99;
6690     }
6691
6692   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6693     {
6694       errmsg ("next hop and next-hop via label set");
6695       return -99;
6696     }
6697   if (address_set == 0)
6698     {
6699       errmsg ("missing addresses");
6700       return -99;
6701     }
6702
6703   if (address_length_set == 0)
6704     {
6705       errmsg ("missing address length");
6706       return -99;
6707     }
6708
6709   /* Generate a pile of unique, random routes */
6710   if (random_add_del)
6711     {
6712       u32 this_random_address;
6713       random_hash = hash_create (count, sizeof (uword));
6714
6715       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6716       for (j = 0; j <= count; j++)
6717         {
6718           do
6719             {
6720               this_random_address = random_u32 (&random_seed);
6721               this_random_address =
6722                 clib_host_to_net_u32 (this_random_address);
6723             }
6724           while (hash_get (random_hash, this_random_address));
6725           vec_add1 (random_vector, this_random_address);
6726           hash_set (random_hash, this_random_address, 1);
6727         }
6728       hash_free (random_hash);
6729       v4_dst_address.as_u32 = random_vector[0];
6730     }
6731
6732   if (count > 1)
6733     {
6734       /* Turn on async mode */
6735       vam->async_mode = 1;
6736       vam->async_errors = 0;
6737       before = vat_time_now (vam);
6738     }
6739
6740   for (j = 0; j < count; j++)
6741     {
6742       /* Construct the API message */
6743       M2 (IP_ADD_DEL_ROUTE, mp,
6744           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6745
6746       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6747       mp->table_id = ntohl (vrf_id);
6748       mp->create_vrf_if_needed = create_vrf_if_needed;
6749
6750       mp->is_add = is_add;
6751       mp->is_drop = is_drop;
6752       mp->is_unreach = is_unreach;
6753       mp->is_prohibit = is_prohibit;
6754       mp->is_ipv6 = is_ipv6;
6755       mp->is_local = is_local;
6756       mp->is_classify = is_classify;
6757       mp->is_multipath = is_multipath;
6758       mp->is_resolve_host = resolve_host;
6759       mp->is_resolve_attached = resolve_attached;
6760       mp->not_last = not_last;
6761       mp->next_hop_weight = next_hop_weight;
6762       mp->dst_address_length = dst_address_length;
6763       mp->next_hop_table_id = ntohl (next_hop_table_id);
6764       mp->classify_table_index = ntohl (classify_table_index);
6765       mp->next_hop_via_label = ntohl (next_hop_via_label);
6766       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6767       if (0 != mp->next_hop_n_out_labels)
6768         {
6769           memcpy (mp->next_hop_out_label_stack,
6770                   next_hop_out_label_stack,
6771                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6772           vec_free (next_hop_out_label_stack);
6773         }
6774
6775       if (is_ipv6)
6776         {
6777           clib_memcpy (mp->dst_address, &v6_dst_address,
6778                        sizeof (v6_dst_address));
6779           if (next_hop_set)
6780             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6781                          sizeof (v6_next_hop_address));
6782           increment_v6_address (&v6_dst_address);
6783         }
6784       else
6785         {
6786           clib_memcpy (mp->dst_address, &v4_dst_address,
6787                        sizeof (v4_dst_address));
6788           if (next_hop_set)
6789             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6790                          sizeof (v4_next_hop_address));
6791           if (random_add_del)
6792             v4_dst_address.as_u32 = random_vector[j + 1];
6793           else
6794             increment_v4_address (&v4_dst_address);
6795         }
6796       /* send it... */
6797       S (mp);
6798       /* If we receive SIGTERM, stop now... */
6799       if (vam->do_exit)
6800         break;
6801     }
6802
6803   /* When testing multiple add/del ops, use a control-ping to sync */
6804   if (count > 1)
6805     {
6806       vl_api_control_ping_t *mp_ping;
6807       f64 after;
6808       f64 timeout;
6809
6810       /* Shut off async mode */
6811       vam->async_mode = 0;
6812
6813       M (CONTROL_PING, mp_ping);
6814       S (mp_ping);
6815
6816       timeout = vat_time_now (vam) + 1.0;
6817       while (vat_time_now (vam) < timeout)
6818         if (vam->result_ready == 1)
6819           goto out;
6820       vam->retval = -99;
6821
6822     out:
6823       if (vam->retval == -99)
6824         errmsg ("timeout");
6825
6826       if (vam->async_errors > 0)
6827         {
6828           errmsg ("%d asynchronous errors", vam->async_errors);
6829           vam->retval = -98;
6830         }
6831       vam->async_errors = 0;
6832       after = vat_time_now (vam);
6833
6834       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6835       if (j > 0)
6836         count = j;
6837
6838       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6839              count, after - before, count / (after - before));
6840     }
6841   else
6842     {
6843       int ret;
6844
6845       /* Wait for a reply... */
6846       W (ret);
6847       return ret;
6848     }
6849
6850   /* Return the good/bad news */
6851   return (vam->retval);
6852 }
6853
6854 static int
6855 api_ip_mroute_add_del (vat_main_t * vam)
6856 {
6857   unformat_input_t *i = vam->input;
6858   vl_api_ip_mroute_add_del_t *mp;
6859   u32 sw_if_index = ~0, vrf_id = 0;
6860   u8 is_ipv6 = 0;
6861   u8 is_local = 0;
6862   u8 create_vrf_if_needed = 0;
6863   u8 is_add = 1;
6864   u8 address_set = 0;
6865   u32 grp_address_length = 0;
6866   ip4_address_t v4_grp_address, v4_src_address;
6867   ip6_address_t v6_grp_address, v6_src_address;
6868   mfib_itf_flags_t iflags = 0;
6869   mfib_entry_flags_t eflags = 0;
6870   int ret;
6871
6872   /* Parse args required to build the message */
6873   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6874     {
6875       if (unformat (i, "sw_if_index %d", &sw_if_index))
6876         ;
6877       else if (unformat (i, "%U %U",
6878                          unformat_ip4_address, &v4_src_address,
6879                          unformat_ip4_address, &v4_grp_address))
6880         {
6881           grp_address_length = 64;
6882           address_set = 1;
6883           is_ipv6 = 0;
6884         }
6885       else if (unformat (i, "%U %U",
6886                          unformat_ip6_address, &v6_src_address,
6887                          unformat_ip6_address, &v6_grp_address))
6888         {
6889           grp_address_length = 256;
6890           address_set = 1;
6891           is_ipv6 = 1;
6892         }
6893       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
6894         {
6895           memset (&v4_src_address, 0, sizeof (v4_src_address));
6896           grp_address_length = 32;
6897           address_set = 1;
6898           is_ipv6 = 0;
6899         }
6900       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
6901         {
6902           memset (&v6_src_address, 0, sizeof (v6_src_address));
6903           grp_address_length = 128;
6904           address_set = 1;
6905           is_ipv6 = 1;
6906         }
6907       else if (unformat (i, "/%d", &grp_address_length))
6908         ;
6909       else if (unformat (i, "local"))
6910         {
6911           is_local = 1;
6912         }
6913       else if (unformat (i, "del"))
6914         is_add = 0;
6915       else if (unformat (i, "add"))
6916         is_add = 1;
6917       else if (unformat (i, "vrf %d", &vrf_id))
6918         ;
6919       else if (unformat (i, "create-vrf"))
6920         create_vrf_if_needed = 1;
6921       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
6922         ;
6923       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6924         ;
6925       else
6926         {
6927           clib_warning ("parse error '%U'", format_unformat_error, i);
6928           return -99;
6929         }
6930     }
6931
6932   if (address_set == 0)
6933     {
6934       errmsg ("missing addresses\n");
6935       return -99;
6936     }
6937
6938   /* Construct the API message */
6939   M (IP_MROUTE_ADD_DEL, mp);
6940
6941   mp->next_hop_sw_if_index = ntohl (sw_if_index);
6942   mp->table_id = ntohl (vrf_id);
6943   mp->create_vrf_if_needed = create_vrf_if_needed;
6944
6945   mp->is_add = is_add;
6946   mp->is_ipv6 = is_ipv6;
6947   mp->is_local = is_local;
6948   mp->itf_flags = ntohl (iflags);
6949   mp->entry_flags = ntohl (eflags);
6950   mp->grp_address_length = grp_address_length;
6951   mp->grp_address_length = ntohs (mp->grp_address_length);
6952
6953   if (is_ipv6)
6954     {
6955       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
6956       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
6957     }
6958   else
6959     {
6960       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
6961       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
6962
6963     }
6964
6965   /* send it... */
6966   S (mp);
6967   /* Wait for a reply... */
6968   W (ret);
6969   return ret;
6970 }
6971
6972 static int
6973 api_mpls_route_add_del (vat_main_t * vam)
6974 {
6975   unformat_input_t *i = vam->input;
6976   vl_api_mpls_route_add_del_t *mp;
6977   u32 sw_if_index = ~0, table_id = 0;
6978   u8 create_table_if_needed = 0;
6979   u8 is_add = 1;
6980   u32 next_hop_weight = 1;
6981   u8 is_multipath = 0;
6982   u32 next_hop_table_id = 0;
6983   u8 next_hop_set = 0;
6984   ip4_address_t v4_next_hop_address = {
6985     .as_u32 = 0,
6986   };
6987   ip6_address_t v6_next_hop_address = { {0} };
6988   int count = 1;
6989   int j;
6990   f64 before = 0;
6991   u32 classify_table_index = ~0;
6992   u8 is_classify = 0;
6993   u8 resolve_host = 0, resolve_attached = 0;
6994   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6995   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6996   mpls_label_t *next_hop_out_label_stack = NULL;
6997   mpls_label_t local_label = MPLS_LABEL_INVALID;
6998   u8 is_eos = 0;
6999   u8 next_hop_proto_is_ip4 = 1;
7000
7001   /* Parse args required to build the message */
7002   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7003     {
7004       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7005         ;
7006       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7007         ;
7008       else if (unformat (i, "%d", &local_label))
7009         ;
7010       else if (unformat (i, "eos"))
7011         is_eos = 1;
7012       else if (unformat (i, "non-eos"))
7013         is_eos = 0;
7014       else if (unformat (i, "via %U", unformat_ip4_address,
7015                          &v4_next_hop_address))
7016         {
7017           next_hop_set = 1;
7018           next_hop_proto_is_ip4 = 1;
7019         }
7020       else if (unformat (i, "via %U", unformat_ip6_address,
7021                          &v6_next_hop_address))
7022         {
7023           next_hop_set = 1;
7024           next_hop_proto_is_ip4 = 0;
7025         }
7026       else if (unformat (i, "weight %d", &next_hop_weight))
7027         ;
7028       else if (unformat (i, "create-table"))
7029         create_table_if_needed = 1;
7030       else if (unformat (i, "classify %d", &classify_table_index))
7031         {
7032           is_classify = 1;
7033         }
7034       else if (unformat (i, "del"))
7035         is_add = 0;
7036       else if (unformat (i, "add"))
7037         is_add = 1;
7038       else if (unformat (i, "resolve-via-host"))
7039         resolve_host = 1;
7040       else if (unformat (i, "resolve-via-attached"))
7041         resolve_attached = 1;
7042       else if (unformat (i, "multipath"))
7043         is_multipath = 1;
7044       else if (unformat (i, "count %d", &count))
7045         ;
7046       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
7047         {
7048           next_hop_set = 1;
7049           next_hop_proto_is_ip4 = 1;
7050         }
7051       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
7052         {
7053           next_hop_set = 1;
7054           next_hop_proto_is_ip4 = 0;
7055         }
7056       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7057         ;
7058       else if (unformat (i, "via-label %d", &next_hop_via_label))
7059         ;
7060       else if (unformat (i, "out-label %d", &next_hop_out_label))
7061         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7062       else
7063         {
7064           clib_warning ("parse error '%U'", format_unformat_error, i);
7065           return -99;
7066         }
7067     }
7068
7069   if (!next_hop_set && !is_classify)
7070     {
7071       errmsg ("next hop / classify not set");
7072       return -99;
7073     }
7074
7075   if (MPLS_LABEL_INVALID == local_label)
7076     {
7077       errmsg ("missing label");
7078       return -99;
7079     }
7080
7081   if (count > 1)
7082     {
7083       /* Turn on async mode */
7084       vam->async_mode = 1;
7085       vam->async_errors = 0;
7086       before = vat_time_now (vam);
7087     }
7088
7089   for (j = 0; j < count; j++)
7090     {
7091       /* Construct the API message */
7092       M2 (MPLS_ROUTE_ADD_DEL, mp,
7093           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7094
7095       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
7096       mp->mr_table_id = ntohl (table_id);
7097       mp->mr_create_table_if_needed = create_table_if_needed;
7098
7099       mp->mr_is_add = is_add;
7100       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7101       mp->mr_is_classify = is_classify;
7102       mp->mr_is_multipath = is_multipath;
7103       mp->mr_is_resolve_host = resolve_host;
7104       mp->mr_is_resolve_attached = resolve_attached;
7105       mp->mr_next_hop_weight = next_hop_weight;
7106       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
7107       mp->mr_classify_table_index = ntohl (classify_table_index);
7108       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
7109       mp->mr_label = ntohl (local_label);
7110       mp->mr_eos = is_eos;
7111
7112       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7113       if (0 != mp->mr_next_hop_n_out_labels)
7114         {
7115           memcpy (mp->mr_next_hop_out_label_stack,
7116                   next_hop_out_label_stack,
7117                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7118           vec_free (next_hop_out_label_stack);
7119         }
7120
7121       if (next_hop_set)
7122         {
7123           if (next_hop_proto_is_ip4)
7124             {
7125               clib_memcpy (mp->mr_next_hop,
7126                            &v4_next_hop_address,
7127                            sizeof (v4_next_hop_address));
7128             }
7129           else
7130             {
7131               clib_memcpy (mp->mr_next_hop,
7132                            &v6_next_hop_address,
7133                            sizeof (v6_next_hop_address));
7134             }
7135         }
7136       local_label++;
7137
7138       /* send it... */
7139       S (mp);
7140       /* If we receive SIGTERM, stop now... */
7141       if (vam->do_exit)
7142         break;
7143     }
7144
7145   /* When testing multiple add/del ops, use a control-ping to sync */
7146   if (count > 1)
7147     {
7148       vl_api_control_ping_t *mp_ping;
7149       f64 after;
7150       f64 timeout;
7151
7152       /* Shut off async mode */
7153       vam->async_mode = 0;
7154
7155       M (CONTROL_PING, mp_ping);
7156       S (mp_ping);
7157
7158       timeout = vat_time_now (vam) + 1.0;
7159       while (vat_time_now (vam) < timeout)
7160         if (vam->result_ready == 1)
7161           goto out;
7162       vam->retval = -99;
7163
7164     out:
7165       if (vam->retval == -99)
7166         errmsg ("timeout");
7167
7168       if (vam->async_errors > 0)
7169         {
7170           errmsg ("%d asynchronous errors", vam->async_errors);
7171           vam->retval = -98;
7172         }
7173       vam->async_errors = 0;
7174       after = vat_time_now (vam);
7175
7176       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7177       if (j > 0)
7178         count = j;
7179
7180       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7181              count, after - before, count / (after - before));
7182     }
7183   else
7184     {
7185       int ret;
7186
7187       /* Wait for a reply... */
7188       W (ret);
7189       return ret;
7190     }
7191
7192   /* Return the good/bad news */
7193   return (vam->retval);
7194 }
7195
7196 static int
7197 api_mpls_ip_bind_unbind (vat_main_t * vam)
7198 {
7199   unformat_input_t *i = vam->input;
7200   vl_api_mpls_ip_bind_unbind_t *mp;
7201   u32 ip_table_id = 0;
7202   u8 create_table_if_needed = 0;
7203   u8 is_bind = 1;
7204   u8 is_ip4 = 1;
7205   ip4_address_t v4_address;
7206   ip6_address_t v6_address;
7207   u32 address_length;
7208   u8 address_set = 0;
7209   mpls_label_t local_label = MPLS_LABEL_INVALID;
7210   int ret;
7211
7212   /* Parse args required to build the message */
7213   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7214     {
7215       if (unformat (i, "%U/%d", unformat_ip4_address,
7216                     &v4_address, &address_length))
7217         {
7218           is_ip4 = 1;
7219           address_set = 1;
7220         }
7221       else if (unformat (i, "%U/%d", unformat_ip6_address,
7222                          &v6_address, &address_length))
7223         {
7224           is_ip4 = 0;
7225           address_set = 1;
7226         }
7227       else if (unformat (i, "%d", &local_label))
7228         ;
7229       else if (unformat (i, "create-table"))
7230         create_table_if_needed = 1;
7231       else if (unformat (i, "table-id %d", &ip_table_id))
7232         ;
7233       else if (unformat (i, "unbind"))
7234         is_bind = 0;
7235       else if (unformat (i, "bind"))
7236         is_bind = 1;
7237       else
7238         {
7239           clib_warning ("parse error '%U'", format_unformat_error, i);
7240           return -99;
7241         }
7242     }
7243
7244   if (!address_set)
7245     {
7246       errmsg ("IP addres not set");
7247       return -99;
7248     }
7249
7250   if (MPLS_LABEL_INVALID == local_label)
7251     {
7252       errmsg ("missing label");
7253       return -99;
7254     }
7255
7256   /* Construct the API message */
7257   M (MPLS_IP_BIND_UNBIND, mp);
7258
7259   mp->mb_create_table_if_needed = create_table_if_needed;
7260   mp->mb_is_bind = is_bind;
7261   mp->mb_is_ip4 = is_ip4;
7262   mp->mb_ip_table_id = ntohl (ip_table_id);
7263   mp->mb_mpls_table_id = 0;
7264   mp->mb_label = ntohl (local_label);
7265   mp->mb_address_length = address_length;
7266
7267   if (is_ip4)
7268     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
7269   else
7270     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
7271
7272   /* send it... */
7273   S (mp);
7274
7275   /* Wait for a reply... */
7276   W (ret);
7277   return ret;
7278 }
7279
7280 static int
7281 api_proxy_arp_add_del (vat_main_t * vam)
7282 {
7283   unformat_input_t *i = vam->input;
7284   vl_api_proxy_arp_add_del_t *mp;
7285   u32 vrf_id = 0;
7286   u8 is_add = 1;
7287   ip4_address_t lo, hi;
7288   u8 range_set = 0;
7289   int ret;
7290
7291   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7292     {
7293       if (unformat (i, "vrf %d", &vrf_id))
7294         ;
7295       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
7296                          unformat_ip4_address, &hi))
7297         range_set = 1;
7298       else if (unformat (i, "del"))
7299         is_add = 0;
7300       else
7301         {
7302           clib_warning ("parse error '%U'", format_unformat_error, i);
7303           return -99;
7304         }
7305     }
7306
7307   if (range_set == 0)
7308     {
7309       errmsg ("address range not set");
7310       return -99;
7311     }
7312
7313   M (PROXY_ARP_ADD_DEL, mp);
7314
7315   mp->vrf_id = ntohl (vrf_id);
7316   mp->is_add = is_add;
7317   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
7318   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
7319
7320   S (mp);
7321   W (ret);
7322   return ret;
7323 }
7324
7325 static int
7326 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
7327 {
7328   unformat_input_t *i = vam->input;
7329   vl_api_proxy_arp_intfc_enable_disable_t *mp;
7330   u32 sw_if_index;
7331   u8 enable = 1;
7332   u8 sw_if_index_set = 0;
7333   int ret;
7334
7335   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7336     {
7337       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7338         sw_if_index_set = 1;
7339       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7340         sw_if_index_set = 1;
7341       else if (unformat (i, "enable"))
7342         enable = 1;
7343       else if (unformat (i, "disable"))
7344         enable = 0;
7345       else
7346         {
7347           clib_warning ("parse error '%U'", format_unformat_error, i);
7348           return -99;
7349         }
7350     }
7351
7352   if (sw_if_index_set == 0)
7353     {
7354       errmsg ("missing interface name or sw_if_index");
7355       return -99;
7356     }
7357
7358   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
7359
7360   mp->sw_if_index = ntohl (sw_if_index);
7361   mp->enable_disable = enable;
7362
7363   S (mp);
7364   W (ret);
7365   return ret;
7366 }
7367
7368 static int
7369 api_mpls_tunnel_add_del (vat_main_t * vam)
7370 {
7371   unformat_input_t *i = vam->input;
7372   vl_api_mpls_tunnel_add_del_t *mp;
7373
7374   u8 is_add = 1;
7375   u8 l2_only = 0;
7376   u32 sw_if_index = ~0;
7377   u32 next_hop_sw_if_index = ~0;
7378   u32 next_hop_proto_is_ip4 = 1;
7379
7380   u32 next_hop_table_id = 0;
7381   ip4_address_t v4_next_hop_address = {
7382     .as_u32 = 0,
7383   };
7384   ip6_address_t v6_next_hop_address = { {0} };
7385   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
7386   int ret;
7387
7388   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7389     {
7390       if (unformat (i, "add"))
7391         is_add = 1;
7392       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7393         is_add = 0;
7394       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7395         ;
7396       else if (unformat (i, "via %U",
7397                          unformat_ip4_address, &v4_next_hop_address))
7398         {
7399           next_hop_proto_is_ip4 = 1;
7400         }
7401       else if (unformat (i, "via %U",
7402                          unformat_ip6_address, &v6_next_hop_address))
7403         {
7404           next_hop_proto_is_ip4 = 0;
7405         }
7406       else if (unformat (i, "l2-only"))
7407         l2_only = 1;
7408       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7409         ;
7410       else if (unformat (i, "out-label %d", &next_hop_out_label))
7411         vec_add1 (labels, ntohl (next_hop_out_label));
7412       else
7413         {
7414           clib_warning ("parse error '%U'", format_unformat_error, i);
7415           return -99;
7416         }
7417     }
7418
7419   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
7420
7421   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
7422   mp->mt_sw_if_index = ntohl (sw_if_index);
7423   mp->mt_is_add = is_add;
7424   mp->mt_l2_only = l2_only;
7425   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
7426   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7427
7428   mp->mt_next_hop_n_out_labels = vec_len (labels);
7429
7430   if (0 != mp->mt_next_hop_n_out_labels)
7431     {
7432       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7433                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7434       vec_free (labels);
7435     }
7436
7437   if (next_hop_proto_is_ip4)
7438     {
7439       clib_memcpy (mp->mt_next_hop,
7440                    &v4_next_hop_address, sizeof (v4_next_hop_address));
7441     }
7442   else
7443     {
7444       clib_memcpy (mp->mt_next_hop,
7445                    &v6_next_hop_address, sizeof (v6_next_hop_address));
7446     }
7447
7448   S (mp);
7449   W (ret);
7450   return ret;
7451 }
7452
7453 static int
7454 api_sw_interface_set_unnumbered (vat_main_t * vam)
7455 {
7456   unformat_input_t *i = vam->input;
7457   vl_api_sw_interface_set_unnumbered_t *mp;
7458   u32 sw_if_index;
7459   u32 unnum_sw_index = ~0;
7460   u8 is_add = 1;
7461   u8 sw_if_index_set = 0;
7462   int ret;
7463
7464   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7465     {
7466       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7467         sw_if_index_set = 1;
7468       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7469         sw_if_index_set = 1;
7470       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7471         ;
7472       else if (unformat (i, "del"))
7473         is_add = 0;
7474       else
7475         {
7476           clib_warning ("parse error '%U'", format_unformat_error, i);
7477           return -99;
7478         }
7479     }
7480
7481   if (sw_if_index_set == 0)
7482     {
7483       errmsg ("missing interface name or sw_if_index");
7484       return -99;
7485     }
7486
7487   M (SW_INTERFACE_SET_UNNUMBERED, mp);
7488
7489   mp->sw_if_index = ntohl (sw_if_index);
7490   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7491   mp->is_add = is_add;
7492
7493   S (mp);
7494   W (ret);
7495   return ret;
7496 }
7497
7498 static int
7499 api_ip_neighbor_add_del (vat_main_t * vam)
7500 {
7501   unformat_input_t *i = vam->input;
7502   vl_api_ip_neighbor_add_del_t *mp;
7503   u32 sw_if_index;
7504   u8 sw_if_index_set = 0;
7505   u8 is_add = 1;
7506   u8 is_static = 0;
7507   u8 is_no_fib_entry = 0;
7508   u8 mac_address[6];
7509   u8 mac_set = 0;
7510   u8 v4_address_set = 0;
7511   u8 v6_address_set = 0;
7512   ip4_address_t v4address;
7513   ip6_address_t v6address;
7514   int ret;
7515
7516   memset (mac_address, 0, sizeof (mac_address));
7517
7518   /* Parse args required to build the message */
7519   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7520     {
7521       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7522         {
7523           mac_set = 1;
7524         }
7525       else if (unformat (i, "del"))
7526         is_add = 0;
7527       else
7528         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7529         sw_if_index_set = 1;
7530       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7531         sw_if_index_set = 1;
7532       else if (unformat (i, "is_static"))
7533         is_static = 1;
7534       else if (unformat (i, "no-fib-entry"))
7535         is_no_fib_entry = 1;
7536       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
7537         v4_address_set = 1;
7538       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
7539         v6_address_set = 1;
7540       else
7541         {
7542           clib_warning ("parse error '%U'", format_unformat_error, i);
7543           return -99;
7544         }
7545     }
7546
7547   if (sw_if_index_set == 0)
7548     {
7549       errmsg ("missing interface name or sw_if_index");
7550       return -99;
7551     }
7552   if (v4_address_set && v6_address_set)
7553     {
7554       errmsg ("both v4 and v6 addresses set");
7555       return -99;
7556     }
7557   if (!v4_address_set && !v6_address_set)
7558     {
7559       errmsg ("no address set");
7560       return -99;
7561     }
7562
7563   /* Construct the API message */
7564   M (IP_NEIGHBOR_ADD_DEL, mp);
7565
7566   mp->sw_if_index = ntohl (sw_if_index);
7567   mp->is_add = is_add;
7568   mp->is_static = is_static;
7569   mp->is_no_adj_fib = is_no_fib_entry;
7570   if (mac_set)
7571     clib_memcpy (mp->mac_address, mac_address, 6);
7572   if (v6_address_set)
7573     {
7574       mp->is_ipv6 = 1;
7575       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
7576     }
7577   else
7578     {
7579       /* mp->is_ipv6 = 0; via memset in M macro above */
7580       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
7581     }
7582
7583   /* send it... */
7584   S (mp);
7585
7586   /* Wait for a reply, return good/bad news  */
7587   W (ret);
7588   return ret;
7589 }
7590
7591 static int
7592 api_reset_vrf (vat_main_t * vam)
7593 {
7594   unformat_input_t *i = vam->input;
7595   vl_api_reset_vrf_t *mp;
7596   u32 vrf_id = 0;
7597   u8 is_ipv6 = 0;
7598   u8 vrf_id_set = 0;
7599   int ret;
7600
7601   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7602     {
7603       if (unformat (i, "vrf %d", &vrf_id))
7604         vrf_id_set = 1;
7605       else if (unformat (i, "ipv6"))
7606         is_ipv6 = 1;
7607       else
7608         {
7609           clib_warning ("parse error '%U'", format_unformat_error, i);
7610           return -99;
7611         }
7612     }
7613
7614   if (vrf_id_set == 0)
7615     {
7616       errmsg ("missing vrf id");
7617       return -99;
7618     }
7619
7620   M (RESET_VRF, mp);
7621
7622   mp->vrf_id = ntohl (vrf_id);
7623   mp->is_ipv6 = is_ipv6;
7624
7625   S (mp);
7626   W (ret);
7627   return ret;
7628 }
7629
7630 static int
7631 api_create_vlan_subif (vat_main_t * vam)
7632 {
7633   unformat_input_t *i = vam->input;
7634   vl_api_create_vlan_subif_t *mp;
7635   u32 sw_if_index;
7636   u8 sw_if_index_set = 0;
7637   u32 vlan_id;
7638   u8 vlan_id_set = 0;
7639   int ret;
7640
7641   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7642     {
7643       if (unformat (i, "sw_if_index %d", &sw_if_index))
7644         sw_if_index_set = 1;
7645       else
7646         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7647         sw_if_index_set = 1;
7648       else if (unformat (i, "vlan %d", &vlan_id))
7649         vlan_id_set = 1;
7650       else
7651         {
7652           clib_warning ("parse error '%U'", format_unformat_error, i);
7653           return -99;
7654         }
7655     }
7656
7657   if (sw_if_index_set == 0)
7658     {
7659       errmsg ("missing interface name or sw_if_index");
7660       return -99;
7661     }
7662
7663   if (vlan_id_set == 0)
7664     {
7665       errmsg ("missing vlan_id");
7666       return -99;
7667     }
7668   M (CREATE_VLAN_SUBIF, mp);
7669
7670   mp->sw_if_index = ntohl (sw_if_index);
7671   mp->vlan_id = ntohl (vlan_id);
7672
7673   S (mp);
7674   W (ret);
7675   return ret;
7676 }
7677
7678 #define foreach_create_subif_bit                \
7679 _(no_tags)                                      \
7680 _(one_tag)                                      \
7681 _(two_tags)                                     \
7682 _(dot1ad)                                       \
7683 _(exact_match)                                  \
7684 _(default_sub)                                  \
7685 _(outer_vlan_id_any)                            \
7686 _(inner_vlan_id_any)
7687
7688 static int
7689 api_create_subif (vat_main_t * vam)
7690 {
7691   unformat_input_t *i = vam->input;
7692   vl_api_create_subif_t *mp;
7693   u32 sw_if_index;
7694   u8 sw_if_index_set = 0;
7695   u32 sub_id;
7696   u8 sub_id_set = 0;
7697   u32 no_tags = 0;
7698   u32 one_tag = 0;
7699   u32 two_tags = 0;
7700   u32 dot1ad = 0;
7701   u32 exact_match = 0;
7702   u32 default_sub = 0;
7703   u32 outer_vlan_id_any = 0;
7704   u32 inner_vlan_id_any = 0;
7705   u32 tmp;
7706   u16 outer_vlan_id = 0;
7707   u16 inner_vlan_id = 0;
7708   int ret;
7709
7710   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7711     {
7712       if (unformat (i, "sw_if_index %d", &sw_if_index))
7713         sw_if_index_set = 1;
7714       else
7715         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7716         sw_if_index_set = 1;
7717       else if (unformat (i, "sub_id %d", &sub_id))
7718         sub_id_set = 1;
7719       else if (unformat (i, "outer_vlan_id %d", &tmp))
7720         outer_vlan_id = tmp;
7721       else if (unformat (i, "inner_vlan_id %d", &tmp))
7722         inner_vlan_id = tmp;
7723
7724 #define _(a) else if (unformat (i, #a)) a = 1 ;
7725       foreach_create_subif_bit
7726 #undef _
7727         else
7728         {
7729           clib_warning ("parse error '%U'", format_unformat_error, i);
7730           return -99;
7731         }
7732     }
7733
7734   if (sw_if_index_set == 0)
7735     {
7736       errmsg ("missing interface name or sw_if_index");
7737       return -99;
7738     }
7739
7740   if (sub_id_set == 0)
7741     {
7742       errmsg ("missing sub_id");
7743       return -99;
7744     }
7745   M (CREATE_SUBIF, mp);
7746
7747   mp->sw_if_index = ntohl (sw_if_index);
7748   mp->sub_id = ntohl (sub_id);
7749
7750 #define _(a) mp->a = a;
7751   foreach_create_subif_bit;
7752 #undef _
7753
7754   mp->outer_vlan_id = ntohs (outer_vlan_id);
7755   mp->inner_vlan_id = ntohs (inner_vlan_id);
7756
7757   S (mp);
7758   W (ret);
7759   return ret;
7760 }
7761
7762 static int
7763 api_oam_add_del (vat_main_t * vam)
7764 {
7765   unformat_input_t *i = vam->input;
7766   vl_api_oam_add_del_t *mp;
7767   u32 vrf_id = 0;
7768   u8 is_add = 1;
7769   ip4_address_t src, dst;
7770   u8 src_set = 0;
7771   u8 dst_set = 0;
7772   int ret;
7773
7774   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7775     {
7776       if (unformat (i, "vrf %d", &vrf_id))
7777         ;
7778       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7779         src_set = 1;
7780       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7781         dst_set = 1;
7782       else if (unformat (i, "del"))
7783         is_add = 0;
7784       else
7785         {
7786           clib_warning ("parse error '%U'", format_unformat_error, i);
7787           return -99;
7788         }
7789     }
7790
7791   if (src_set == 0)
7792     {
7793       errmsg ("missing src addr");
7794       return -99;
7795     }
7796
7797   if (dst_set == 0)
7798     {
7799       errmsg ("missing dst addr");
7800       return -99;
7801     }
7802
7803   M (OAM_ADD_DEL, mp);
7804
7805   mp->vrf_id = ntohl (vrf_id);
7806   mp->is_add = is_add;
7807   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7808   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7809
7810   S (mp);
7811   W (ret);
7812   return ret;
7813 }
7814
7815 static int
7816 api_reset_fib (vat_main_t * vam)
7817 {
7818   unformat_input_t *i = vam->input;
7819   vl_api_reset_fib_t *mp;
7820   u32 vrf_id = 0;
7821   u8 is_ipv6 = 0;
7822   u8 vrf_id_set = 0;
7823
7824   int ret;
7825   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7826     {
7827       if (unformat (i, "vrf %d", &vrf_id))
7828         vrf_id_set = 1;
7829       else if (unformat (i, "ipv6"))
7830         is_ipv6 = 1;
7831       else
7832         {
7833           clib_warning ("parse error '%U'", format_unformat_error, i);
7834           return -99;
7835         }
7836     }
7837
7838   if (vrf_id_set == 0)
7839     {
7840       errmsg ("missing vrf id");
7841       return -99;
7842     }
7843
7844   M (RESET_FIB, mp);
7845
7846   mp->vrf_id = ntohl (vrf_id);
7847   mp->is_ipv6 = is_ipv6;
7848
7849   S (mp);
7850   W (ret);
7851   return ret;
7852 }
7853
7854 static int
7855 api_dhcp_proxy_config (vat_main_t * vam)
7856 {
7857   unformat_input_t *i = vam->input;
7858   vl_api_dhcp_proxy_config_t *mp;
7859   u32 rx_vrf_id = 0;
7860   u32 server_vrf_id = 0;
7861   u8 is_add = 1;
7862   u8 v4_address_set = 0;
7863   u8 v6_address_set = 0;
7864   ip4_address_t v4address;
7865   ip6_address_t v6address;
7866   u8 v4_src_address_set = 0;
7867   u8 v6_src_address_set = 0;
7868   ip4_address_t v4srcaddress;
7869   ip6_address_t v6srcaddress;
7870   int ret;
7871
7872   /* Parse args required to build the message */
7873   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7874     {
7875       if (unformat (i, "del"))
7876         is_add = 0;
7877       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7878         ;
7879       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7880         ;
7881       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7882         v4_address_set = 1;
7883       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7884         v6_address_set = 1;
7885       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7886         v4_src_address_set = 1;
7887       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7888         v6_src_address_set = 1;
7889       else
7890         break;
7891     }
7892
7893   if (v4_address_set && v6_address_set)
7894     {
7895       errmsg ("both v4 and v6 server addresses set");
7896       return -99;
7897     }
7898   if (!v4_address_set && !v6_address_set)
7899     {
7900       errmsg ("no server addresses set");
7901       return -99;
7902     }
7903
7904   if (v4_src_address_set && v6_src_address_set)
7905     {
7906       errmsg ("both v4 and v6  src addresses set");
7907       return -99;
7908     }
7909   if (!v4_src_address_set && !v6_src_address_set)
7910     {
7911       errmsg ("no src addresses set");
7912       return -99;
7913     }
7914
7915   if (!(v4_src_address_set && v4_address_set) &&
7916       !(v6_src_address_set && v6_address_set))
7917     {
7918       errmsg ("no matching server and src addresses set");
7919       return -99;
7920     }
7921
7922   /* Construct the API message */
7923   M (DHCP_PROXY_CONFIG, mp);
7924
7925   mp->is_add = is_add;
7926   mp->rx_vrf_id = ntohl (rx_vrf_id);
7927   mp->server_vrf_id = ntohl (server_vrf_id);
7928   if (v6_address_set)
7929     {
7930       mp->is_ipv6 = 1;
7931       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7932       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7933     }
7934   else
7935     {
7936       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7937       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7938     }
7939
7940   /* send it... */
7941   S (mp);
7942
7943   /* Wait for a reply, return good/bad news  */
7944   W (ret);
7945   return ret;
7946 }
7947
7948 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
7949 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
7950
7951 static void
7952 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
7953 {
7954   vat_main_t *vam = &vat_main;
7955   u32 i, count = mp->count;
7956   vl_api_dhcp_server_t *s;
7957
7958   if (mp->is_ipv6)
7959     print (vam->ofp,
7960            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7961            ntohl (mp->rx_vrf_id),
7962            format_ip6_address, mp->dhcp_src_address,
7963            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7964   else
7965     print (vam->ofp,
7966            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7967            ntohl (mp->rx_vrf_id),
7968            format_ip4_address, mp->dhcp_src_address,
7969            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7970
7971   for (i = 0; i < count; i++)
7972     {
7973       s = &mp->servers[i];
7974
7975       if (mp->is_ipv6)
7976         print (vam->ofp,
7977                " Server Table-ID %d, Server Address %U",
7978                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
7979       else
7980         print (vam->ofp,
7981                " Server Table-ID %d, Server Address %U",
7982                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
7983     }
7984 }
7985
7986 static void vl_api_dhcp_proxy_details_t_handler_json
7987   (vl_api_dhcp_proxy_details_t * mp)
7988 {
7989   vat_main_t *vam = &vat_main;
7990   vat_json_node_t *node = NULL;
7991   u32 i, count = mp->count;
7992   struct in_addr ip4;
7993   struct in6_addr ip6;
7994   vl_api_dhcp_server_t *s;
7995
7996   if (VAT_JSON_ARRAY != vam->json_tree.type)
7997     {
7998       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7999       vat_json_init_array (&vam->json_tree);
8000     }
8001   node = vat_json_array_add (&vam->json_tree);
8002
8003   vat_json_init_object (node);
8004   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
8005   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
8006   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
8007
8008   if (mp->is_ipv6)
8009     {
8010       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
8011       vat_json_object_add_ip6 (node, "src_address", ip6);
8012     }
8013   else
8014     {
8015       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
8016       vat_json_object_add_ip4 (node, "src_address", ip4);
8017     }
8018
8019   for (i = 0; i < count; i++)
8020     {
8021       s = &mp->servers[i];
8022
8023       vat_json_object_add_uint (node, "server-table-id",
8024                                 ntohl (s->server_vrf_id));
8025
8026       if (mp->is_ipv6)
8027         {
8028           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
8029           vat_json_object_add_ip4 (node, "src_address", ip4);
8030         }
8031       else
8032         {
8033           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
8034           vat_json_object_add_ip6 (node, "server_address", ip6);
8035         }
8036     }
8037 }
8038
8039 static int
8040 api_dhcp_proxy_dump (vat_main_t * vam)
8041 {
8042   unformat_input_t *i = vam->input;
8043   vl_api_control_ping_t *mp_ping;
8044   vl_api_dhcp_proxy_dump_t *mp;
8045   u8 is_ipv6 = 0;
8046   int ret;
8047
8048   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8049     {
8050       if (unformat (i, "ipv6"))
8051         is_ipv6 = 1;
8052       else
8053         {
8054           clib_warning ("parse error '%U'", format_unformat_error, i);
8055           return -99;
8056         }
8057     }
8058
8059   M (DHCP_PROXY_DUMP, mp);
8060
8061   mp->is_ip6 = is_ipv6;
8062   S (mp);
8063
8064   /* Use a control ping for synchronization */
8065   M (CONTROL_PING, mp_ping);
8066   S (mp_ping);
8067
8068   W (ret);
8069   return ret;
8070 }
8071
8072 static int
8073 api_dhcp_proxy_set_vss (vat_main_t * vam)
8074 {
8075   unformat_input_t *i = vam->input;
8076   vl_api_dhcp_proxy_set_vss_t *mp;
8077   u8 is_ipv6 = 0;
8078   u8 is_add = 1;
8079   u32 tbl_id;
8080   u8 tbl_id_set = 0;
8081   u32 oui;
8082   u8 oui_set = 0;
8083   u32 fib_id;
8084   u8 fib_id_set = 0;
8085   int ret;
8086
8087   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8088     {
8089       if (unformat (i, "tbl_id %d", &tbl_id))
8090         tbl_id_set = 1;
8091       if (unformat (i, "fib_id %d", &fib_id))
8092         fib_id_set = 1;
8093       if (unformat (i, "oui %d", &oui))
8094         oui_set = 1;
8095       else if (unformat (i, "ipv6"))
8096         is_ipv6 = 1;
8097       else if (unformat (i, "del"))
8098         is_add = 0;
8099       else
8100         {
8101           clib_warning ("parse error '%U'", format_unformat_error, i);
8102           return -99;
8103         }
8104     }
8105
8106   if (tbl_id_set == 0)
8107     {
8108       errmsg ("missing tbl id");
8109       return -99;
8110     }
8111
8112   if (fib_id_set == 0)
8113     {
8114       errmsg ("missing fib id");
8115       return -99;
8116     }
8117   if (oui_set == 0)
8118     {
8119       errmsg ("missing oui");
8120       return -99;
8121     }
8122
8123   M (DHCP_PROXY_SET_VSS, mp);
8124   mp->tbl_id = ntohl (tbl_id);
8125   mp->fib_id = ntohl (fib_id);
8126   mp->oui = ntohl (oui);
8127   mp->is_ipv6 = is_ipv6;
8128   mp->is_add = is_add;
8129
8130   S (mp);
8131   W (ret);
8132   return ret;
8133 }
8134
8135 static int
8136 api_dhcp_client_config (vat_main_t * vam)
8137 {
8138   unformat_input_t *i = vam->input;
8139   vl_api_dhcp_client_config_t *mp;
8140   u32 sw_if_index;
8141   u8 sw_if_index_set = 0;
8142   u8 is_add = 1;
8143   u8 *hostname = 0;
8144   u8 disable_event = 0;
8145   int ret;
8146
8147   /* Parse args required to build the message */
8148   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8149     {
8150       if (unformat (i, "del"))
8151         is_add = 0;
8152       else
8153         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8154         sw_if_index_set = 1;
8155       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8156         sw_if_index_set = 1;
8157       else if (unformat (i, "hostname %s", &hostname))
8158         ;
8159       else if (unformat (i, "disable_event"))
8160         disable_event = 1;
8161       else
8162         break;
8163     }
8164
8165   if (sw_if_index_set == 0)
8166     {
8167       errmsg ("missing interface name or sw_if_index");
8168       return -99;
8169     }
8170
8171   if (vec_len (hostname) > 63)
8172     {
8173       errmsg ("hostname too long");
8174     }
8175   vec_add1 (hostname, 0);
8176
8177   /* Construct the API message */
8178   M (DHCP_CLIENT_CONFIG, mp);
8179
8180   mp->sw_if_index = htonl (sw_if_index);
8181   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
8182   vec_free (hostname);
8183   mp->is_add = is_add;
8184   mp->want_dhcp_event = disable_event ? 0 : 1;
8185   mp->pid = htonl (getpid ());
8186
8187   /* send it... */
8188   S (mp);
8189
8190   /* Wait for a reply, return good/bad news  */
8191   W (ret);
8192   return ret;
8193 }
8194
8195 static int
8196 api_set_ip_flow_hash (vat_main_t * vam)
8197 {
8198   unformat_input_t *i = vam->input;
8199   vl_api_set_ip_flow_hash_t *mp;
8200   u32 vrf_id = 0;
8201   u8 is_ipv6 = 0;
8202   u8 vrf_id_set = 0;
8203   u8 src = 0;
8204   u8 dst = 0;
8205   u8 sport = 0;
8206   u8 dport = 0;
8207   u8 proto = 0;
8208   u8 reverse = 0;
8209   int ret;
8210
8211   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8212     {
8213       if (unformat (i, "vrf %d", &vrf_id))
8214         vrf_id_set = 1;
8215       else if (unformat (i, "ipv6"))
8216         is_ipv6 = 1;
8217       else if (unformat (i, "src"))
8218         src = 1;
8219       else if (unformat (i, "dst"))
8220         dst = 1;
8221       else if (unformat (i, "sport"))
8222         sport = 1;
8223       else if (unformat (i, "dport"))
8224         dport = 1;
8225       else if (unformat (i, "proto"))
8226         proto = 1;
8227       else if (unformat (i, "reverse"))
8228         reverse = 1;
8229
8230       else
8231         {
8232           clib_warning ("parse error '%U'", format_unformat_error, i);
8233           return -99;
8234         }
8235     }
8236
8237   if (vrf_id_set == 0)
8238     {
8239       errmsg ("missing vrf id");
8240       return -99;
8241     }
8242
8243   M (SET_IP_FLOW_HASH, mp);
8244   mp->src = src;
8245   mp->dst = dst;
8246   mp->sport = sport;
8247   mp->dport = dport;
8248   mp->proto = proto;
8249   mp->reverse = reverse;
8250   mp->vrf_id = ntohl (vrf_id);
8251   mp->is_ipv6 = is_ipv6;
8252
8253   S (mp);
8254   W (ret);
8255   return ret;
8256 }
8257
8258 static int
8259 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
8260 {
8261   unformat_input_t *i = vam->input;
8262   vl_api_sw_interface_ip6_enable_disable_t *mp;
8263   u32 sw_if_index;
8264   u8 sw_if_index_set = 0;
8265   u8 enable = 0;
8266   int ret;
8267
8268   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8269     {
8270       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8271         sw_if_index_set = 1;
8272       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8273         sw_if_index_set = 1;
8274       else if (unformat (i, "enable"))
8275         enable = 1;
8276       else if (unformat (i, "disable"))
8277         enable = 0;
8278       else
8279         {
8280           clib_warning ("parse error '%U'", format_unformat_error, i);
8281           return -99;
8282         }
8283     }
8284
8285   if (sw_if_index_set == 0)
8286     {
8287       errmsg ("missing interface name or sw_if_index");
8288       return -99;
8289     }
8290
8291   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
8292
8293   mp->sw_if_index = ntohl (sw_if_index);
8294   mp->enable = enable;
8295
8296   S (mp);
8297   W (ret);
8298   return ret;
8299 }
8300
8301 static int
8302 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
8303 {
8304   unformat_input_t *i = vam->input;
8305   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
8306   u32 sw_if_index;
8307   u8 sw_if_index_set = 0;
8308   u8 v6_address_set = 0;
8309   ip6_address_t v6address;
8310   int ret;
8311
8312   /* Parse args required to build the message */
8313   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8314     {
8315       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8316         sw_if_index_set = 1;
8317       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8318         sw_if_index_set = 1;
8319       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8320         v6_address_set = 1;
8321       else
8322         break;
8323     }
8324
8325   if (sw_if_index_set == 0)
8326     {
8327       errmsg ("missing interface name or sw_if_index");
8328       return -99;
8329     }
8330   if (!v6_address_set)
8331     {
8332       errmsg ("no address set");
8333       return -99;
8334     }
8335
8336   /* Construct the API message */
8337   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
8338
8339   mp->sw_if_index = ntohl (sw_if_index);
8340   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8341
8342   /* send it... */
8343   S (mp);
8344
8345   /* Wait for a reply, return good/bad news  */
8346   W (ret);
8347   return ret;
8348 }
8349
8350 static int
8351 api_ip6nd_proxy_add_del (vat_main_t * vam)
8352 {
8353   unformat_input_t *i = vam->input;
8354   vl_api_ip6nd_proxy_add_del_t *mp;
8355   u32 sw_if_index = ~0;
8356   u8 v6_address_set = 0;
8357   ip6_address_t v6address;
8358   u8 is_del = 0;
8359   int ret;
8360
8361   /* Parse args required to build the message */
8362   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8363     {
8364       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8365         ;
8366       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8367         ;
8368       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8369         v6_address_set = 1;
8370       if (unformat (i, "del"))
8371         is_del = 1;
8372       else
8373         {
8374           clib_warning ("parse error '%U'", format_unformat_error, i);
8375           return -99;
8376         }
8377     }
8378
8379   if (sw_if_index == ~0)
8380     {
8381       errmsg ("missing interface name or sw_if_index");
8382       return -99;
8383     }
8384   if (!v6_address_set)
8385     {
8386       errmsg ("no address set");
8387       return -99;
8388     }
8389
8390   /* Construct the API message */
8391   M (IP6ND_PROXY_ADD_DEL, mp);
8392
8393   mp->is_del = is_del;
8394   mp->sw_if_index = ntohl (sw_if_index);
8395   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8396
8397   /* send it... */
8398   S (mp);
8399
8400   /* Wait for a reply, return good/bad news  */
8401   W (ret);
8402   return ret;
8403 }
8404
8405 static int
8406 api_ip6nd_proxy_dump (vat_main_t * vam)
8407 {
8408   vl_api_ip6nd_proxy_dump_t *mp;
8409   vl_api_control_ping_t *mp_ping;
8410   int ret;
8411
8412   M (IP6ND_PROXY_DUMP, mp);
8413
8414   S (mp);
8415
8416   /* Use a control ping for synchronization */
8417   M (CONTROL_PING, mp_ping);
8418   S (mp_ping);
8419
8420   W (ret);
8421   return ret;
8422 }
8423
8424 static void vl_api_ip6nd_proxy_details_t_handler
8425   (vl_api_ip6nd_proxy_details_t * mp)
8426 {
8427   vat_main_t *vam = &vat_main;
8428
8429   print (vam->ofp, "host %U sw_if_index %d",
8430          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
8431 }
8432
8433 static void vl_api_ip6nd_proxy_details_t_handler_json
8434   (vl_api_ip6nd_proxy_details_t * mp)
8435 {
8436   vat_main_t *vam = &vat_main;
8437   struct in6_addr ip6;
8438   vat_json_node_t *node = NULL;
8439
8440   if (VAT_JSON_ARRAY != vam->json_tree.type)
8441     {
8442       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8443       vat_json_init_array (&vam->json_tree);
8444     }
8445   node = vat_json_array_add (&vam->json_tree);
8446
8447   vat_json_init_object (node);
8448   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
8449
8450   clib_memcpy (&ip6, mp->address, sizeof (ip6));
8451   vat_json_object_add_ip6 (node, "host", ip6);
8452 }
8453
8454 static int
8455 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
8456 {
8457   unformat_input_t *i = vam->input;
8458   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
8459   u32 sw_if_index;
8460   u8 sw_if_index_set = 0;
8461   u32 address_length = 0;
8462   u8 v6_address_set = 0;
8463   ip6_address_t v6address;
8464   u8 use_default = 0;
8465   u8 no_advertise = 0;
8466   u8 off_link = 0;
8467   u8 no_autoconfig = 0;
8468   u8 no_onlink = 0;
8469   u8 is_no = 0;
8470   u32 val_lifetime = 0;
8471   u32 pref_lifetime = 0;
8472   int ret;
8473
8474   /* Parse args required to build the message */
8475   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8476     {
8477       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8478         sw_if_index_set = 1;
8479       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8480         sw_if_index_set = 1;
8481       else if (unformat (i, "%U/%d",
8482                          unformat_ip6_address, &v6address, &address_length))
8483         v6_address_set = 1;
8484       else if (unformat (i, "val_life %d", &val_lifetime))
8485         ;
8486       else if (unformat (i, "pref_life %d", &pref_lifetime))
8487         ;
8488       else if (unformat (i, "def"))
8489         use_default = 1;
8490       else if (unformat (i, "noadv"))
8491         no_advertise = 1;
8492       else if (unformat (i, "offl"))
8493         off_link = 1;
8494       else if (unformat (i, "noauto"))
8495         no_autoconfig = 1;
8496       else if (unformat (i, "nolink"))
8497         no_onlink = 1;
8498       else if (unformat (i, "isno"))
8499         is_no = 1;
8500       else
8501         {
8502           clib_warning ("parse error '%U'", format_unformat_error, i);
8503           return -99;
8504         }
8505     }
8506
8507   if (sw_if_index_set == 0)
8508     {
8509       errmsg ("missing interface name or sw_if_index");
8510       return -99;
8511     }
8512   if (!v6_address_set)
8513     {
8514       errmsg ("no address set");
8515       return -99;
8516     }
8517
8518   /* Construct the API message */
8519   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
8520
8521   mp->sw_if_index = ntohl (sw_if_index);
8522   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8523   mp->address_length = address_length;
8524   mp->use_default = use_default;
8525   mp->no_advertise = no_advertise;
8526   mp->off_link = off_link;
8527   mp->no_autoconfig = no_autoconfig;
8528   mp->no_onlink = no_onlink;
8529   mp->is_no = is_no;
8530   mp->val_lifetime = ntohl (val_lifetime);
8531   mp->pref_lifetime = ntohl (pref_lifetime);
8532
8533   /* send it... */
8534   S (mp);
8535
8536   /* Wait for a reply, return good/bad news  */
8537   W (ret);
8538   return ret;
8539 }
8540
8541 static int
8542 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
8543 {
8544   unformat_input_t *i = vam->input;
8545   vl_api_sw_interface_ip6nd_ra_config_t *mp;
8546   u32 sw_if_index;
8547   u8 sw_if_index_set = 0;
8548   u8 suppress = 0;
8549   u8 managed = 0;
8550   u8 other = 0;
8551   u8 ll_option = 0;
8552   u8 send_unicast = 0;
8553   u8 cease = 0;
8554   u8 is_no = 0;
8555   u8 default_router = 0;
8556   u32 max_interval = 0;
8557   u32 min_interval = 0;
8558   u32 lifetime = 0;
8559   u32 initial_count = 0;
8560   u32 initial_interval = 0;
8561   int ret;
8562
8563
8564   /* Parse args required to build the message */
8565   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8566     {
8567       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8568         sw_if_index_set = 1;
8569       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8570         sw_if_index_set = 1;
8571       else if (unformat (i, "maxint %d", &max_interval))
8572         ;
8573       else if (unformat (i, "minint %d", &min_interval))
8574         ;
8575       else if (unformat (i, "life %d", &lifetime))
8576         ;
8577       else if (unformat (i, "count %d", &initial_count))
8578         ;
8579       else if (unformat (i, "interval %d", &initial_interval))
8580         ;
8581       else if (unformat (i, "suppress") || unformat (i, "surpress"))
8582         suppress = 1;
8583       else if (unformat (i, "managed"))
8584         managed = 1;
8585       else if (unformat (i, "other"))
8586         other = 1;
8587       else if (unformat (i, "ll"))
8588         ll_option = 1;
8589       else if (unformat (i, "send"))
8590         send_unicast = 1;
8591       else if (unformat (i, "cease"))
8592         cease = 1;
8593       else if (unformat (i, "isno"))
8594         is_no = 1;
8595       else if (unformat (i, "def"))
8596         default_router = 1;
8597       else
8598         {
8599           clib_warning ("parse error '%U'", format_unformat_error, i);
8600           return -99;
8601         }
8602     }
8603
8604   if (sw_if_index_set == 0)
8605     {
8606       errmsg ("missing interface name or sw_if_index");
8607       return -99;
8608     }
8609
8610   /* Construct the API message */
8611   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
8612
8613   mp->sw_if_index = ntohl (sw_if_index);
8614   mp->max_interval = ntohl (max_interval);
8615   mp->min_interval = ntohl (min_interval);
8616   mp->lifetime = ntohl (lifetime);
8617   mp->initial_count = ntohl (initial_count);
8618   mp->initial_interval = ntohl (initial_interval);
8619   mp->suppress = suppress;
8620   mp->managed = managed;
8621   mp->other = other;
8622   mp->ll_option = ll_option;
8623   mp->send_unicast = send_unicast;
8624   mp->cease = cease;
8625   mp->is_no = is_no;
8626   mp->default_router = default_router;
8627
8628   /* send it... */
8629   S (mp);
8630
8631   /* Wait for a reply, return good/bad news  */
8632   W (ret);
8633   return ret;
8634 }
8635
8636 static int
8637 api_set_arp_neighbor_limit (vat_main_t * vam)
8638 {
8639   unformat_input_t *i = vam->input;
8640   vl_api_set_arp_neighbor_limit_t *mp;
8641   u32 arp_nbr_limit;
8642   u8 limit_set = 0;
8643   u8 is_ipv6 = 0;
8644   int ret;
8645
8646   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8647     {
8648       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
8649         limit_set = 1;
8650       else if (unformat (i, "ipv6"))
8651         is_ipv6 = 1;
8652       else
8653         {
8654           clib_warning ("parse error '%U'", format_unformat_error, i);
8655           return -99;
8656         }
8657     }
8658
8659   if (limit_set == 0)
8660     {
8661       errmsg ("missing limit value");
8662       return -99;
8663     }
8664
8665   M (SET_ARP_NEIGHBOR_LIMIT, mp);
8666
8667   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
8668   mp->is_ipv6 = is_ipv6;
8669
8670   S (mp);
8671   W (ret);
8672   return ret;
8673 }
8674
8675 static int
8676 api_l2_patch_add_del (vat_main_t * vam)
8677 {
8678   unformat_input_t *i = vam->input;
8679   vl_api_l2_patch_add_del_t *mp;
8680   u32 rx_sw_if_index;
8681   u8 rx_sw_if_index_set = 0;
8682   u32 tx_sw_if_index;
8683   u8 tx_sw_if_index_set = 0;
8684   u8 is_add = 1;
8685   int ret;
8686
8687   /* Parse args required to build the message */
8688   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8689     {
8690       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
8691         rx_sw_if_index_set = 1;
8692       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
8693         tx_sw_if_index_set = 1;
8694       else if (unformat (i, "rx"))
8695         {
8696           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8697             {
8698               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8699                             &rx_sw_if_index))
8700                 rx_sw_if_index_set = 1;
8701             }
8702           else
8703             break;
8704         }
8705       else if (unformat (i, "tx"))
8706         {
8707           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8708             {
8709               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8710                             &tx_sw_if_index))
8711                 tx_sw_if_index_set = 1;
8712             }
8713           else
8714             break;
8715         }
8716       else if (unformat (i, "del"))
8717         is_add = 0;
8718       else
8719         break;
8720     }
8721
8722   if (rx_sw_if_index_set == 0)
8723     {
8724       errmsg ("missing rx interface name or rx_sw_if_index");
8725       return -99;
8726     }
8727
8728   if (tx_sw_if_index_set == 0)
8729     {
8730       errmsg ("missing tx interface name or tx_sw_if_index");
8731       return -99;
8732     }
8733
8734   M (L2_PATCH_ADD_DEL, mp);
8735
8736   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
8737   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
8738   mp->is_add = is_add;
8739
8740   S (mp);
8741   W (ret);
8742   return ret;
8743 }
8744
8745 u8 is_del;
8746 u8 localsid_addr[16];
8747 u8 end_psp;
8748 u8 behavior;
8749 u32 sw_if_index;
8750 u32 vlan_index;
8751 u32 fib_table;
8752 u8 nh_addr[16];
8753
8754 static int
8755 api_sr_localsid_add_del (vat_main_t * vam)
8756 {
8757   unformat_input_t *i = vam->input;
8758   vl_api_sr_localsid_add_del_t *mp;
8759
8760   u8 is_del;
8761   ip6_address_t localsid;
8762   u8 end_psp = 0;
8763   u8 behavior = ~0;
8764   u32 sw_if_index;
8765   u32 fib_table = ~(u32) 0;
8766   ip6_address_t next_hop;
8767
8768   bool nexthop_set = 0;
8769
8770   int ret;
8771
8772   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8773     {
8774       if (unformat (i, "del"))
8775         is_del = 1;
8776       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
8777       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
8778         nexthop_set = 1;
8779       else if (unformat (i, "behavior %u", &behavior));
8780       else if (unformat (i, "sw_if_index %u", &sw_if_index));
8781       else if (unformat (i, "fib-table %u", &fib_table));
8782       else if (unformat (i, "end.psp %u", &behavior));
8783       else
8784         break;
8785     }
8786
8787   M (SR_LOCALSID_ADD_DEL, mp);
8788
8789   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
8790   if (nexthop_set)
8791     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
8792   mp->behavior = behavior;
8793   mp->sw_if_index = ntohl (sw_if_index);
8794   mp->fib_table = ntohl (fib_table);
8795   mp->end_psp = end_psp;
8796   mp->is_del = is_del;
8797
8798   S (mp);
8799   W (ret);
8800   return ret;
8801 }
8802
8803 static int
8804 api_ioam_enable (vat_main_t * vam)
8805 {
8806   unformat_input_t *input = vam->input;
8807   vl_api_ioam_enable_t *mp;
8808   u32 id = 0;
8809   int has_trace_option = 0;
8810   int has_pot_option = 0;
8811   int has_seqno_option = 0;
8812   int has_analyse_option = 0;
8813   int ret;
8814
8815   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8816     {
8817       if (unformat (input, "trace"))
8818         has_trace_option = 1;
8819       else if (unformat (input, "pot"))
8820         has_pot_option = 1;
8821       else if (unformat (input, "seqno"))
8822         has_seqno_option = 1;
8823       else if (unformat (input, "analyse"))
8824         has_analyse_option = 1;
8825       else
8826         break;
8827     }
8828   M (IOAM_ENABLE, mp);
8829   mp->id = htons (id);
8830   mp->seqno = has_seqno_option;
8831   mp->analyse = has_analyse_option;
8832   mp->pot_enable = has_pot_option;
8833   mp->trace_enable = has_trace_option;
8834
8835   S (mp);
8836   W (ret);
8837   return ret;
8838 }
8839
8840
8841 static int
8842 api_ioam_disable (vat_main_t * vam)
8843 {
8844   vl_api_ioam_disable_t *mp;
8845   int ret;
8846
8847   M (IOAM_DISABLE, mp);
8848   S (mp);
8849   W (ret);
8850   return ret;
8851 }
8852
8853 #define foreach_tcp_proto_field                 \
8854 _(src_port)                                     \
8855 _(dst_port)
8856
8857 #define foreach_udp_proto_field                 \
8858 _(src_port)                                     \
8859 _(dst_port)
8860
8861 #define foreach_ip4_proto_field                 \
8862 _(src_address)                                  \
8863 _(dst_address)                                  \
8864 _(tos)                                          \
8865 _(length)                                       \
8866 _(fragment_id)                                  \
8867 _(ttl)                                          \
8868 _(protocol)                                     \
8869 _(checksum)
8870
8871 typedef struct
8872 {
8873   u16 src_port, dst_port;
8874 } tcpudp_header_t;
8875
8876 #if VPP_API_TEST_BUILTIN == 0
8877 uword
8878 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8879 {
8880   u8 **maskp = va_arg (*args, u8 **);
8881   u8 *mask = 0;
8882   u8 found_something = 0;
8883   tcp_header_t *tcp;
8884
8885 #define _(a) u8 a=0;
8886   foreach_tcp_proto_field;
8887 #undef _
8888
8889   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8890     {
8891       if (0);
8892 #define _(a) else if (unformat (input, #a)) a=1;
8893       foreach_tcp_proto_field
8894 #undef _
8895         else
8896         break;
8897     }
8898
8899 #define _(a) found_something += a;
8900   foreach_tcp_proto_field;
8901 #undef _
8902
8903   if (found_something == 0)
8904     return 0;
8905
8906   vec_validate (mask, sizeof (*tcp) - 1);
8907
8908   tcp = (tcp_header_t *) mask;
8909
8910 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8911   foreach_tcp_proto_field;
8912 #undef _
8913
8914   *maskp = mask;
8915   return 1;
8916 }
8917
8918 uword
8919 unformat_udp_mask (unformat_input_t * input, va_list * args)
8920 {
8921   u8 **maskp = va_arg (*args, u8 **);
8922   u8 *mask = 0;
8923   u8 found_something = 0;
8924   udp_header_t *udp;
8925
8926 #define _(a) u8 a=0;
8927   foreach_udp_proto_field;
8928 #undef _
8929
8930   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8931     {
8932       if (0);
8933 #define _(a) else if (unformat (input, #a)) a=1;
8934       foreach_udp_proto_field
8935 #undef _
8936         else
8937         break;
8938     }
8939
8940 #define _(a) found_something += a;
8941   foreach_udp_proto_field;
8942 #undef _
8943
8944   if (found_something == 0)
8945     return 0;
8946
8947   vec_validate (mask, sizeof (*udp) - 1);
8948
8949   udp = (udp_header_t *) mask;
8950
8951 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8952   foreach_udp_proto_field;
8953 #undef _
8954
8955   *maskp = mask;
8956   return 1;
8957 }
8958
8959 uword
8960 unformat_l4_mask (unformat_input_t * input, va_list * args)
8961 {
8962   u8 **maskp = va_arg (*args, u8 **);
8963   u16 src_port = 0, dst_port = 0;
8964   tcpudp_header_t *tcpudp;
8965
8966   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8967     {
8968       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8969         return 1;
8970       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8971         return 1;
8972       else if (unformat (input, "src_port"))
8973         src_port = 0xFFFF;
8974       else if (unformat (input, "dst_port"))
8975         dst_port = 0xFFFF;
8976       else
8977         return 0;
8978     }
8979
8980   if (!src_port && !dst_port)
8981     return 0;
8982
8983   u8 *mask = 0;
8984   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8985
8986   tcpudp = (tcpudp_header_t *) mask;
8987   tcpudp->src_port = src_port;
8988   tcpudp->dst_port = dst_port;
8989
8990   *maskp = mask;
8991
8992   return 1;
8993 }
8994
8995 uword
8996 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8997 {
8998   u8 **maskp = va_arg (*args, u8 **);
8999   u8 *mask = 0;
9000   u8 found_something = 0;
9001   ip4_header_t *ip;
9002
9003 #define _(a) u8 a=0;
9004   foreach_ip4_proto_field;
9005 #undef _
9006   u8 version = 0;
9007   u8 hdr_length = 0;
9008
9009
9010   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9011     {
9012       if (unformat (input, "version"))
9013         version = 1;
9014       else if (unformat (input, "hdr_length"))
9015         hdr_length = 1;
9016       else if (unformat (input, "src"))
9017         src_address = 1;
9018       else if (unformat (input, "dst"))
9019         dst_address = 1;
9020       else if (unformat (input, "proto"))
9021         protocol = 1;
9022
9023 #define _(a) else if (unformat (input, #a)) a=1;
9024       foreach_ip4_proto_field
9025 #undef _
9026         else
9027         break;
9028     }
9029
9030 #define _(a) found_something += a;
9031   foreach_ip4_proto_field;
9032 #undef _
9033
9034   if (found_something == 0)
9035     return 0;
9036
9037   vec_validate (mask, sizeof (*ip) - 1);
9038
9039   ip = (ip4_header_t *) mask;
9040
9041 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9042   foreach_ip4_proto_field;
9043 #undef _
9044
9045   ip->ip_version_and_header_length = 0;
9046
9047   if (version)
9048     ip->ip_version_and_header_length |= 0xF0;
9049
9050   if (hdr_length)
9051     ip->ip_version_and_header_length |= 0x0F;
9052
9053   *maskp = mask;
9054   return 1;
9055 }
9056
9057 #define foreach_ip6_proto_field                 \
9058 _(src_address)                                  \
9059 _(dst_address)                                  \
9060 _(payload_length)                               \
9061 _(hop_limit)                                    \
9062 _(protocol)
9063
9064 uword
9065 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9066 {
9067   u8 **maskp = va_arg (*args, u8 **);
9068   u8 *mask = 0;
9069   u8 found_something = 0;
9070   ip6_header_t *ip;
9071   u32 ip_version_traffic_class_and_flow_label;
9072
9073 #define _(a) u8 a=0;
9074   foreach_ip6_proto_field;
9075 #undef _
9076   u8 version = 0;
9077   u8 traffic_class = 0;
9078   u8 flow_label = 0;
9079
9080   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9081     {
9082       if (unformat (input, "version"))
9083         version = 1;
9084       else if (unformat (input, "traffic-class"))
9085         traffic_class = 1;
9086       else if (unformat (input, "flow-label"))
9087         flow_label = 1;
9088       else if (unformat (input, "src"))
9089         src_address = 1;
9090       else if (unformat (input, "dst"))
9091         dst_address = 1;
9092       else if (unformat (input, "proto"))
9093         protocol = 1;
9094
9095 #define _(a) else if (unformat (input, #a)) a=1;
9096       foreach_ip6_proto_field
9097 #undef _
9098         else
9099         break;
9100     }
9101
9102 #define _(a) found_something += a;
9103   foreach_ip6_proto_field;
9104 #undef _
9105
9106   if (found_something == 0)
9107     return 0;
9108
9109   vec_validate (mask, sizeof (*ip) - 1);
9110
9111   ip = (ip6_header_t *) mask;
9112
9113 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9114   foreach_ip6_proto_field;
9115 #undef _
9116
9117   ip_version_traffic_class_and_flow_label = 0;
9118
9119   if (version)
9120     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9121
9122   if (traffic_class)
9123     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9124
9125   if (flow_label)
9126     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9127
9128   ip->ip_version_traffic_class_and_flow_label =
9129     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9130
9131   *maskp = mask;
9132   return 1;
9133 }
9134
9135 uword
9136 unformat_l3_mask (unformat_input_t * input, va_list * args)
9137 {
9138   u8 **maskp = va_arg (*args, u8 **);
9139
9140   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9141     {
9142       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9143         return 1;
9144       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9145         return 1;
9146       else
9147         break;
9148     }
9149   return 0;
9150 }
9151
9152 uword
9153 unformat_l2_mask (unformat_input_t * input, va_list * args)
9154 {
9155   u8 **maskp = va_arg (*args, u8 **);
9156   u8 *mask = 0;
9157   u8 src = 0;
9158   u8 dst = 0;
9159   u8 proto = 0;
9160   u8 tag1 = 0;
9161   u8 tag2 = 0;
9162   u8 ignore_tag1 = 0;
9163   u8 ignore_tag2 = 0;
9164   u8 cos1 = 0;
9165   u8 cos2 = 0;
9166   u8 dot1q = 0;
9167   u8 dot1ad = 0;
9168   int len = 14;
9169
9170   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9171     {
9172       if (unformat (input, "src"))
9173         src = 1;
9174       else if (unformat (input, "dst"))
9175         dst = 1;
9176       else if (unformat (input, "proto"))
9177         proto = 1;
9178       else if (unformat (input, "tag1"))
9179         tag1 = 1;
9180       else if (unformat (input, "tag2"))
9181         tag2 = 1;
9182       else if (unformat (input, "ignore-tag1"))
9183         ignore_tag1 = 1;
9184       else if (unformat (input, "ignore-tag2"))
9185         ignore_tag2 = 1;
9186       else if (unformat (input, "cos1"))
9187         cos1 = 1;
9188       else if (unformat (input, "cos2"))
9189         cos2 = 1;
9190       else if (unformat (input, "dot1q"))
9191         dot1q = 1;
9192       else if (unformat (input, "dot1ad"))
9193         dot1ad = 1;
9194       else
9195         break;
9196     }
9197   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9198        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9199     return 0;
9200
9201   if (tag1 || ignore_tag1 || cos1 || dot1q)
9202     len = 18;
9203   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9204     len = 22;
9205
9206   vec_validate (mask, len - 1);
9207
9208   if (dst)
9209     memset (mask, 0xff, 6);
9210
9211   if (src)
9212     memset (mask + 6, 0xff, 6);
9213
9214   if (tag2 || dot1ad)
9215     {
9216       /* inner vlan tag */
9217       if (tag2)
9218         {
9219           mask[19] = 0xff;
9220           mask[18] = 0x0f;
9221         }
9222       if (cos2)
9223         mask[18] |= 0xe0;
9224       if (proto)
9225         mask[21] = mask[20] = 0xff;
9226       if (tag1)
9227         {
9228           mask[15] = 0xff;
9229           mask[14] = 0x0f;
9230         }
9231       if (cos1)
9232         mask[14] |= 0xe0;
9233       *maskp = mask;
9234       return 1;
9235     }
9236   if (tag1 | dot1q)
9237     {
9238       if (tag1)
9239         {
9240           mask[15] = 0xff;
9241           mask[14] = 0x0f;
9242         }
9243       if (cos1)
9244         mask[14] |= 0xe0;
9245       if (proto)
9246         mask[16] = mask[17] = 0xff;
9247
9248       *maskp = mask;
9249       return 1;
9250     }
9251   if (cos2)
9252     mask[18] |= 0xe0;
9253   if (cos1)
9254     mask[14] |= 0xe0;
9255   if (proto)
9256     mask[12] = mask[13] = 0xff;
9257
9258   *maskp = mask;
9259   return 1;
9260 }
9261
9262 uword
9263 unformat_classify_mask (unformat_input_t * input, va_list * args)
9264 {
9265   u8 **maskp = va_arg (*args, u8 **);
9266   u32 *skipp = va_arg (*args, u32 *);
9267   u32 *matchp = va_arg (*args, u32 *);
9268   u32 match;
9269   u8 *mask = 0;
9270   u8 *l2 = 0;
9271   u8 *l3 = 0;
9272   u8 *l4 = 0;
9273   int i;
9274
9275   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9276     {
9277       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9278         ;
9279       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9280         ;
9281       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9282         ;
9283       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9284         ;
9285       else
9286         break;
9287     }
9288
9289   if (l4 && !l3)
9290     {
9291       vec_free (mask);
9292       vec_free (l2);
9293       vec_free (l4);
9294       return 0;
9295     }
9296
9297   if (mask || l2 || l3 || l4)
9298     {
9299       if (l2 || l3 || l4)
9300         {
9301           /* "With a free Ethernet header in every package" */
9302           if (l2 == 0)
9303             vec_validate (l2, 13);
9304           mask = l2;
9305           if (vec_len (l3))
9306             {
9307               vec_append (mask, l3);
9308               vec_free (l3);
9309             }
9310           if (vec_len (l4))
9311             {
9312               vec_append (mask, l4);
9313               vec_free (l4);
9314             }
9315         }
9316
9317       /* Scan forward looking for the first significant mask octet */
9318       for (i = 0; i < vec_len (mask); i++)
9319         if (mask[i])
9320           break;
9321
9322       /* compute (skip, match) params */
9323       *skipp = i / sizeof (u32x4);
9324       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9325
9326       /* Pad mask to an even multiple of the vector size */
9327       while (vec_len (mask) % sizeof (u32x4))
9328         vec_add1 (mask, 0);
9329
9330       match = vec_len (mask) / sizeof (u32x4);
9331
9332       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9333         {
9334           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9335           if (*tmp || *(tmp + 1))
9336             break;
9337           match--;
9338         }
9339       if (match == 0)
9340         clib_warning ("BUG: match 0");
9341
9342       _vec_len (mask) = match * sizeof (u32x4);
9343
9344       *matchp = match;
9345       *maskp = mask;
9346
9347       return 1;
9348     }
9349
9350   return 0;
9351 }
9352 #endif /* VPP_API_TEST_BUILTIN */
9353
9354 #define foreach_l2_next                         \
9355 _(drop, DROP)                                   \
9356 _(ethernet, ETHERNET_INPUT)                     \
9357 _(ip4, IP4_INPUT)                               \
9358 _(ip6, IP6_INPUT)
9359
9360 uword
9361 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9362 {
9363   u32 *miss_next_indexp = va_arg (*args, u32 *);
9364   u32 next_index = 0;
9365   u32 tmp;
9366
9367 #define _(n,N) \
9368   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9369   foreach_l2_next;
9370 #undef _
9371
9372   if (unformat (input, "%d", &tmp))
9373     {
9374       next_index = tmp;
9375       goto out;
9376     }
9377
9378   return 0;
9379
9380 out:
9381   *miss_next_indexp = next_index;
9382   return 1;
9383 }
9384
9385 #define foreach_ip_next                         \
9386 _(drop, DROP)                                   \
9387 _(local, LOCAL)                                 \
9388 _(rewrite, REWRITE)
9389
9390 uword
9391 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9392 {
9393   u32 *miss_next_indexp = va_arg (*args, u32 *);
9394   u32 next_index = 0;
9395   u32 tmp;
9396
9397 #define _(n,N) \
9398   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9399   foreach_ip_next;
9400 #undef _
9401
9402   if (unformat (input, "%d", &tmp))
9403     {
9404       next_index = tmp;
9405       goto out;
9406     }
9407
9408   return 0;
9409
9410 out:
9411   *miss_next_indexp = next_index;
9412   return 1;
9413 }
9414
9415 #define foreach_acl_next                        \
9416 _(deny, DENY)
9417
9418 uword
9419 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9420 {
9421   u32 *miss_next_indexp = va_arg (*args, u32 *);
9422   u32 next_index = 0;
9423   u32 tmp;
9424
9425 #define _(n,N) \
9426   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9427   foreach_acl_next;
9428 #undef _
9429
9430   if (unformat (input, "permit"))
9431     {
9432       next_index = ~0;
9433       goto out;
9434     }
9435   else if (unformat (input, "%d", &tmp))
9436     {
9437       next_index = tmp;
9438       goto out;
9439     }
9440
9441   return 0;
9442
9443 out:
9444   *miss_next_indexp = next_index;
9445   return 1;
9446 }
9447
9448 uword
9449 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9450 {
9451   u32 *r = va_arg (*args, u32 *);
9452
9453   if (unformat (input, "conform-color"))
9454     *r = POLICE_CONFORM;
9455   else if (unformat (input, "exceed-color"))
9456     *r = POLICE_EXCEED;
9457   else
9458     return 0;
9459
9460   return 1;
9461 }
9462
9463 static int
9464 api_classify_add_del_table (vat_main_t * vam)
9465 {
9466   unformat_input_t *i = vam->input;
9467   vl_api_classify_add_del_table_t *mp;
9468
9469   u32 nbuckets = 2;
9470   u32 skip = ~0;
9471   u32 match = ~0;
9472   int is_add = 1;
9473   int del_chain = 0;
9474   u32 table_index = ~0;
9475   u32 next_table_index = ~0;
9476   u32 miss_next_index = ~0;
9477   u32 memory_size = 32 << 20;
9478   u8 *mask = 0;
9479   u32 current_data_flag = 0;
9480   int current_data_offset = 0;
9481   int ret;
9482
9483   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9484     {
9485       if (unformat (i, "del"))
9486         is_add = 0;
9487       else if (unformat (i, "del-chain"))
9488         {
9489           is_add = 0;
9490           del_chain = 1;
9491         }
9492       else if (unformat (i, "buckets %d", &nbuckets))
9493         ;
9494       else if (unformat (i, "memory_size %d", &memory_size))
9495         ;
9496       else if (unformat (i, "skip %d", &skip))
9497         ;
9498       else if (unformat (i, "match %d", &match))
9499         ;
9500       else if (unformat (i, "table %d", &table_index))
9501         ;
9502       else if (unformat (i, "mask %U", unformat_classify_mask,
9503                          &mask, &skip, &match))
9504         ;
9505       else if (unformat (i, "next-table %d", &next_table_index))
9506         ;
9507       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
9508                          &miss_next_index))
9509         ;
9510       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
9511                          &miss_next_index))
9512         ;
9513       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
9514                          &miss_next_index))
9515         ;
9516       else if (unformat (i, "current-data-flag %d", &current_data_flag))
9517         ;
9518       else if (unformat (i, "current-data-offset %d", &current_data_offset))
9519         ;
9520       else
9521         break;
9522     }
9523
9524   if (is_add && mask == 0)
9525     {
9526       errmsg ("Mask required");
9527       return -99;
9528     }
9529
9530   if (is_add && skip == ~0)
9531     {
9532       errmsg ("skip count required");
9533       return -99;
9534     }
9535
9536   if (is_add && match == ~0)
9537     {
9538       errmsg ("match count required");
9539       return -99;
9540     }
9541
9542   if (!is_add && table_index == ~0)
9543     {
9544       errmsg ("table index required for delete");
9545       return -99;
9546     }
9547
9548   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
9549
9550   mp->is_add = is_add;
9551   mp->del_chain = del_chain;
9552   mp->table_index = ntohl (table_index);
9553   mp->nbuckets = ntohl (nbuckets);
9554   mp->memory_size = ntohl (memory_size);
9555   mp->skip_n_vectors = ntohl (skip);
9556   mp->match_n_vectors = ntohl (match);
9557   mp->next_table_index = ntohl (next_table_index);
9558   mp->miss_next_index = ntohl (miss_next_index);
9559   mp->current_data_flag = ntohl (current_data_flag);
9560   mp->current_data_offset = ntohl (current_data_offset);
9561   clib_memcpy (mp->mask, mask, vec_len (mask));
9562
9563   vec_free (mask);
9564
9565   S (mp);
9566   W (ret);
9567   return ret;
9568 }
9569
9570 #if VPP_API_TEST_BUILTIN == 0
9571 uword
9572 unformat_l4_match (unformat_input_t * input, va_list * args)
9573 {
9574   u8 **matchp = va_arg (*args, u8 **);
9575
9576   u8 *proto_header = 0;
9577   int src_port = 0;
9578   int dst_port = 0;
9579
9580   tcpudp_header_t h;
9581
9582   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9583     {
9584       if (unformat (input, "src_port %d", &src_port))
9585         ;
9586       else if (unformat (input, "dst_port %d", &dst_port))
9587         ;
9588       else
9589         return 0;
9590     }
9591
9592   h.src_port = clib_host_to_net_u16 (src_port);
9593   h.dst_port = clib_host_to_net_u16 (dst_port);
9594   vec_validate (proto_header, sizeof (h) - 1);
9595   memcpy (proto_header, &h, sizeof (h));
9596
9597   *matchp = proto_header;
9598
9599   return 1;
9600 }
9601
9602 uword
9603 unformat_ip4_match (unformat_input_t * input, va_list * args)
9604 {
9605   u8 **matchp = va_arg (*args, u8 **);
9606   u8 *match = 0;
9607   ip4_header_t *ip;
9608   int version = 0;
9609   u32 version_val;
9610   int hdr_length = 0;
9611   u32 hdr_length_val;
9612   int src = 0, dst = 0;
9613   ip4_address_t src_val, dst_val;
9614   int proto = 0;
9615   u32 proto_val;
9616   int tos = 0;
9617   u32 tos_val;
9618   int length = 0;
9619   u32 length_val;
9620   int fragment_id = 0;
9621   u32 fragment_id_val;
9622   int ttl = 0;
9623   int ttl_val;
9624   int checksum = 0;
9625   u32 checksum_val;
9626
9627   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9628     {
9629       if (unformat (input, "version %d", &version_val))
9630         version = 1;
9631       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9632         hdr_length = 1;
9633       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9634         src = 1;
9635       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9636         dst = 1;
9637       else if (unformat (input, "proto %d", &proto_val))
9638         proto = 1;
9639       else if (unformat (input, "tos %d", &tos_val))
9640         tos = 1;
9641       else if (unformat (input, "length %d", &length_val))
9642         length = 1;
9643       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9644         fragment_id = 1;
9645       else if (unformat (input, "ttl %d", &ttl_val))
9646         ttl = 1;
9647       else if (unformat (input, "checksum %d", &checksum_val))
9648         checksum = 1;
9649       else
9650         break;
9651     }
9652
9653   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9654       + ttl + checksum == 0)
9655     return 0;
9656
9657   /*
9658    * Aligned because we use the real comparison functions
9659    */
9660   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9661
9662   ip = (ip4_header_t *) match;
9663
9664   /* These are realistically matched in practice */
9665   if (src)
9666     ip->src_address.as_u32 = src_val.as_u32;
9667
9668   if (dst)
9669     ip->dst_address.as_u32 = dst_val.as_u32;
9670
9671   if (proto)
9672     ip->protocol = proto_val;
9673
9674
9675   /* These are not, but they're included for completeness */
9676   if (version)
9677     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9678
9679   if (hdr_length)
9680     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9681
9682   if (tos)
9683     ip->tos = tos_val;
9684
9685   if (length)
9686     ip->length = clib_host_to_net_u16 (length_val);
9687
9688   if (ttl)
9689     ip->ttl = ttl_val;
9690
9691   if (checksum)
9692     ip->checksum = clib_host_to_net_u16 (checksum_val);
9693
9694   *matchp = match;
9695   return 1;
9696 }
9697
9698 uword
9699 unformat_ip6_match (unformat_input_t * input, va_list * args)
9700 {
9701   u8 **matchp = va_arg (*args, u8 **);
9702   u8 *match = 0;
9703   ip6_header_t *ip;
9704   int version = 0;
9705   u32 version_val;
9706   u8 traffic_class = 0;
9707   u32 traffic_class_val = 0;
9708   u8 flow_label = 0;
9709   u8 flow_label_val;
9710   int src = 0, dst = 0;
9711   ip6_address_t src_val, dst_val;
9712   int proto = 0;
9713   u32 proto_val;
9714   int payload_length = 0;
9715   u32 payload_length_val;
9716   int hop_limit = 0;
9717   int hop_limit_val;
9718   u32 ip_version_traffic_class_and_flow_label;
9719
9720   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9721     {
9722       if (unformat (input, "version %d", &version_val))
9723         version = 1;
9724       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9725         traffic_class = 1;
9726       else if (unformat (input, "flow_label %d", &flow_label_val))
9727         flow_label = 1;
9728       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9729         src = 1;
9730       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9731         dst = 1;
9732       else if (unformat (input, "proto %d", &proto_val))
9733         proto = 1;
9734       else if (unformat (input, "payload_length %d", &payload_length_val))
9735         payload_length = 1;
9736       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9737         hop_limit = 1;
9738       else
9739         break;
9740     }
9741
9742   if (version + traffic_class + flow_label + src + dst + proto +
9743       payload_length + hop_limit == 0)
9744     return 0;
9745
9746   /*
9747    * Aligned because we use the real comparison functions
9748    */
9749   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9750
9751   ip = (ip6_header_t *) match;
9752
9753   if (src)
9754     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9755
9756   if (dst)
9757     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9758
9759   if (proto)
9760     ip->protocol = proto_val;
9761
9762   ip_version_traffic_class_and_flow_label = 0;
9763
9764   if (version)
9765     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9766
9767   if (traffic_class)
9768     ip_version_traffic_class_and_flow_label |=
9769       (traffic_class_val & 0xFF) << 20;
9770
9771   if (flow_label)
9772     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9773
9774   ip->ip_version_traffic_class_and_flow_label =
9775     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9776
9777   if (payload_length)
9778     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9779
9780   if (hop_limit)
9781     ip->hop_limit = hop_limit_val;
9782
9783   *matchp = match;
9784   return 1;
9785 }
9786
9787 uword
9788 unformat_l3_match (unformat_input_t * input, va_list * args)
9789 {
9790   u8 **matchp = va_arg (*args, u8 **);
9791
9792   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9793     {
9794       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9795         return 1;
9796       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9797         return 1;
9798       else
9799         break;
9800     }
9801   return 0;
9802 }
9803
9804 uword
9805 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9806 {
9807   u8 *tagp = va_arg (*args, u8 *);
9808   u32 tag;
9809
9810   if (unformat (input, "%d", &tag))
9811     {
9812       tagp[0] = (tag >> 8) & 0x0F;
9813       tagp[1] = tag & 0xFF;
9814       return 1;
9815     }
9816
9817   return 0;
9818 }
9819
9820 uword
9821 unformat_l2_match (unformat_input_t * input, va_list * args)
9822 {
9823   u8 **matchp = va_arg (*args, u8 **);
9824   u8 *match = 0;
9825   u8 src = 0;
9826   u8 src_val[6];
9827   u8 dst = 0;
9828   u8 dst_val[6];
9829   u8 proto = 0;
9830   u16 proto_val;
9831   u8 tag1 = 0;
9832   u8 tag1_val[2];
9833   u8 tag2 = 0;
9834   u8 tag2_val[2];
9835   int len = 14;
9836   u8 ignore_tag1 = 0;
9837   u8 ignore_tag2 = 0;
9838   u8 cos1 = 0;
9839   u8 cos2 = 0;
9840   u32 cos1_val = 0;
9841   u32 cos2_val = 0;
9842
9843   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9844     {
9845       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9846         src = 1;
9847       else
9848         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9849         dst = 1;
9850       else if (unformat (input, "proto %U",
9851                          unformat_ethernet_type_host_byte_order, &proto_val))
9852         proto = 1;
9853       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9854         tag1 = 1;
9855       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9856         tag2 = 1;
9857       else if (unformat (input, "ignore-tag1"))
9858         ignore_tag1 = 1;
9859       else if (unformat (input, "ignore-tag2"))
9860         ignore_tag2 = 1;
9861       else if (unformat (input, "cos1 %d", &cos1_val))
9862         cos1 = 1;
9863       else if (unformat (input, "cos2 %d", &cos2_val))
9864         cos2 = 1;
9865       else
9866         break;
9867     }
9868   if ((src + dst + proto + tag1 + tag2 +
9869        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9870     return 0;
9871
9872   if (tag1 || ignore_tag1 || cos1)
9873     len = 18;
9874   if (tag2 || ignore_tag2 || cos2)
9875     len = 22;
9876
9877   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9878
9879   if (dst)
9880     clib_memcpy (match, dst_val, 6);
9881
9882   if (src)
9883     clib_memcpy (match + 6, src_val, 6);
9884
9885   if (tag2)
9886     {
9887       /* inner vlan tag */
9888       match[19] = tag2_val[1];
9889       match[18] = tag2_val[0];
9890       if (cos2)
9891         match[18] |= (cos2_val & 0x7) << 5;
9892       if (proto)
9893         {
9894           match[21] = proto_val & 0xff;
9895           match[20] = proto_val >> 8;
9896         }
9897       if (tag1)
9898         {
9899           match[15] = tag1_val[1];
9900           match[14] = tag1_val[0];
9901         }
9902       if (cos1)
9903         match[14] |= (cos1_val & 0x7) << 5;
9904       *matchp = match;
9905       return 1;
9906     }
9907   if (tag1)
9908     {
9909       match[15] = tag1_val[1];
9910       match[14] = tag1_val[0];
9911       if (proto)
9912         {
9913           match[17] = proto_val & 0xff;
9914           match[16] = proto_val >> 8;
9915         }
9916       if (cos1)
9917         match[14] |= (cos1_val & 0x7) << 5;
9918
9919       *matchp = match;
9920       return 1;
9921     }
9922   if (cos2)
9923     match[18] |= (cos2_val & 0x7) << 5;
9924   if (cos1)
9925     match[14] |= (cos1_val & 0x7) << 5;
9926   if (proto)
9927     {
9928       match[13] = proto_val & 0xff;
9929       match[12] = proto_val >> 8;
9930     }
9931
9932   *matchp = match;
9933   return 1;
9934 }
9935 #endif
9936
9937 uword
9938 api_unformat_classify_match (unformat_input_t * input, va_list * args)
9939 {
9940   u8 **matchp = va_arg (*args, u8 **);
9941   u32 skip_n_vectors = va_arg (*args, u32);
9942   u32 match_n_vectors = va_arg (*args, u32);
9943
9944   u8 *match = 0;
9945   u8 *l2 = 0;
9946   u8 *l3 = 0;
9947   u8 *l4 = 0;
9948
9949   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9950     {
9951       if (unformat (input, "hex %U", unformat_hex_string, &match))
9952         ;
9953       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9954         ;
9955       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9956         ;
9957       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9958         ;
9959       else
9960         break;
9961     }
9962
9963   if (l4 && !l3)
9964     {
9965       vec_free (match);
9966       vec_free (l2);
9967       vec_free (l4);
9968       return 0;
9969     }
9970
9971   if (match || l2 || l3 || l4)
9972     {
9973       if (l2 || l3 || l4)
9974         {
9975           /* "Win a free Ethernet header in every packet" */
9976           if (l2 == 0)
9977             vec_validate_aligned (l2, 13, sizeof (u32x4));
9978           match = l2;
9979           if (vec_len (l3))
9980             {
9981               vec_append_aligned (match, l3, sizeof (u32x4));
9982               vec_free (l3);
9983             }
9984           if (vec_len (l4))
9985             {
9986               vec_append_aligned (match, l4, sizeof (u32x4));
9987               vec_free (l4);
9988             }
9989         }
9990
9991       /* Make sure the vector is big enough even if key is all 0's */
9992       vec_validate_aligned
9993         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9994          sizeof (u32x4));
9995
9996       /* Set size, include skipped vectors */
9997       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9998
9999       *matchp = match;
10000
10001       return 1;
10002     }
10003
10004   return 0;
10005 }
10006
10007 static int
10008 api_classify_add_del_session (vat_main_t * vam)
10009 {
10010   unformat_input_t *i = vam->input;
10011   vl_api_classify_add_del_session_t *mp;
10012   int is_add = 1;
10013   u32 table_index = ~0;
10014   u32 hit_next_index = ~0;
10015   u32 opaque_index = ~0;
10016   u8 *match = 0;
10017   i32 advance = 0;
10018   u32 skip_n_vectors = 0;
10019   u32 match_n_vectors = 0;
10020   u32 action = 0;
10021   u32 metadata = 0;
10022   int ret;
10023
10024   /*
10025    * Warning: you have to supply skip_n and match_n
10026    * because the API client cant simply look at the classify
10027    * table object.
10028    */
10029
10030   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10031     {
10032       if (unformat (i, "del"))
10033         is_add = 0;
10034       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10035                          &hit_next_index))
10036         ;
10037       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10038                          &hit_next_index))
10039         ;
10040       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10041                          &hit_next_index))
10042         ;
10043       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10044         ;
10045       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10046         ;
10047       else if (unformat (i, "opaque-index %d", &opaque_index))
10048         ;
10049       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10050         ;
10051       else if (unformat (i, "match_n %d", &match_n_vectors))
10052         ;
10053       else if (unformat (i, "match %U", api_unformat_classify_match,
10054                          &match, skip_n_vectors, match_n_vectors))
10055         ;
10056       else if (unformat (i, "advance %d", &advance))
10057         ;
10058       else if (unformat (i, "table-index %d", &table_index))
10059         ;
10060       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10061         action = 1;
10062       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10063         action = 2;
10064       else if (unformat (i, "action %d", &action))
10065         ;
10066       else if (unformat (i, "metadata %d", &metadata))
10067         ;
10068       else
10069         break;
10070     }
10071
10072   if (table_index == ~0)
10073     {
10074       errmsg ("Table index required");
10075       return -99;
10076     }
10077
10078   if (is_add && match == 0)
10079     {
10080       errmsg ("Match value required");
10081       return -99;
10082     }
10083
10084   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10085
10086   mp->is_add = is_add;
10087   mp->table_index = ntohl (table_index);
10088   mp->hit_next_index = ntohl (hit_next_index);
10089   mp->opaque_index = ntohl (opaque_index);
10090   mp->advance = ntohl (advance);
10091   mp->action = action;
10092   mp->metadata = ntohl (metadata);
10093   clib_memcpy (mp->match, match, vec_len (match));
10094   vec_free (match);
10095
10096   S (mp);
10097   W (ret);
10098   return ret;
10099 }
10100
10101 static int
10102 api_classify_set_interface_ip_table (vat_main_t * vam)
10103 {
10104   unformat_input_t *i = vam->input;
10105   vl_api_classify_set_interface_ip_table_t *mp;
10106   u32 sw_if_index;
10107   int sw_if_index_set;
10108   u32 table_index = ~0;
10109   u8 is_ipv6 = 0;
10110   int ret;
10111
10112   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10113     {
10114       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10115         sw_if_index_set = 1;
10116       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10117         sw_if_index_set = 1;
10118       else if (unformat (i, "table %d", &table_index))
10119         ;
10120       else
10121         {
10122           clib_warning ("parse error '%U'", format_unformat_error, i);
10123           return -99;
10124         }
10125     }
10126
10127   if (sw_if_index_set == 0)
10128     {
10129       errmsg ("missing interface name or sw_if_index");
10130       return -99;
10131     }
10132
10133
10134   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10135
10136   mp->sw_if_index = ntohl (sw_if_index);
10137   mp->table_index = ntohl (table_index);
10138   mp->is_ipv6 = is_ipv6;
10139
10140   S (mp);
10141   W (ret);
10142   return ret;
10143 }
10144
10145 static int
10146 api_classify_set_interface_l2_tables (vat_main_t * vam)
10147 {
10148   unformat_input_t *i = vam->input;
10149   vl_api_classify_set_interface_l2_tables_t *mp;
10150   u32 sw_if_index;
10151   int sw_if_index_set;
10152   u32 ip4_table_index = ~0;
10153   u32 ip6_table_index = ~0;
10154   u32 other_table_index = ~0;
10155   u32 is_input = 1;
10156   int ret;
10157
10158   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10159     {
10160       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10161         sw_if_index_set = 1;
10162       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10163         sw_if_index_set = 1;
10164       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10165         ;
10166       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10167         ;
10168       else if (unformat (i, "other-table %d", &other_table_index))
10169         ;
10170       else if (unformat (i, "is-input %d", &is_input))
10171         ;
10172       else
10173         {
10174           clib_warning ("parse error '%U'", format_unformat_error, i);
10175           return -99;
10176         }
10177     }
10178
10179   if (sw_if_index_set == 0)
10180     {
10181       errmsg ("missing interface name or sw_if_index");
10182       return -99;
10183     }
10184
10185
10186   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10187
10188   mp->sw_if_index = ntohl (sw_if_index);
10189   mp->ip4_table_index = ntohl (ip4_table_index);
10190   mp->ip6_table_index = ntohl (ip6_table_index);
10191   mp->other_table_index = ntohl (other_table_index);
10192   mp->is_input = (u8) is_input;
10193
10194   S (mp);
10195   W (ret);
10196   return ret;
10197 }
10198
10199 static int
10200 api_set_ipfix_exporter (vat_main_t * vam)
10201 {
10202   unformat_input_t *i = vam->input;
10203   vl_api_set_ipfix_exporter_t *mp;
10204   ip4_address_t collector_address;
10205   u8 collector_address_set = 0;
10206   u32 collector_port = ~0;
10207   ip4_address_t src_address;
10208   u8 src_address_set = 0;
10209   u32 vrf_id = ~0;
10210   u32 path_mtu = ~0;
10211   u32 template_interval = ~0;
10212   u8 udp_checksum = 0;
10213   int ret;
10214
10215   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10216     {
10217       if (unformat (i, "collector_address %U", unformat_ip4_address,
10218                     &collector_address))
10219         collector_address_set = 1;
10220       else if (unformat (i, "collector_port %d", &collector_port))
10221         ;
10222       else if (unformat (i, "src_address %U", unformat_ip4_address,
10223                          &src_address))
10224         src_address_set = 1;
10225       else if (unformat (i, "vrf_id %d", &vrf_id))
10226         ;
10227       else if (unformat (i, "path_mtu %d", &path_mtu))
10228         ;
10229       else if (unformat (i, "template_interval %d", &template_interval))
10230         ;
10231       else if (unformat (i, "udp_checksum"))
10232         udp_checksum = 1;
10233       else
10234         break;
10235     }
10236
10237   if (collector_address_set == 0)
10238     {
10239       errmsg ("collector_address required");
10240       return -99;
10241     }
10242
10243   if (src_address_set == 0)
10244     {
10245       errmsg ("src_address required");
10246       return -99;
10247     }
10248
10249   M (SET_IPFIX_EXPORTER, mp);
10250
10251   memcpy (mp->collector_address, collector_address.data,
10252           sizeof (collector_address.data));
10253   mp->collector_port = htons ((u16) collector_port);
10254   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
10255   mp->vrf_id = htonl (vrf_id);
10256   mp->path_mtu = htonl (path_mtu);
10257   mp->template_interval = htonl (template_interval);
10258   mp->udp_checksum = udp_checksum;
10259
10260   S (mp);
10261   W (ret);
10262   return ret;
10263 }
10264
10265 static int
10266 api_set_ipfix_classify_stream (vat_main_t * vam)
10267 {
10268   unformat_input_t *i = vam->input;
10269   vl_api_set_ipfix_classify_stream_t *mp;
10270   u32 domain_id = 0;
10271   u32 src_port = UDP_DST_PORT_ipfix;
10272   int ret;
10273
10274   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10275     {
10276       if (unformat (i, "domain %d", &domain_id))
10277         ;
10278       else if (unformat (i, "src_port %d", &src_port))
10279         ;
10280       else
10281         {
10282           errmsg ("unknown input `%U'", format_unformat_error, i);
10283           return -99;
10284         }
10285     }
10286
10287   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10288
10289   mp->domain_id = htonl (domain_id);
10290   mp->src_port = htons ((u16) src_port);
10291
10292   S (mp);
10293   W (ret);
10294   return ret;
10295 }
10296
10297 static int
10298 api_ipfix_classify_table_add_del (vat_main_t * vam)
10299 {
10300   unformat_input_t *i = vam->input;
10301   vl_api_ipfix_classify_table_add_del_t *mp;
10302   int is_add = -1;
10303   u32 classify_table_index = ~0;
10304   u8 ip_version = 0;
10305   u8 transport_protocol = 255;
10306   int ret;
10307
10308   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10309     {
10310       if (unformat (i, "add"))
10311         is_add = 1;
10312       else if (unformat (i, "del"))
10313         is_add = 0;
10314       else if (unformat (i, "table %d", &classify_table_index))
10315         ;
10316       else if (unformat (i, "ip4"))
10317         ip_version = 4;
10318       else if (unformat (i, "ip6"))
10319         ip_version = 6;
10320       else if (unformat (i, "tcp"))
10321         transport_protocol = 6;
10322       else if (unformat (i, "udp"))
10323         transport_protocol = 17;
10324       else
10325         {
10326           errmsg ("unknown input `%U'", format_unformat_error, i);
10327           return -99;
10328         }
10329     }
10330
10331   if (is_add == -1)
10332     {
10333       errmsg ("expecting: add|del");
10334       return -99;
10335     }
10336   if (classify_table_index == ~0)
10337     {
10338       errmsg ("classifier table not specified");
10339       return -99;
10340     }
10341   if (ip_version == 0)
10342     {
10343       errmsg ("IP version not specified");
10344       return -99;
10345     }
10346
10347   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10348
10349   mp->is_add = is_add;
10350   mp->table_id = htonl (classify_table_index);
10351   mp->ip_version = ip_version;
10352   mp->transport_protocol = transport_protocol;
10353
10354   S (mp);
10355   W (ret);
10356   return ret;
10357 }
10358
10359 static int
10360 api_get_node_index (vat_main_t * vam)
10361 {
10362   unformat_input_t *i = vam->input;
10363   vl_api_get_node_index_t *mp;
10364   u8 *name = 0;
10365   int ret;
10366
10367   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10368     {
10369       if (unformat (i, "node %s", &name))
10370         ;
10371       else
10372         break;
10373     }
10374   if (name == 0)
10375     {
10376       errmsg ("node name required");
10377       return -99;
10378     }
10379   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10380     {
10381       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10382       return -99;
10383     }
10384
10385   M (GET_NODE_INDEX, mp);
10386   clib_memcpy (mp->node_name, name, vec_len (name));
10387   vec_free (name);
10388
10389   S (mp);
10390   W (ret);
10391   return ret;
10392 }
10393
10394 static int
10395 api_get_next_index (vat_main_t * vam)
10396 {
10397   unformat_input_t *i = vam->input;
10398   vl_api_get_next_index_t *mp;
10399   u8 *node_name = 0, *next_node_name = 0;
10400   int ret;
10401
10402   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10403     {
10404       if (unformat (i, "node-name %s", &node_name))
10405         ;
10406       else if (unformat (i, "next-node-name %s", &next_node_name))
10407         break;
10408     }
10409
10410   if (node_name == 0)
10411     {
10412       errmsg ("node name required");
10413       return -99;
10414     }
10415   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10416     {
10417       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10418       return -99;
10419     }
10420
10421   if (next_node_name == 0)
10422     {
10423       errmsg ("next node name required");
10424       return -99;
10425     }
10426   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10427     {
10428       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10429       return -99;
10430     }
10431
10432   M (GET_NEXT_INDEX, mp);
10433   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10434   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10435   vec_free (node_name);
10436   vec_free (next_node_name);
10437
10438   S (mp);
10439   W (ret);
10440   return ret;
10441 }
10442
10443 static int
10444 api_add_node_next (vat_main_t * vam)
10445 {
10446   unformat_input_t *i = vam->input;
10447   vl_api_add_node_next_t *mp;
10448   u8 *name = 0;
10449   u8 *next = 0;
10450   int ret;
10451
10452   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10453     {
10454       if (unformat (i, "node %s", &name))
10455         ;
10456       else if (unformat (i, "next %s", &next))
10457         ;
10458       else
10459         break;
10460     }
10461   if (name == 0)
10462     {
10463       errmsg ("node name required");
10464       return -99;
10465     }
10466   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10467     {
10468       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10469       return -99;
10470     }
10471   if (next == 0)
10472     {
10473       errmsg ("next node required");
10474       return -99;
10475     }
10476   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10477     {
10478       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10479       return -99;
10480     }
10481
10482   M (ADD_NODE_NEXT, mp);
10483   clib_memcpy (mp->node_name, name, vec_len (name));
10484   clib_memcpy (mp->next_name, next, vec_len (next));
10485   vec_free (name);
10486   vec_free (next);
10487
10488   S (mp);
10489   W (ret);
10490   return ret;
10491 }
10492
10493 static int
10494 api_l2tpv3_create_tunnel (vat_main_t * vam)
10495 {
10496   unformat_input_t *i = vam->input;
10497   ip6_address_t client_address, our_address;
10498   int client_address_set = 0;
10499   int our_address_set = 0;
10500   u32 local_session_id = 0;
10501   u32 remote_session_id = 0;
10502   u64 local_cookie = 0;
10503   u64 remote_cookie = 0;
10504   u8 l2_sublayer_present = 0;
10505   vl_api_l2tpv3_create_tunnel_t *mp;
10506   int ret;
10507
10508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10509     {
10510       if (unformat (i, "client_address %U", unformat_ip6_address,
10511                     &client_address))
10512         client_address_set = 1;
10513       else if (unformat (i, "our_address %U", unformat_ip6_address,
10514                          &our_address))
10515         our_address_set = 1;
10516       else if (unformat (i, "local_session_id %d", &local_session_id))
10517         ;
10518       else if (unformat (i, "remote_session_id %d", &remote_session_id))
10519         ;
10520       else if (unformat (i, "local_cookie %lld", &local_cookie))
10521         ;
10522       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10523         ;
10524       else if (unformat (i, "l2-sublayer-present"))
10525         l2_sublayer_present = 1;
10526       else
10527         break;
10528     }
10529
10530   if (client_address_set == 0)
10531     {
10532       errmsg ("client_address required");
10533       return -99;
10534     }
10535
10536   if (our_address_set == 0)
10537     {
10538       errmsg ("our_address required");
10539       return -99;
10540     }
10541
10542   M (L2TPV3_CREATE_TUNNEL, mp);
10543
10544   clib_memcpy (mp->client_address, client_address.as_u8,
10545                sizeof (mp->client_address));
10546
10547   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10548
10549   mp->local_session_id = ntohl (local_session_id);
10550   mp->remote_session_id = ntohl (remote_session_id);
10551   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10552   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10553   mp->l2_sublayer_present = l2_sublayer_present;
10554   mp->is_ipv6 = 1;
10555
10556   S (mp);
10557   W (ret);
10558   return ret;
10559 }
10560
10561 static int
10562 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10563 {
10564   unformat_input_t *i = vam->input;
10565   u32 sw_if_index;
10566   u8 sw_if_index_set = 0;
10567   u64 new_local_cookie = 0;
10568   u64 new_remote_cookie = 0;
10569   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10570   int ret;
10571
10572   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10573     {
10574       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10575         sw_if_index_set = 1;
10576       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10577         sw_if_index_set = 1;
10578       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10579         ;
10580       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10581         ;
10582       else
10583         break;
10584     }
10585
10586   if (sw_if_index_set == 0)
10587     {
10588       errmsg ("missing interface name or sw_if_index");
10589       return -99;
10590     }
10591
10592   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
10593
10594   mp->sw_if_index = ntohl (sw_if_index);
10595   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10596   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10597
10598   S (mp);
10599   W (ret);
10600   return ret;
10601 }
10602
10603 static int
10604 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10605 {
10606   unformat_input_t *i = vam->input;
10607   vl_api_l2tpv3_interface_enable_disable_t *mp;
10608   u32 sw_if_index;
10609   u8 sw_if_index_set = 0;
10610   u8 enable_disable = 1;
10611   int ret;
10612
10613   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10614     {
10615       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10616         sw_if_index_set = 1;
10617       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10618         sw_if_index_set = 1;
10619       else if (unformat (i, "enable"))
10620         enable_disable = 1;
10621       else if (unformat (i, "disable"))
10622         enable_disable = 0;
10623       else
10624         break;
10625     }
10626
10627   if (sw_if_index_set == 0)
10628     {
10629       errmsg ("missing interface name or sw_if_index");
10630       return -99;
10631     }
10632
10633   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
10634
10635   mp->sw_if_index = ntohl (sw_if_index);
10636   mp->enable_disable = enable_disable;
10637
10638   S (mp);
10639   W (ret);
10640   return ret;
10641 }
10642
10643 static int
10644 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10645 {
10646   unformat_input_t *i = vam->input;
10647   vl_api_l2tpv3_set_lookup_key_t *mp;
10648   u8 key = ~0;
10649   int ret;
10650
10651   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10652     {
10653       if (unformat (i, "lookup_v6_src"))
10654         key = L2T_LOOKUP_SRC_ADDRESS;
10655       else if (unformat (i, "lookup_v6_dst"))
10656         key = L2T_LOOKUP_DST_ADDRESS;
10657       else if (unformat (i, "lookup_session_id"))
10658         key = L2T_LOOKUP_SESSION_ID;
10659       else
10660         break;
10661     }
10662
10663   if (key == (u8) ~ 0)
10664     {
10665       errmsg ("l2tp session lookup key unset");
10666       return -99;
10667     }
10668
10669   M (L2TPV3_SET_LOOKUP_KEY, mp);
10670
10671   mp->key = key;
10672
10673   S (mp);
10674   W (ret);
10675   return ret;
10676 }
10677
10678 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10679   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10680 {
10681   vat_main_t *vam = &vat_main;
10682
10683   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10684          format_ip6_address, mp->our_address,
10685          format_ip6_address, mp->client_address,
10686          clib_net_to_host_u32 (mp->sw_if_index));
10687
10688   print (vam->ofp,
10689          "   local cookies %016llx %016llx remote cookie %016llx",
10690          clib_net_to_host_u64 (mp->local_cookie[0]),
10691          clib_net_to_host_u64 (mp->local_cookie[1]),
10692          clib_net_to_host_u64 (mp->remote_cookie));
10693
10694   print (vam->ofp, "   local session-id %d remote session-id %d",
10695          clib_net_to_host_u32 (mp->local_session_id),
10696          clib_net_to_host_u32 (mp->remote_session_id));
10697
10698   print (vam->ofp, "   l2 specific sublayer %s\n",
10699          mp->l2_sublayer_present ? "preset" : "absent");
10700
10701 }
10702
10703 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10704   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10705 {
10706   vat_main_t *vam = &vat_main;
10707   vat_json_node_t *node = NULL;
10708   struct in6_addr addr;
10709
10710   if (VAT_JSON_ARRAY != vam->json_tree.type)
10711     {
10712       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10713       vat_json_init_array (&vam->json_tree);
10714     }
10715   node = vat_json_array_add (&vam->json_tree);
10716
10717   vat_json_init_object (node);
10718
10719   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10720   vat_json_object_add_ip6 (node, "our_address", addr);
10721   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10722   vat_json_object_add_ip6 (node, "client_address", addr);
10723
10724   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10725   vat_json_init_array (lc);
10726   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10727   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10728   vat_json_object_add_uint (node, "remote_cookie",
10729                             clib_net_to_host_u64 (mp->remote_cookie));
10730
10731   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10732   vat_json_object_add_uint (node, "local_session_id",
10733                             clib_net_to_host_u32 (mp->local_session_id));
10734   vat_json_object_add_uint (node, "remote_session_id",
10735                             clib_net_to_host_u32 (mp->remote_session_id));
10736   vat_json_object_add_string_copy (node, "l2_sublayer",
10737                                    mp->l2_sublayer_present ? (u8 *) "present"
10738                                    : (u8 *) "absent");
10739 }
10740
10741 static int
10742 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10743 {
10744   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10745   vl_api_control_ping_t *mp_ping;
10746   int ret;
10747
10748   /* Get list of l2tpv3-tunnel interfaces */
10749   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
10750   S (mp);
10751
10752   /* Use a control ping for synchronization */
10753   M (CONTROL_PING, mp_ping);
10754   S (mp_ping);
10755
10756   W (ret);
10757   return ret;
10758 }
10759
10760
10761 static void vl_api_sw_interface_tap_details_t_handler
10762   (vl_api_sw_interface_tap_details_t * mp)
10763 {
10764   vat_main_t *vam = &vat_main;
10765
10766   print (vam->ofp, "%-16s %d",
10767          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10768 }
10769
10770 static void vl_api_sw_interface_tap_details_t_handler_json
10771   (vl_api_sw_interface_tap_details_t * mp)
10772 {
10773   vat_main_t *vam = &vat_main;
10774   vat_json_node_t *node = NULL;
10775
10776   if (VAT_JSON_ARRAY != vam->json_tree.type)
10777     {
10778       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10779       vat_json_init_array (&vam->json_tree);
10780     }
10781   node = vat_json_array_add (&vam->json_tree);
10782
10783   vat_json_init_object (node);
10784   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10785   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10786 }
10787
10788 static int
10789 api_sw_interface_tap_dump (vat_main_t * vam)
10790 {
10791   vl_api_sw_interface_tap_dump_t *mp;
10792   vl_api_control_ping_t *mp_ping;
10793   int ret;
10794
10795   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10796   /* Get list of tap interfaces */
10797   M (SW_INTERFACE_TAP_DUMP, mp);
10798   S (mp);
10799
10800   /* Use a control ping for synchronization */
10801   M (CONTROL_PING, mp_ping);
10802   S (mp_ping);
10803
10804   W (ret);
10805   return ret;
10806 }
10807
10808 static uword unformat_vxlan_decap_next
10809   (unformat_input_t * input, va_list * args)
10810 {
10811   u32 *result = va_arg (*args, u32 *);
10812   u32 tmp;
10813
10814   if (unformat (input, "l2"))
10815     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10816   else if (unformat (input, "%d", &tmp))
10817     *result = tmp;
10818   else
10819     return 0;
10820   return 1;
10821 }
10822
10823 static int
10824 api_vxlan_add_del_tunnel (vat_main_t * vam)
10825 {
10826   unformat_input_t *line_input = vam->input;
10827   vl_api_vxlan_add_del_tunnel_t *mp;
10828   ip46_address_t src, dst;
10829   u8 is_add = 1;
10830   u8 ipv4_set = 0, ipv6_set = 0;
10831   u8 src_set = 0;
10832   u8 dst_set = 0;
10833   u8 grp_set = 0;
10834   u32 mcast_sw_if_index = ~0;
10835   u32 encap_vrf_id = 0;
10836   u32 decap_next_index = ~0;
10837   u32 vni = 0;
10838   int ret;
10839
10840   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10841   memset (&src, 0, sizeof src);
10842   memset (&dst, 0, sizeof dst);
10843
10844   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10845     {
10846       if (unformat (line_input, "del"))
10847         is_add = 0;
10848       else
10849         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10850         {
10851           ipv4_set = 1;
10852           src_set = 1;
10853         }
10854       else
10855         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10856         {
10857           ipv4_set = 1;
10858           dst_set = 1;
10859         }
10860       else
10861         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10862         {
10863           ipv6_set = 1;
10864           src_set = 1;
10865         }
10866       else
10867         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10868         {
10869           ipv6_set = 1;
10870           dst_set = 1;
10871         }
10872       else if (unformat (line_input, "group %U %U",
10873                          unformat_ip4_address, &dst.ip4,
10874                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10875         {
10876           grp_set = dst_set = 1;
10877           ipv4_set = 1;
10878         }
10879       else if (unformat (line_input, "group %U",
10880                          unformat_ip4_address, &dst.ip4))
10881         {
10882           grp_set = dst_set = 1;
10883           ipv4_set = 1;
10884         }
10885       else if (unformat (line_input, "group %U %U",
10886                          unformat_ip6_address, &dst.ip6,
10887                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10888         {
10889           grp_set = dst_set = 1;
10890           ipv6_set = 1;
10891         }
10892       else if (unformat (line_input, "group %U",
10893                          unformat_ip6_address, &dst.ip6))
10894         {
10895           grp_set = dst_set = 1;
10896           ipv6_set = 1;
10897         }
10898       else
10899         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10900         ;
10901       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10902         ;
10903       else if (unformat (line_input, "decap-next %U",
10904                          unformat_vxlan_decap_next, &decap_next_index))
10905         ;
10906       else if (unformat (line_input, "vni %d", &vni))
10907         ;
10908       else
10909         {
10910           errmsg ("parse error '%U'", format_unformat_error, line_input);
10911           return -99;
10912         }
10913     }
10914
10915   if (src_set == 0)
10916     {
10917       errmsg ("tunnel src address not specified");
10918       return -99;
10919     }
10920   if (dst_set == 0)
10921     {
10922       errmsg ("tunnel dst address not specified");
10923       return -99;
10924     }
10925
10926   if (grp_set && !ip46_address_is_multicast (&dst))
10927     {
10928       errmsg ("tunnel group address not multicast");
10929       return -99;
10930     }
10931   if (grp_set && mcast_sw_if_index == ~0)
10932     {
10933       errmsg ("tunnel nonexistent multicast device");
10934       return -99;
10935     }
10936   if (grp_set == 0 && ip46_address_is_multicast (&dst))
10937     {
10938       errmsg ("tunnel dst address must be unicast");
10939       return -99;
10940     }
10941
10942
10943   if (ipv4_set && ipv6_set)
10944     {
10945       errmsg ("both IPv4 and IPv6 addresses specified");
10946       return -99;
10947     }
10948
10949   if ((vni == 0) || (vni >> 24))
10950     {
10951       errmsg ("vni not specified or out of range");
10952       return -99;
10953     }
10954
10955   M (VXLAN_ADD_DEL_TUNNEL, mp);
10956
10957   if (ipv6_set)
10958     {
10959       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10960       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10961     }
10962   else
10963     {
10964       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10965       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10966     }
10967   mp->encap_vrf_id = ntohl (encap_vrf_id);
10968   mp->decap_next_index = ntohl (decap_next_index);
10969   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10970   mp->vni = ntohl (vni);
10971   mp->is_add = is_add;
10972   mp->is_ipv6 = ipv6_set;
10973
10974   S (mp);
10975   W (ret);
10976   return ret;
10977 }
10978
10979 static void vl_api_vxlan_tunnel_details_t_handler
10980   (vl_api_vxlan_tunnel_details_t * mp)
10981 {
10982   vat_main_t *vam = &vat_main;
10983   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
10984   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
10985
10986   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
10987          ntohl (mp->sw_if_index),
10988          format_ip46_address, &src, IP46_TYPE_ANY,
10989          format_ip46_address, &dst, IP46_TYPE_ANY,
10990          ntohl (mp->encap_vrf_id),
10991          ntohl (mp->decap_next_index), ntohl (mp->vni),
10992          ntohl (mp->mcast_sw_if_index));
10993 }
10994
10995 static void vl_api_vxlan_tunnel_details_t_handler_json
10996   (vl_api_vxlan_tunnel_details_t * mp)
10997 {
10998   vat_main_t *vam = &vat_main;
10999   vat_json_node_t *node = NULL;
11000
11001   if (VAT_JSON_ARRAY != vam->json_tree.type)
11002     {
11003       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11004       vat_json_init_array (&vam->json_tree);
11005     }
11006   node = vat_json_array_add (&vam->json_tree);
11007
11008   vat_json_init_object (node);
11009   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11010   if (mp->is_ipv6)
11011     {
11012       struct in6_addr ip6;
11013
11014       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
11015       vat_json_object_add_ip6 (node, "src_address", ip6);
11016       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
11017       vat_json_object_add_ip6 (node, "dst_address", ip6);
11018     }
11019   else
11020     {
11021       struct in_addr ip4;
11022
11023       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
11024       vat_json_object_add_ip4 (node, "src_address", ip4);
11025       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
11026       vat_json_object_add_ip4 (node, "dst_address", ip4);
11027     }
11028   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11029   vat_json_object_add_uint (node, "decap_next_index",
11030                             ntohl (mp->decap_next_index));
11031   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11032   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11033   vat_json_object_add_uint (node, "mcast_sw_if_index",
11034                             ntohl (mp->mcast_sw_if_index));
11035 }
11036
11037 static int
11038 api_vxlan_tunnel_dump (vat_main_t * vam)
11039 {
11040   unformat_input_t *i = vam->input;
11041   vl_api_vxlan_tunnel_dump_t *mp;
11042   vl_api_control_ping_t *mp_ping;
11043   u32 sw_if_index;
11044   u8 sw_if_index_set = 0;
11045   int ret;
11046
11047   /* Parse args required to build the message */
11048   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11049     {
11050       if (unformat (i, "sw_if_index %d", &sw_if_index))
11051         sw_if_index_set = 1;
11052       else
11053         break;
11054     }
11055
11056   if (sw_if_index_set == 0)
11057     {
11058       sw_if_index = ~0;
11059     }
11060
11061   if (!vam->json_output)
11062     {
11063       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
11064              "sw_if_index", "src_address", "dst_address",
11065              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11066     }
11067
11068   /* Get list of vxlan-tunnel interfaces */
11069   M (VXLAN_TUNNEL_DUMP, mp);
11070
11071   mp->sw_if_index = htonl (sw_if_index);
11072
11073   S (mp);
11074
11075   /* Use a control ping for synchronization */
11076   M (CONTROL_PING, mp_ping);
11077   S (mp_ping);
11078
11079   W (ret);
11080   return ret;
11081 }
11082
11083 static int
11084 api_gre_add_del_tunnel (vat_main_t * vam)
11085 {
11086   unformat_input_t *line_input = vam->input;
11087   vl_api_gre_add_del_tunnel_t *mp;
11088   ip4_address_t src4, dst4;
11089   ip6_address_t src6, dst6;
11090   u8 is_add = 1;
11091   u8 ipv4_set = 0;
11092   u8 ipv6_set = 0;
11093   u8 teb = 0;
11094   u8 src_set = 0;
11095   u8 dst_set = 0;
11096   u32 outer_fib_id = 0;
11097   int ret;
11098
11099   memset (&src4, 0, sizeof src4);
11100   memset (&dst4, 0, sizeof dst4);
11101   memset (&src6, 0, sizeof src6);
11102   memset (&dst6, 0, sizeof dst6);
11103
11104   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11105     {
11106       if (unformat (line_input, "del"))
11107         is_add = 0;
11108       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
11109         {
11110           src_set = 1;
11111           ipv4_set = 1;
11112         }
11113       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
11114         {
11115           dst_set = 1;
11116           ipv4_set = 1;
11117         }
11118       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
11119         {
11120           src_set = 1;
11121           ipv6_set = 1;
11122         }
11123       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
11124         {
11125           dst_set = 1;
11126           ipv6_set = 1;
11127         }
11128       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
11129         ;
11130       else if (unformat (line_input, "teb"))
11131         teb = 1;
11132       else
11133         {
11134           errmsg ("parse error '%U'", format_unformat_error, line_input);
11135           return -99;
11136         }
11137     }
11138
11139   if (src_set == 0)
11140     {
11141       errmsg ("tunnel src address not specified");
11142       return -99;
11143     }
11144   if (dst_set == 0)
11145     {
11146       errmsg ("tunnel dst address not specified");
11147       return -99;
11148     }
11149   if (ipv4_set && ipv6_set)
11150     {
11151       errmsg ("both IPv4 and IPv6 addresses specified");
11152       return -99;
11153     }
11154
11155
11156   M (GRE_ADD_DEL_TUNNEL, mp);
11157
11158   if (ipv4_set)
11159     {
11160       clib_memcpy (&mp->src_address, &src4, 4);
11161       clib_memcpy (&mp->dst_address, &dst4, 4);
11162     }
11163   else
11164     {
11165       clib_memcpy (&mp->src_address, &src6, 16);
11166       clib_memcpy (&mp->dst_address, &dst6, 16);
11167     }
11168   mp->outer_fib_id = ntohl (outer_fib_id);
11169   mp->is_add = is_add;
11170   mp->teb = teb;
11171   mp->is_ipv6 = ipv6_set;
11172
11173   S (mp);
11174   W (ret);
11175   return ret;
11176 }
11177
11178 static void vl_api_gre_tunnel_details_t_handler
11179   (vl_api_gre_tunnel_details_t * mp)
11180 {
11181   vat_main_t *vam = &vat_main;
11182   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
11183   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
11184
11185   print (vam->ofp, "%11d%24U%24U%6d%14d",
11186          ntohl (mp->sw_if_index),
11187          format_ip46_address, &src, IP46_TYPE_ANY,
11188          format_ip46_address, &dst, IP46_TYPE_ANY,
11189          mp->teb, ntohl (mp->outer_fib_id));
11190 }
11191
11192 static void vl_api_gre_tunnel_details_t_handler_json
11193   (vl_api_gre_tunnel_details_t * mp)
11194 {
11195   vat_main_t *vam = &vat_main;
11196   vat_json_node_t *node = NULL;
11197   struct in_addr ip4;
11198   struct in6_addr ip6;
11199
11200   if (VAT_JSON_ARRAY != vam->json_tree.type)
11201     {
11202       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11203       vat_json_init_array (&vam->json_tree);
11204     }
11205   node = vat_json_array_add (&vam->json_tree);
11206
11207   vat_json_init_object (node);
11208   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11209   if (!mp->is_ipv6)
11210     {
11211       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
11212       vat_json_object_add_ip4 (node, "src_address", ip4);
11213       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
11214       vat_json_object_add_ip4 (node, "dst_address", ip4);
11215     }
11216   else
11217     {
11218       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
11219       vat_json_object_add_ip6 (node, "src_address", ip6);
11220       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
11221       vat_json_object_add_ip6 (node, "dst_address", ip6);
11222     }
11223   vat_json_object_add_uint (node, "teb", mp->teb);
11224   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
11225   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
11226 }
11227
11228 static int
11229 api_gre_tunnel_dump (vat_main_t * vam)
11230 {
11231   unformat_input_t *i = vam->input;
11232   vl_api_gre_tunnel_dump_t *mp;
11233   vl_api_control_ping_t *mp_ping;
11234   u32 sw_if_index;
11235   u8 sw_if_index_set = 0;
11236   int ret;
11237
11238   /* Parse args required to build the message */
11239   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11240     {
11241       if (unformat (i, "sw_if_index %d", &sw_if_index))
11242         sw_if_index_set = 1;
11243       else
11244         break;
11245     }
11246
11247   if (sw_if_index_set == 0)
11248     {
11249       sw_if_index = ~0;
11250     }
11251
11252   if (!vam->json_output)
11253     {
11254       print (vam->ofp, "%11s%24s%24s%6s%14s",
11255              "sw_if_index", "src_address", "dst_address", "teb",
11256              "outer_fib_id");
11257     }
11258
11259   /* Get list of gre-tunnel interfaces */
11260   M (GRE_TUNNEL_DUMP, mp);
11261
11262   mp->sw_if_index = htonl (sw_if_index);
11263
11264   S (mp);
11265
11266   /* Use a control ping for synchronization */
11267   M (CONTROL_PING, mp_ping);
11268   S (mp_ping);
11269
11270   W (ret);
11271   return ret;
11272 }
11273
11274 static int
11275 api_l2_fib_clear_table (vat_main_t * vam)
11276 {
11277 //  unformat_input_t * i = vam->input;
11278   vl_api_l2_fib_clear_table_t *mp;
11279   int ret;
11280
11281   M (L2_FIB_CLEAR_TABLE, mp);
11282
11283   S (mp);
11284   W (ret);
11285   return ret;
11286 }
11287
11288 static int
11289 api_l2_interface_efp_filter (vat_main_t * vam)
11290 {
11291   unformat_input_t *i = vam->input;
11292   vl_api_l2_interface_efp_filter_t *mp;
11293   u32 sw_if_index;
11294   u8 enable = 1;
11295   u8 sw_if_index_set = 0;
11296   int ret;
11297
11298   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11299     {
11300       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11301         sw_if_index_set = 1;
11302       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11303         sw_if_index_set = 1;
11304       else if (unformat (i, "enable"))
11305         enable = 1;
11306       else if (unformat (i, "disable"))
11307         enable = 0;
11308       else
11309         {
11310           clib_warning ("parse error '%U'", format_unformat_error, i);
11311           return -99;
11312         }
11313     }
11314
11315   if (sw_if_index_set == 0)
11316     {
11317       errmsg ("missing sw_if_index");
11318       return -99;
11319     }
11320
11321   M (L2_INTERFACE_EFP_FILTER, mp);
11322
11323   mp->sw_if_index = ntohl (sw_if_index);
11324   mp->enable_disable = enable;
11325
11326   S (mp);
11327   W (ret);
11328   return ret;
11329 }
11330
11331 #define foreach_vtr_op                          \
11332 _("disable",  L2_VTR_DISABLED)                  \
11333 _("push-1",  L2_VTR_PUSH_1)                     \
11334 _("push-2",  L2_VTR_PUSH_2)                     \
11335 _("pop-1",  L2_VTR_POP_1)                       \
11336 _("pop-2",  L2_VTR_POP_2)                       \
11337 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
11338 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
11339 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
11340 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
11341
11342 static int
11343 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
11344 {
11345   unformat_input_t *i = vam->input;
11346   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
11347   u32 sw_if_index;
11348   u8 sw_if_index_set = 0;
11349   u8 vtr_op_set = 0;
11350   u32 vtr_op = 0;
11351   u32 push_dot1q = 1;
11352   u32 tag1 = ~0;
11353   u32 tag2 = ~0;
11354   int ret;
11355
11356   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11357     {
11358       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11359         sw_if_index_set = 1;
11360       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11361         sw_if_index_set = 1;
11362       else if (unformat (i, "vtr_op %d", &vtr_op))
11363         vtr_op_set = 1;
11364 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
11365       foreach_vtr_op
11366 #undef _
11367         else if (unformat (i, "push_dot1q %d", &push_dot1q))
11368         ;
11369       else if (unformat (i, "tag1 %d", &tag1))
11370         ;
11371       else if (unformat (i, "tag2 %d", &tag2))
11372         ;
11373       else
11374         {
11375           clib_warning ("parse error '%U'", format_unformat_error, i);
11376           return -99;
11377         }
11378     }
11379
11380   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
11381     {
11382       errmsg ("missing vtr operation or sw_if_index");
11383       return -99;
11384     }
11385
11386   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
11387   mp->sw_if_index = ntohl (sw_if_index);
11388   mp->vtr_op = ntohl (vtr_op);
11389   mp->push_dot1q = ntohl (push_dot1q);
11390   mp->tag1 = ntohl (tag1);
11391   mp->tag2 = ntohl (tag2);
11392
11393   S (mp);
11394   W (ret);
11395   return ret;
11396 }
11397
11398 static int
11399 api_create_vhost_user_if (vat_main_t * vam)
11400 {
11401   unformat_input_t *i = vam->input;
11402   vl_api_create_vhost_user_if_t *mp;
11403   u8 *file_name;
11404   u8 is_server = 0;
11405   u8 file_name_set = 0;
11406   u32 custom_dev_instance = ~0;
11407   u8 hwaddr[6];
11408   u8 use_custom_mac = 0;
11409   u8 *tag = 0;
11410   int ret;
11411   u8 operation_mode = VHOST_USER_POLLING_MODE;
11412
11413   /* Shut up coverity */
11414   memset (hwaddr, 0, sizeof (hwaddr));
11415
11416   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11417     {
11418       if (unformat (i, "socket %s", &file_name))
11419         {
11420           file_name_set = 1;
11421         }
11422       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11423         ;
11424       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
11425         use_custom_mac = 1;
11426       else if (unformat (i, "server"))
11427         is_server = 1;
11428       else if (unformat (i, "tag %s", &tag))
11429         ;
11430       else if (unformat (i, "mode %U",
11431                          api_unformat_vhost_user_operation_mode,
11432                          &operation_mode))
11433         ;
11434       else
11435         break;
11436     }
11437
11438   if (file_name_set == 0)
11439     {
11440       errmsg ("missing socket file name");
11441       return -99;
11442     }
11443
11444   if (vec_len (file_name) > 255)
11445     {
11446       errmsg ("socket file name too long");
11447       return -99;
11448     }
11449   vec_add1 (file_name, 0);
11450
11451   M (CREATE_VHOST_USER_IF, mp);
11452
11453   mp->operation_mode = operation_mode;
11454   mp->is_server = is_server;
11455   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11456   vec_free (file_name);
11457   if (custom_dev_instance != ~0)
11458     {
11459       mp->renumber = 1;
11460       mp->custom_dev_instance = ntohl (custom_dev_instance);
11461     }
11462   mp->use_custom_mac = use_custom_mac;
11463   clib_memcpy (mp->mac_address, hwaddr, 6);
11464   if (tag)
11465     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
11466   vec_free (tag);
11467
11468   S (mp);
11469   W (ret);
11470   return ret;
11471 }
11472
11473 static int
11474 api_modify_vhost_user_if (vat_main_t * vam)
11475 {
11476   unformat_input_t *i = vam->input;
11477   vl_api_modify_vhost_user_if_t *mp;
11478   u8 *file_name;
11479   u8 is_server = 0;
11480   u8 file_name_set = 0;
11481   u32 custom_dev_instance = ~0;
11482   u8 sw_if_index_set = 0;
11483   u32 sw_if_index = (u32) ~ 0;
11484   int ret;
11485   u8 operation_mode = VHOST_USER_POLLING_MODE;
11486
11487   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11488     {
11489       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11490         sw_if_index_set = 1;
11491       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11492         sw_if_index_set = 1;
11493       else if (unformat (i, "socket %s", &file_name))
11494         {
11495           file_name_set = 1;
11496         }
11497       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11498         ;
11499       else if (unformat (i, "server"))
11500         is_server = 1;
11501       else if (unformat (i, "mode %U",
11502                          api_unformat_vhost_user_operation_mode,
11503                          &operation_mode))
11504         ;
11505       else
11506         break;
11507     }
11508
11509   if (sw_if_index_set == 0)
11510     {
11511       errmsg ("missing sw_if_index or interface name");
11512       return -99;
11513     }
11514
11515   if (file_name_set == 0)
11516     {
11517       errmsg ("missing socket file name");
11518       return -99;
11519     }
11520
11521   if (vec_len (file_name) > 255)
11522     {
11523       errmsg ("socket file name too long");
11524       return -99;
11525     }
11526   vec_add1 (file_name, 0);
11527
11528   M (MODIFY_VHOST_USER_IF, mp);
11529
11530   mp->operation_mode = operation_mode;
11531   mp->sw_if_index = ntohl (sw_if_index);
11532   mp->is_server = is_server;
11533   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11534   vec_free (file_name);
11535   if (custom_dev_instance != ~0)
11536     {
11537       mp->renumber = 1;
11538       mp->custom_dev_instance = ntohl (custom_dev_instance);
11539     }
11540
11541   S (mp);
11542   W (ret);
11543   return ret;
11544 }
11545
11546 static int
11547 api_delete_vhost_user_if (vat_main_t * vam)
11548 {
11549   unformat_input_t *i = vam->input;
11550   vl_api_delete_vhost_user_if_t *mp;
11551   u32 sw_if_index = ~0;
11552   u8 sw_if_index_set = 0;
11553   int ret;
11554
11555   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11556     {
11557       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11558         sw_if_index_set = 1;
11559       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11560         sw_if_index_set = 1;
11561       else
11562         break;
11563     }
11564
11565   if (sw_if_index_set == 0)
11566     {
11567       errmsg ("missing sw_if_index or interface name");
11568       return -99;
11569     }
11570
11571
11572   M (DELETE_VHOST_USER_IF, mp);
11573
11574   mp->sw_if_index = ntohl (sw_if_index);
11575
11576   S (mp);
11577   W (ret);
11578   return ret;
11579 }
11580
11581 static void vl_api_sw_interface_vhost_user_details_t_handler
11582   (vl_api_sw_interface_vhost_user_details_t * mp)
11583 {
11584   vat_main_t *vam = &vat_main;
11585
11586   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %U %s",
11587          (char *) mp->interface_name,
11588          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11589          clib_net_to_host_u64 (mp->features), mp->is_server,
11590          ntohl (mp->num_regions), api_format_vhost_user_operation_mode,
11591          mp->operation_mode, (char *) mp->sock_filename);
11592   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
11593 }
11594
11595 static void vl_api_sw_interface_vhost_user_details_t_handler_json
11596   (vl_api_sw_interface_vhost_user_details_t * mp)
11597 {
11598   vat_main_t *vam = &vat_main;
11599   vat_json_node_t *node = NULL;
11600
11601   if (VAT_JSON_ARRAY != vam->json_tree.type)
11602     {
11603       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11604       vat_json_init_array (&vam->json_tree);
11605     }
11606   node = vat_json_array_add (&vam->json_tree);
11607
11608   vat_json_init_object (node);
11609   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11610   vat_json_object_add_string_copy (node, "interface_name",
11611                                    mp->interface_name);
11612   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11613                             ntohl (mp->virtio_net_hdr_sz));
11614   vat_json_object_add_uint (node, "features",
11615                             clib_net_to_host_u64 (mp->features));
11616   vat_json_object_add_uint (node, "is_server", mp->is_server);
11617   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11618   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11619   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11620   vat_json_object_add_uint (node, "mode", mp->operation_mode);
11621 }
11622
11623 static int
11624 api_sw_interface_vhost_user_dump (vat_main_t * vam)
11625 {
11626   vl_api_sw_interface_vhost_user_dump_t *mp;
11627   vl_api_control_ping_t *mp_ping;
11628   int ret;
11629   print (vam->ofp,
11630          "Interface name            idx hdr_sz features server regions mode"
11631          "      filename");
11632
11633   /* Get list of vhost-user interfaces */
11634   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
11635   S (mp);
11636
11637   /* Use a control ping for synchronization */
11638   M (CONTROL_PING, mp_ping);
11639   S (mp_ping);
11640
11641   W (ret);
11642   return ret;
11643 }
11644
11645 static int
11646 api_show_version (vat_main_t * vam)
11647 {
11648   vl_api_show_version_t *mp;
11649   int ret;
11650
11651   M (SHOW_VERSION, mp);
11652
11653   S (mp);
11654   W (ret);
11655   return ret;
11656 }
11657
11658
11659 static int
11660 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11661 {
11662   unformat_input_t *line_input = vam->input;
11663   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11664   ip4_address_t local4, remote4;
11665   ip6_address_t local6, remote6;
11666   u8 is_add = 1;
11667   u8 ipv4_set = 0, ipv6_set = 0;
11668   u8 local_set = 0;
11669   u8 remote_set = 0;
11670   u32 encap_vrf_id = 0;
11671   u32 decap_vrf_id = 0;
11672   u8 protocol = ~0;
11673   u32 vni;
11674   u8 vni_set = 0;
11675   int ret;
11676
11677   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11678     {
11679       if (unformat (line_input, "del"))
11680         is_add = 0;
11681       else if (unformat (line_input, "local %U",
11682                          unformat_ip4_address, &local4))
11683         {
11684           local_set = 1;
11685           ipv4_set = 1;
11686         }
11687       else if (unformat (line_input, "remote %U",
11688                          unformat_ip4_address, &remote4))
11689         {
11690           remote_set = 1;
11691           ipv4_set = 1;
11692         }
11693       else if (unformat (line_input, "local %U",
11694                          unformat_ip6_address, &local6))
11695         {
11696           local_set = 1;
11697           ipv6_set = 1;
11698         }
11699       else if (unformat (line_input, "remote %U",
11700                          unformat_ip6_address, &remote6))
11701         {
11702           remote_set = 1;
11703           ipv6_set = 1;
11704         }
11705       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11706         ;
11707       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11708         ;
11709       else if (unformat (line_input, "vni %d", &vni))
11710         vni_set = 1;
11711       else if (unformat (line_input, "next-ip4"))
11712         protocol = 1;
11713       else if (unformat (line_input, "next-ip6"))
11714         protocol = 2;
11715       else if (unformat (line_input, "next-ethernet"))
11716         protocol = 3;
11717       else if (unformat (line_input, "next-nsh"))
11718         protocol = 4;
11719       else
11720         {
11721           errmsg ("parse error '%U'", format_unformat_error, line_input);
11722           return -99;
11723         }
11724     }
11725
11726   if (local_set == 0)
11727     {
11728       errmsg ("tunnel local address not specified");
11729       return -99;
11730     }
11731   if (remote_set == 0)
11732     {
11733       errmsg ("tunnel remote address not specified");
11734       return -99;
11735     }
11736   if (ipv4_set && ipv6_set)
11737     {
11738       errmsg ("both IPv4 and IPv6 addresses specified");
11739       return -99;
11740     }
11741
11742   if (vni_set == 0)
11743     {
11744       errmsg ("vni not specified");
11745       return -99;
11746     }
11747
11748   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
11749
11750
11751   if (ipv6_set)
11752     {
11753       clib_memcpy (&mp->local, &local6, sizeof (local6));
11754       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11755     }
11756   else
11757     {
11758       clib_memcpy (&mp->local, &local4, sizeof (local4));
11759       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11760     }
11761
11762   mp->encap_vrf_id = ntohl (encap_vrf_id);
11763   mp->decap_vrf_id = ntohl (decap_vrf_id);
11764   mp->protocol = protocol;
11765   mp->vni = ntohl (vni);
11766   mp->is_add = is_add;
11767   mp->is_ipv6 = ipv6_set;
11768
11769   S (mp);
11770   W (ret);
11771   return ret;
11772 }
11773
11774 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11775   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11776 {
11777   vat_main_t *vam = &vat_main;
11778
11779   print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11780          ntohl (mp->sw_if_index),
11781          format_ip46_address, &(mp->local[0]),
11782          format_ip46_address, &(mp->remote[0]),
11783          ntohl (mp->vni),
11784          ntohl (mp->protocol),
11785          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11786 }
11787
11788 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11789   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11790 {
11791   vat_main_t *vam = &vat_main;
11792   vat_json_node_t *node = NULL;
11793   struct in_addr ip4;
11794   struct in6_addr ip6;
11795
11796   if (VAT_JSON_ARRAY != vam->json_tree.type)
11797     {
11798       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11799       vat_json_init_array (&vam->json_tree);
11800     }
11801   node = vat_json_array_add (&vam->json_tree);
11802
11803   vat_json_init_object (node);
11804   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11805   if (mp->is_ipv6)
11806     {
11807       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11808       vat_json_object_add_ip6 (node, "local", ip6);
11809       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11810       vat_json_object_add_ip6 (node, "remote", ip6);
11811     }
11812   else
11813     {
11814       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11815       vat_json_object_add_ip4 (node, "local", ip4);
11816       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11817       vat_json_object_add_ip4 (node, "remote", ip4);
11818     }
11819   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11820   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11821   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11822   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11823   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11824 }
11825
11826 static int
11827 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11828 {
11829   unformat_input_t *i = vam->input;
11830   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11831   vl_api_control_ping_t *mp_ping;
11832   u32 sw_if_index;
11833   u8 sw_if_index_set = 0;
11834   int ret;
11835
11836   /* Parse args required to build the message */
11837   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11838     {
11839       if (unformat (i, "sw_if_index %d", &sw_if_index))
11840         sw_if_index_set = 1;
11841       else
11842         break;
11843     }
11844
11845   if (sw_if_index_set == 0)
11846     {
11847       sw_if_index = ~0;
11848     }
11849
11850   if (!vam->json_output)
11851     {
11852       print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11853              "sw_if_index", "local", "remote", "vni",
11854              "protocol", "encap_vrf_id", "decap_vrf_id");
11855     }
11856
11857   /* Get list of vxlan-tunnel interfaces */
11858   M (VXLAN_GPE_TUNNEL_DUMP, mp);
11859
11860   mp->sw_if_index = htonl (sw_if_index);
11861
11862   S (mp);
11863
11864   /* Use a control ping for synchronization */
11865   M (CONTROL_PING, mp_ping);
11866   S (mp_ping);
11867
11868   W (ret);
11869   return ret;
11870 }
11871
11872 u8 *
11873 format_l2_fib_mac_address (u8 * s, va_list * args)
11874 {
11875   u8 *a = va_arg (*args, u8 *);
11876
11877   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11878                  a[2], a[3], a[4], a[5], a[6], a[7]);
11879 }
11880
11881 static void vl_api_l2_fib_table_entry_t_handler
11882   (vl_api_l2_fib_table_entry_t * mp)
11883 {
11884   vat_main_t *vam = &vat_main;
11885
11886   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11887          "       %d       %d     %d",
11888          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11889          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11890          mp->bvi_mac);
11891 }
11892
11893 static void vl_api_l2_fib_table_entry_t_handler_json
11894   (vl_api_l2_fib_table_entry_t * mp)
11895 {
11896   vat_main_t *vam = &vat_main;
11897   vat_json_node_t *node = NULL;
11898
11899   if (VAT_JSON_ARRAY != vam->json_tree.type)
11900     {
11901       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11902       vat_json_init_array (&vam->json_tree);
11903     }
11904   node = vat_json_array_add (&vam->json_tree);
11905
11906   vat_json_init_object (node);
11907   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11908   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11909   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11910   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11911   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11912   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11913 }
11914
11915 static int
11916 api_l2_fib_table_dump (vat_main_t * vam)
11917 {
11918   unformat_input_t *i = vam->input;
11919   vl_api_l2_fib_table_dump_t *mp;
11920   vl_api_control_ping_t *mp_ping;
11921   u32 bd_id;
11922   u8 bd_id_set = 0;
11923   int ret;
11924
11925   /* Parse args required to build the message */
11926   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11927     {
11928       if (unformat (i, "bd_id %d", &bd_id))
11929         bd_id_set = 1;
11930       else
11931         break;
11932     }
11933
11934   if (bd_id_set == 0)
11935     {
11936       errmsg ("missing bridge domain");
11937       return -99;
11938     }
11939
11940   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
11941
11942   /* Get list of l2 fib entries */
11943   M (L2_FIB_TABLE_DUMP, mp);
11944
11945   mp->bd_id = ntohl (bd_id);
11946   S (mp);
11947
11948   /* Use a control ping for synchronization */
11949   M (CONTROL_PING, mp_ping);
11950   S (mp_ping);
11951
11952   W (ret);
11953   return ret;
11954 }
11955
11956
11957 static int
11958 api_interface_name_renumber (vat_main_t * vam)
11959 {
11960   unformat_input_t *line_input = vam->input;
11961   vl_api_interface_name_renumber_t *mp;
11962   u32 sw_if_index = ~0;
11963   u32 new_show_dev_instance = ~0;
11964   int ret;
11965
11966   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11967     {
11968       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
11969                     &sw_if_index))
11970         ;
11971       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11972         ;
11973       else if (unformat (line_input, "new_show_dev_instance %d",
11974                          &new_show_dev_instance))
11975         ;
11976       else
11977         break;
11978     }
11979
11980   if (sw_if_index == ~0)
11981     {
11982       errmsg ("missing interface name or sw_if_index");
11983       return -99;
11984     }
11985
11986   if (new_show_dev_instance == ~0)
11987     {
11988       errmsg ("missing new_show_dev_instance");
11989       return -99;
11990     }
11991
11992   M (INTERFACE_NAME_RENUMBER, mp);
11993
11994   mp->sw_if_index = ntohl (sw_if_index);
11995   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11996
11997   S (mp);
11998   W (ret);
11999   return ret;
12000 }
12001
12002 static int
12003 api_want_ip4_arp_events (vat_main_t * vam)
12004 {
12005   unformat_input_t *line_input = vam->input;
12006   vl_api_want_ip4_arp_events_t *mp;
12007   ip4_address_t address;
12008   int address_set = 0;
12009   u32 enable_disable = 1;
12010   int ret;
12011
12012   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12013     {
12014       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
12015         address_set = 1;
12016       else if (unformat (line_input, "del"))
12017         enable_disable = 0;
12018       else
12019         break;
12020     }
12021
12022   if (address_set == 0)
12023     {
12024       errmsg ("missing addresses");
12025       return -99;
12026     }
12027
12028   M (WANT_IP4_ARP_EVENTS, mp);
12029   mp->enable_disable = enable_disable;
12030   mp->pid = htonl (getpid ());
12031   mp->address = address.as_u32;
12032
12033   S (mp);
12034   W (ret);
12035   return ret;
12036 }
12037
12038 static int
12039 api_want_ip6_nd_events (vat_main_t * vam)
12040 {
12041   unformat_input_t *line_input = vam->input;
12042   vl_api_want_ip6_nd_events_t *mp;
12043   ip6_address_t address;
12044   int address_set = 0;
12045   u32 enable_disable = 1;
12046   int ret;
12047
12048   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12049     {
12050       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
12051         address_set = 1;
12052       else if (unformat (line_input, "del"))
12053         enable_disable = 0;
12054       else
12055         break;
12056     }
12057
12058   if (address_set == 0)
12059     {
12060       errmsg ("missing addresses");
12061       return -99;
12062     }
12063
12064   M (WANT_IP6_ND_EVENTS, mp);
12065   mp->enable_disable = enable_disable;
12066   mp->pid = htonl (getpid ());
12067   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
12068
12069   S (mp);
12070   W (ret);
12071   return ret;
12072 }
12073
12074 static int
12075 api_input_acl_set_interface (vat_main_t * vam)
12076 {
12077   unformat_input_t *i = vam->input;
12078   vl_api_input_acl_set_interface_t *mp;
12079   u32 sw_if_index;
12080   int sw_if_index_set;
12081   u32 ip4_table_index = ~0;
12082   u32 ip6_table_index = ~0;
12083   u32 l2_table_index = ~0;
12084   u8 is_add = 1;
12085   int ret;
12086
12087   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12088     {
12089       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12090         sw_if_index_set = 1;
12091       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12092         sw_if_index_set = 1;
12093       else if (unformat (i, "del"))
12094         is_add = 0;
12095       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12096         ;
12097       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12098         ;
12099       else if (unformat (i, "l2-table %d", &l2_table_index))
12100         ;
12101       else
12102         {
12103           clib_warning ("parse error '%U'", format_unformat_error, i);
12104           return -99;
12105         }
12106     }
12107
12108   if (sw_if_index_set == 0)
12109     {
12110       errmsg ("missing interface name or sw_if_index");
12111       return -99;
12112     }
12113
12114   M (INPUT_ACL_SET_INTERFACE, mp);
12115
12116   mp->sw_if_index = ntohl (sw_if_index);
12117   mp->ip4_table_index = ntohl (ip4_table_index);
12118   mp->ip6_table_index = ntohl (ip6_table_index);
12119   mp->l2_table_index = ntohl (l2_table_index);
12120   mp->is_add = is_add;
12121
12122   S (mp);
12123   W (ret);
12124   return ret;
12125 }
12126
12127 static int
12128 api_ip_address_dump (vat_main_t * vam)
12129 {
12130   unformat_input_t *i = vam->input;
12131   vl_api_ip_address_dump_t *mp;
12132   vl_api_control_ping_t *mp_ping;
12133   u32 sw_if_index = ~0;
12134   u8 sw_if_index_set = 0;
12135   u8 ipv4_set = 0;
12136   u8 ipv6_set = 0;
12137   int ret;
12138
12139   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12140     {
12141       if (unformat (i, "sw_if_index %d", &sw_if_index))
12142         sw_if_index_set = 1;
12143       else
12144         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12145         sw_if_index_set = 1;
12146       else if (unformat (i, "ipv4"))
12147         ipv4_set = 1;
12148       else if (unformat (i, "ipv6"))
12149         ipv6_set = 1;
12150       else
12151         break;
12152     }
12153
12154   if (ipv4_set && ipv6_set)
12155     {
12156       errmsg ("ipv4 and ipv6 flags cannot be both set");
12157       return -99;
12158     }
12159
12160   if ((!ipv4_set) && (!ipv6_set))
12161     {
12162       errmsg ("no ipv4 nor ipv6 flag set");
12163       return -99;
12164     }
12165
12166   if (sw_if_index_set == 0)
12167     {
12168       errmsg ("missing interface name or sw_if_index");
12169       return -99;
12170     }
12171
12172   vam->current_sw_if_index = sw_if_index;
12173   vam->is_ipv6 = ipv6_set;
12174
12175   M (IP_ADDRESS_DUMP, mp);
12176   mp->sw_if_index = ntohl (sw_if_index);
12177   mp->is_ipv6 = ipv6_set;
12178   S (mp);
12179
12180   /* Use a control ping for synchronization */
12181   M (CONTROL_PING, mp_ping);
12182   S (mp_ping);
12183
12184   W (ret);
12185   return ret;
12186 }
12187
12188 static int
12189 api_ip_dump (vat_main_t * vam)
12190 {
12191   vl_api_ip_dump_t *mp;
12192   vl_api_control_ping_t *mp_ping;
12193   unformat_input_t *in = vam->input;
12194   int ipv4_set = 0;
12195   int ipv6_set = 0;
12196   int is_ipv6;
12197   int i;
12198   int ret;
12199
12200   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
12201     {
12202       if (unformat (in, "ipv4"))
12203         ipv4_set = 1;
12204       else if (unformat (in, "ipv6"))
12205         ipv6_set = 1;
12206       else
12207         break;
12208     }
12209
12210   if (ipv4_set && ipv6_set)
12211     {
12212       errmsg ("ipv4 and ipv6 flags cannot be both set");
12213       return -99;
12214     }
12215
12216   if ((!ipv4_set) && (!ipv6_set))
12217     {
12218       errmsg ("no ipv4 nor ipv6 flag set");
12219       return -99;
12220     }
12221
12222   is_ipv6 = ipv6_set;
12223   vam->is_ipv6 = is_ipv6;
12224
12225   /* free old data */
12226   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
12227     {
12228       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
12229     }
12230   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
12231
12232   M (IP_DUMP, mp);
12233   mp->is_ipv6 = ipv6_set;
12234   S (mp);
12235
12236   /* Use a control ping for synchronization */
12237   M (CONTROL_PING, mp_ping);
12238   S (mp_ping);
12239
12240   W (ret);
12241   return ret;
12242 }
12243
12244 static int
12245 api_ipsec_spd_add_del (vat_main_t * vam)
12246 {
12247   unformat_input_t *i = vam->input;
12248   vl_api_ipsec_spd_add_del_t *mp;
12249   u32 spd_id = ~0;
12250   u8 is_add = 1;
12251   int ret;
12252
12253   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12254     {
12255       if (unformat (i, "spd_id %d", &spd_id))
12256         ;
12257       else if (unformat (i, "del"))
12258         is_add = 0;
12259       else
12260         {
12261           clib_warning ("parse error '%U'", format_unformat_error, i);
12262           return -99;
12263         }
12264     }
12265   if (spd_id == ~0)
12266     {
12267       errmsg ("spd_id must be set");
12268       return -99;
12269     }
12270
12271   M (IPSEC_SPD_ADD_DEL, mp);
12272
12273   mp->spd_id = ntohl (spd_id);
12274   mp->is_add = is_add;
12275
12276   S (mp);
12277   W (ret);
12278   return ret;
12279 }
12280
12281 static int
12282 api_ipsec_interface_add_del_spd (vat_main_t * vam)
12283 {
12284   unformat_input_t *i = vam->input;
12285   vl_api_ipsec_interface_add_del_spd_t *mp;
12286   u32 sw_if_index;
12287   u8 sw_if_index_set = 0;
12288   u32 spd_id = (u32) ~ 0;
12289   u8 is_add = 1;
12290   int ret;
12291
12292   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12293     {
12294       if (unformat (i, "del"))
12295         is_add = 0;
12296       else if (unformat (i, "spd_id %d", &spd_id))
12297         ;
12298       else
12299         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12300         sw_if_index_set = 1;
12301       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12302         sw_if_index_set = 1;
12303       else
12304         {
12305           clib_warning ("parse error '%U'", format_unformat_error, i);
12306           return -99;
12307         }
12308
12309     }
12310
12311   if (spd_id == (u32) ~ 0)
12312     {
12313       errmsg ("spd_id must be set");
12314       return -99;
12315     }
12316
12317   if (sw_if_index_set == 0)
12318     {
12319       errmsg ("missing interface name or sw_if_index");
12320       return -99;
12321     }
12322
12323   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
12324
12325   mp->spd_id = ntohl (spd_id);
12326   mp->sw_if_index = ntohl (sw_if_index);
12327   mp->is_add = is_add;
12328
12329   S (mp);
12330   W (ret);
12331   return ret;
12332 }
12333
12334 static int
12335 api_ipsec_spd_add_del_entry (vat_main_t * vam)
12336 {
12337   unformat_input_t *i = vam->input;
12338   vl_api_ipsec_spd_add_del_entry_t *mp;
12339   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
12340   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
12341   i32 priority = 0;
12342   u32 rport_start = 0, rport_stop = (u32) ~ 0;
12343   u32 lport_start = 0, lport_stop = (u32) ~ 0;
12344   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
12345   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
12346   int ret;
12347
12348   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
12349   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
12350   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
12351   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
12352   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
12353   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
12354
12355   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12356     {
12357       if (unformat (i, "del"))
12358         is_add = 0;
12359       if (unformat (i, "outbound"))
12360         is_outbound = 1;
12361       if (unformat (i, "inbound"))
12362         is_outbound = 0;
12363       else if (unformat (i, "spd_id %d", &spd_id))
12364         ;
12365       else if (unformat (i, "sa_id %d", &sa_id))
12366         ;
12367       else if (unformat (i, "priority %d", &priority))
12368         ;
12369       else if (unformat (i, "protocol %d", &protocol))
12370         ;
12371       else if (unformat (i, "lport_start %d", &lport_start))
12372         ;
12373       else if (unformat (i, "lport_stop %d", &lport_stop))
12374         ;
12375       else if (unformat (i, "rport_start %d", &rport_start))
12376         ;
12377       else if (unformat (i, "rport_stop %d", &rport_stop))
12378         ;
12379       else
12380         if (unformat
12381             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
12382         {
12383           is_ipv6 = 0;
12384           is_ip_any = 0;
12385         }
12386       else
12387         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
12388         {
12389           is_ipv6 = 0;
12390           is_ip_any = 0;
12391         }
12392       else
12393         if (unformat
12394             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
12395         {
12396           is_ipv6 = 0;
12397           is_ip_any = 0;
12398         }
12399       else
12400         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
12401         {
12402           is_ipv6 = 0;
12403           is_ip_any = 0;
12404         }
12405       else
12406         if (unformat
12407             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
12408         {
12409           is_ipv6 = 1;
12410           is_ip_any = 0;
12411         }
12412       else
12413         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
12414         {
12415           is_ipv6 = 1;
12416           is_ip_any = 0;
12417         }
12418       else
12419         if (unformat
12420             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
12421         {
12422           is_ipv6 = 1;
12423           is_ip_any = 0;
12424         }
12425       else
12426         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
12427         {
12428           is_ipv6 = 1;
12429           is_ip_any = 0;
12430         }
12431       else
12432         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
12433         {
12434           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
12435             {
12436               clib_warning ("unsupported action: 'resolve'");
12437               return -99;
12438             }
12439         }
12440       else
12441         {
12442           clib_warning ("parse error '%U'", format_unformat_error, i);
12443           return -99;
12444         }
12445
12446     }
12447
12448   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
12449
12450   mp->spd_id = ntohl (spd_id);
12451   mp->priority = ntohl (priority);
12452   mp->is_outbound = is_outbound;
12453
12454   mp->is_ipv6 = is_ipv6;
12455   if (is_ipv6 || is_ip_any)
12456     {
12457       clib_memcpy (mp->remote_address_start, &raddr6_start,
12458                    sizeof (ip6_address_t));
12459       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
12460                    sizeof (ip6_address_t));
12461       clib_memcpy (mp->local_address_start, &laddr6_start,
12462                    sizeof (ip6_address_t));
12463       clib_memcpy (mp->local_address_stop, &laddr6_stop,
12464                    sizeof (ip6_address_t));
12465     }
12466   else
12467     {
12468       clib_memcpy (mp->remote_address_start, &raddr4_start,
12469                    sizeof (ip4_address_t));
12470       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
12471                    sizeof (ip4_address_t));
12472       clib_memcpy (mp->local_address_start, &laddr4_start,
12473                    sizeof (ip4_address_t));
12474       clib_memcpy (mp->local_address_stop, &laddr4_stop,
12475                    sizeof (ip4_address_t));
12476     }
12477   mp->protocol = (u8) protocol;
12478   mp->local_port_start = ntohs ((u16) lport_start);
12479   mp->local_port_stop = ntohs ((u16) lport_stop);
12480   mp->remote_port_start = ntohs ((u16) rport_start);
12481   mp->remote_port_stop = ntohs ((u16) rport_stop);
12482   mp->policy = (u8) policy;
12483   mp->sa_id = ntohl (sa_id);
12484   mp->is_add = is_add;
12485   mp->is_ip_any = is_ip_any;
12486   S (mp);
12487   W (ret);
12488   return ret;
12489 }
12490
12491 static int
12492 api_ipsec_sad_add_del_entry (vat_main_t * vam)
12493 {
12494   unformat_input_t *i = vam->input;
12495   vl_api_ipsec_sad_add_del_entry_t *mp;
12496   u32 sad_id = 0, spi = 0;
12497   u8 *ck = 0, *ik = 0;
12498   u8 is_add = 1;
12499
12500   u8 protocol = IPSEC_PROTOCOL_AH;
12501   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
12502   u32 crypto_alg = 0, integ_alg = 0;
12503   ip4_address_t tun_src4;
12504   ip4_address_t tun_dst4;
12505   ip6_address_t tun_src6;
12506   ip6_address_t tun_dst6;
12507   int ret;
12508
12509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12510     {
12511       if (unformat (i, "del"))
12512         is_add = 0;
12513       else if (unformat (i, "sad_id %d", &sad_id))
12514         ;
12515       else if (unformat (i, "spi %d", &spi))
12516         ;
12517       else if (unformat (i, "esp"))
12518         protocol = IPSEC_PROTOCOL_ESP;
12519       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
12520         {
12521           is_tunnel = 1;
12522           is_tunnel_ipv6 = 0;
12523         }
12524       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
12525         {
12526           is_tunnel = 1;
12527           is_tunnel_ipv6 = 0;
12528         }
12529       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
12530         {
12531           is_tunnel = 1;
12532           is_tunnel_ipv6 = 1;
12533         }
12534       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
12535         {
12536           is_tunnel = 1;
12537           is_tunnel_ipv6 = 1;
12538         }
12539       else
12540         if (unformat
12541             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12542         {
12543           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12544               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12545             {
12546               clib_warning ("unsupported crypto-alg: '%U'",
12547                             format_ipsec_crypto_alg, crypto_alg);
12548               return -99;
12549             }
12550         }
12551       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12552         ;
12553       else
12554         if (unformat
12555             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12556         {
12557           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12558               integ_alg >= IPSEC_INTEG_N_ALG)
12559             {
12560               clib_warning ("unsupported integ-alg: '%U'",
12561                             format_ipsec_integ_alg, integ_alg);
12562               return -99;
12563             }
12564         }
12565       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12566         ;
12567       else
12568         {
12569           clib_warning ("parse error '%U'", format_unformat_error, i);
12570           return -99;
12571         }
12572
12573     }
12574
12575   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
12576
12577   mp->sad_id = ntohl (sad_id);
12578   mp->is_add = is_add;
12579   mp->protocol = protocol;
12580   mp->spi = ntohl (spi);
12581   mp->is_tunnel = is_tunnel;
12582   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12583   mp->crypto_algorithm = crypto_alg;
12584   mp->integrity_algorithm = integ_alg;
12585   mp->crypto_key_length = vec_len (ck);
12586   mp->integrity_key_length = vec_len (ik);
12587
12588   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12589     mp->crypto_key_length = sizeof (mp->crypto_key);
12590
12591   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12592     mp->integrity_key_length = sizeof (mp->integrity_key);
12593
12594   if (ck)
12595     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12596   if (ik)
12597     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12598
12599   if (is_tunnel)
12600     {
12601       if (is_tunnel_ipv6)
12602         {
12603           clib_memcpy (mp->tunnel_src_address, &tun_src6,
12604                        sizeof (ip6_address_t));
12605           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12606                        sizeof (ip6_address_t));
12607         }
12608       else
12609         {
12610           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12611                        sizeof (ip4_address_t));
12612           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12613                        sizeof (ip4_address_t));
12614         }
12615     }
12616
12617   S (mp);
12618   W (ret);
12619   return ret;
12620 }
12621
12622 static int
12623 api_ipsec_sa_set_key (vat_main_t * vam)
12624 {
12625   unformat_input_t *i = vam->input;
12626   vl_api_ipsec_sa_set_key_t *mp;
12627   u32 sa_id;
12628   u8 *ck = 0, *ik = 0;
12629   int ret;
12630
12631   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12632     {
12633       if (unformat (i, "sa_id %d", &sa_id))
12634         ;
12635       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12636         ;
12637       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12638         ;
12639       else
12640         {
12641           clib_warning ("parse error '%U'", format_unformat_error, i);
12642           return -99;
12643         }
12644     }
12645
12646   M (IPSEC_SA_SET_KEY, mp);
12647
12648   mp->sa_id = ntohl (sa_id);
12649   mp->crypto_key_length = vec_len (ck);
12650   mp->integrity_key_length = vec_len (ik);
12651
12652   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12653     mp->crypto_key_length = sizeof (mp->crypto_key);
12654
12655   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12656     mp->integrity_key_length = sizeof (mp->integrity_key);
12657
12658   if (ck)
12659     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12660   if (ik)
12661     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12662
12663   S (mp);
12664   W (ret);
12665   return ret;
12666 }
12667
12668 static int
12669 api_ikev2_profile_add_del (vat_main_t * vam)
12670 {
12671   unformat_input_t *i = vam->input;
12672   vl_api_ikev2_profile_add_del_t *mp;
12673   u8 is_add = 1;
12674   u8 *name = 0;
12675   int ret;
12676
12677   const char *valid_chars = "a-zA-Z0-9_";
12678
12679   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12680     {
12681       if (unformat (i, "del"))
12682         is_add = 0;
12683       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12684         vec_add1 (name, 0);
12685       else
12686         {
12687           errmsg ("parse error '%U'", format_unformat_error, i);
12688           return -99;
12689         }
12690     }
12691
12692   if (!vec_len (name))
12693     {
12694       errmsg ("profile name must be specified");
12695       return -99;
12696     }
12697
12698   if (vec_len (name) > 64)
12699     {
12700       errmsg ("profile name too long");
12701       return -99;
12702     }
12703
12704   M (IKEV2_PROFILE_ADD_DEL, mp);
12705
12706   clib_memcpy (mp->name, name, vec_len (name));
12707   mp->is_add = is_add;
12708   vec_free (name);
12709
12710   S (mp);
12711   W (ret);
12712   return ret;
12713 }
12714
12715 static int
12716 api_ikev2_profile_set_auth (vat_main_t * vam)
12717 {
12718   unformat_input_t *i = vam->input;
12719   vl_api_ikev2_profile_set_auth_t *mp;
12720   u8 *name = 0;
12721   u8 *data = 0;
12722   u32 auth_method = 0;
12723   u8 is_hex = 0;
12724   int ret;
12725
12726   const char *valid_chars = "a-zA-Z0-9_";
12727
12728   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12729     {
12730       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12731         vec_add1 (name, 0);
12732       else if (unformat (i, "auth_method %U",
12733                          unformat_ikev2_auth_method, &auth_method))
12734         ;
12735       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12736         is_hex = 1;
12737       else if (unformat (i, "auth_data %v", &data))
12738         ;
12739       else
12740         {
12741           errmsg ("parse error '%U'", format_unformat_error, i);
12742           return -99;
12743         }
12744     }
12745
12746   if (!vec_len (name))
12747     {
12748       errmsg ("profile name must be specified");
12749       return -99;
12750     }
12751
12752   if (vec_len (name) > 64)
12753     {
12754       errmsg ("profile name too long");
12755       return -99;
12756     }
12757
12758   if (!vec_len (data))
12759     {
12760       errmsg ("auth_data must be specified");
12761       return -99;
12762     }
12763
12764   if (!auth_method)
12765     {
12766       errmsg ("auth_method must be specified");
12767       return -99;
12768     }
12769
12770   M (IKEV2_PROFILE_SET_AUTH, mp);
12771
12772   mp->is_hex = is_hex;
12773   mp->auth_method = (u8) auth_method;
12774   mp->data_len = vec_len (data);
12775   clib_memcpy (mp->name, name, vec_len (name));
12776   clib_memcpy (mp->data, data, vec_len (data));
12777   vec_free (name);
12778   vec_free (data);
12779
12780   S (mp);
12781   W (ret);
12782   return ret;
12783 }
12784
12785 static int
12786 api_ikev2_profile_set_id (vat_main_t * vam)
12787 {
12788   unformat_input_t *i = vam->input;
12789   vl_api_ikev2_profile_set_id_t *mp;
12790   u8 *name = 0;
12791   u8 *data = 0;
12792   u8 is_local = 0;
12793   u32 id_type = 0;
12794   ip4_address_t ip4;
12795   int ret;
12796
12797   const char *valid_chars = "a-zA-Z0-9_";
12798
12799   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12800     {
12801       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12802         vec_add1 (name, 0);
12803       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12804         ;
12805       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12806         {
12807           data = vec_new (u8, 4);
12808           clib_memcpy (data, ip4.as_u8, 4);
12809         }
12810       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12811         ;
12812       else if (unformat (i, "id_data %v", &data))
12813         ;
12814       else if (unformat (i, "local"))
12815         is_local = 1;
12816       else if (unformat (i, "remote"))
12817         is_local = 0;
12818       else
12819         {
12820           errmsg ("parse error '%U'", format_unformat_error, i);
12821           return -99;
12822         }
12823     }
12824
12825   if (!vec_len (name))
12826     {
12827       errmsg ("profile name must be specified");
12828       return -99;
12829     }
12830
12831   if (vec_len (name) > 64)
12832     {
12833       errmsg ("profile name too long");
12834       return -99;
12835     }
12836
12837   if (!vec_len (data))
12838     {
12839       errmsg ("id_data must be specified");
12840       return -99;
12841     }
12842
12843   if (!id_type)
12844     {
12845       errmsg ("id_type must be specified");
12846       return -99;
12847     }
12848
12849   M (IKEV2_PROFILE_SET_ID, mp);
12850
12851   mp->is_local = is_local;
12852   mp->id_type = (u8) id_type;
12853   mp->data_len = vec_len (data);
12854   clib_memcpy (mp->name, name, vec_len (name));
12855   clib_memcpy (mp->data, data, vec_len (data));
12856   vec_free (name);
12857   vec_free (data);
12858
12859   S (mp);
12860   W (ret);
12861   return ret;
12862 }
12863
12864 static int
12865 api_ikev2_profile_set_ts (vat_main_t * vam)
12866 {
12867   unformat_input_t *i = vam->input;
12868   vl_api_ikev2_profile_set_ts_t *mp;
12869   u8 *name = 0;
12870   u8 is_local = 0;
12871   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12872   ip4_address_t start_addr, end_addr;
12873
12874   const char *valid_chars = "a-zA-Z0-9_";
12875   int ret;
12876
12877   start_addr.as_u32 = 0;
12878   end_addr.as_u32 = (u32) ~ 0;
12879
12880   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12881     {
12882       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12883         vec_add1 (name, 0);
12884       else if (unformat (i, "protocol %d", &proto))
12885         ;
12886       else if (unformat (i, "start_port %d", &start_port))
12887         ;
12888       else if (unformat (i, "end_port %d", &end_port))
12889         ;
12890       else
12891         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12892         ;
12893       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12894         ;
12895       else if (unformat (i, "local"))
12896         is_local = 1;
12897       else if (unformat (i, "remote"))
12898         is_local = 0;
12899       else
12900         {
12901           errmsg ("parse error '%U'", format_unformat_error, i);
12902           return -99;
12903         }
12904     }
12905
12906   if (!vec_len (name))
12907     {
12908       errmsg ("profile name must be specified");
12909       return -99;
12910     }
12911
12912   if (vec_len (name) > 64)
12913     {
12914       errmsg ("profile name too long");
12915       return -99;
12916     }
12917
12918   M (IKEV2_PROFILE_SET_TS, mp);
12919
12920   mp->is_local = is_local;
12921   mp->proto = (u8) proto;
12922   mp->start_port = (u16) start_port;
12923   mp->end_port = (u16) end_port;
12924   mp->start_addr = start_addr.as_u32;
12925   mp->end_addr = end_addr.as_u32;
12926   clib_memcpy (mp->name, name, vec_len (name));
12927   vec_free (name);
12928
12929   S (mp);
12930   W (ret);
12931   return ret;
12932 }
12933
12934 static int
12935 api_ikev2_set_local_key (vat_main_t * vam)
12936 {
12937   unformat_input_t *i = vam->input;
12938   vl_api_ikev2_set_local_key_t *mp;
12939   u8 *file = 0;
12940   int ret;
12941
12942   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12943     {
12944       if (unformat (i, "file %v", &file))
12945         vec_add1 (file, 0);
12946       else
12947         {
12948           errmsg ("parse error '%U'", format_unformat_error, i);
12949           return -99;
12950         }
12951     }
12952
12953   if (!vec_len (file))
12954     {
12955       errmsg ("RSA key file must be specified");
12956       return -99;
12957     }
12958
12959   if (vec_len (file) > 256)
12960     {
12961       errmsg ("file name too long");
12962       return -99;
12963     }
12964
12965   M (IKEV2_SET_LOCAL_KEY, mp);
12966
12967   clib_memcpy (mp->key_file, file, vec_len (file));
12968   vec_free (file);
12969
12970   S (mp);
12971   W (ret);
12972   return ret;
12973 }
12974
12975 static int
12976 api_ikev2_set_responder (vat_main_t * vam)
12977 {
12978   unformat_input_t *i = vam->input;
12979   vl_api_ikev2_set_responder_t *mp;
12980   int ret;
12981   u8 *name = 0;
12982   u32 sw_if_index = ~0;
12983   ip4_address_t address;
12984
12985   const char *valid_chars = "a-zA-Z0-9_";
12986
12987   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12988     {
12989       if (unformat
12990           (i, "%U interface %d address %U", unformat_token, valid_chars,
12991            &name, &sw_if_index, unformat_ip4_address, &address))
12992         vec_add1 (name, 0);
12993       else
12994         {
12995           errmsg ("parse error '%U'", format_unformat_error, i);
12996           return -99;
12997         }
12998     }
12999
13000   if (!vec_len (name))
13001     {
13002       errmsg ("profile name must be specified");
13003       return -99;
13004     }
13005
13006   if (vec_len (name) > 64)
13007     {
13008       errmsg ("profile name too long");
13009       return -99;
13010     }
13011
13012   M (IKEV2_SET_RESPONDER, mp);
13013
13014   clib_memcpy (mp->name, name, vec_len (name));
13015   vec_free (name);
13016
13017   mp->sw_if_index = sw_if_index;
13018   clib_memcpy (mp->address, &address, sizeof (address));
13019
13020   S (mp);
13021   W (ret);
13022   return ret;
13023 }
13024
13025 static int
13026 api_ikev2_set_ike_transforms (vat_main_t * vam)
13027 {
13028   unformat_input_t *i = vam->input;
13029   vl_api_ikev2_set_ike_transforms_t *mp;
13030   int ret;
13031   u8 *name = 0;
13032   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13033
13034   const char *valid_chars = "a-zA-Z0-9_";
13035
13036   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13037     {
13038       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13039                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13040         vec_add1 (name, 0);
13041       else
13042         {
13043           errmsg ("parse error '%U'", format_unformat_error, i);
13044           return -99;
13045         }
13046     }
13047
13048   if (!vec_len (name))
13049     {
13050       errmsg ("profile name must be specified");
13051       return -99;
13052     }
13053
13054   if (vec_len (name) > 64)
13055     {
13056       errmsg ("profile name too long");
13057       return -99;
13058     }
13059
13060   M (IKEV2_SET_IKE_TRANSFORMS, mp);
13061
13062   clib_memcpy (mp->name, name, vec_len (name));
13063   vec_free (name);
13064   mp->crypto_alg = crypto_alg;
13065   mp->crypto_key_size = crypto_key_size;
13066   mp->integ_alg = integ_alg;
13067   mp->dh_group = dh_group;
13068
13069   S (mp);
13070   W (ret);
13071   return ret;
13072 }
13073
13074
13075 static int
13076 api_ikev2_set_esp_transforms (vat_main_t * vam)
13077 {
13078   unformat_input_t *i = vam->input;
13079   vl_api_ikev2_set_esp_transforms_t *mp;
13080   int ret;
13081   u8 *name = 0;
13082   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13083
13084   const char *valid_chars = "a-zA-Z0-9_";
13085
13086   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13087     {
13088       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13089                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13090         vec_add1 (name, 0);
13091       else
13092         {
13093           errmsg ("parse error '%U'", format_unformat_error, i);
13094           return -99;
13095         }
13096     }
13097
13098   if (!vec_len (name))
13099     {
13100       errmsg ("profile name must be specified");
13101       return -99;
13102     }
13103
13104   if (vec_len (name) > 64)
13105     {
13106       errmsg ("profile name too long");
13107       return -99;
13108     }
13109
13110   M (IKEV2_SET_ESP_TRANSFORMS, mp);
13111
13112   clib_memcpy (mp->name, name, vec_len (name));
13113   vec_free (name);
13114   mp->crypto_alg = crypto_alg;
13115   mp->crypto_key_size = crypto_key_size;
13116   mp->integ_alg = integ_alg;
13117   mp->dh_group = dh_group;
13118
13119   S (mp);
13120   W (ret);
13121   return ret;
13122 }
13123
13124 static int
13125 api_ikev2_set_sa_lifetime (vat_main_t * vam)
13126 {
13127   unformat_input_t *i = vam->input;
13128   vl_api_ikev2_set_sa_lifetime_t *mp;
13129   int ret;
13130   u8 *name = 0;
13131   u64 lifetime, lifetime_maxdata;
13132   u32 lifetime_jitter, handover;
13133
13134   const char *valid_chars = "a-zA-Z0-9_";
13135
13136   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13137     {
13138       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
13139                     &lifetime, &lifetime_jitter, &handover,
13140                     &lifetime_maxdata))
13141         vec_add1 (name, 0);
13142       else
13143         {
13144           errmsg ("parse error '%U'", format_unformat_error, i);
13145           return -99;
13146         }
13147     }
13148
13149   if (!vec_len (name))
13150     {
13151       errmsg ("profile name must be specified");
13152       return -99;
13153     }
13154
13155   if (vec_len (name) > 64)
13156     {
13157       errmsg ("profile name too long");
13158       return -99;
13159     }
13160
13161   M (IKEV2_SET_SA_LIFETIME, mp);
13162
13163   clib_memcpy (mp->name, name, vec_len (name));
13164   vec_free (name);
13165   mp->lifetime = lifetime;
13166   mp->lifetime_jitter = lifetime_jitter;
13167   mp->handover = handover;
13168   mp->lifetime_maxdata = lifetime_maxdata;
13169
13170   S (mp);
13171   W (ret);
13172   return ret;
13173 }
13174
13175 static int
13176 api_ikev2_initiate_sa_init (vat_main_t * vam)
13177 {
13178   unformat_input_t *i = vam->input;
13179   vl_api_ikev2_initiate_sa_init_t *mp;
13180   int ret;
13181   u8 *name = 0;
13182
13183   const char *valid_chars = "a-zA-Z0-9_";
13184
13185   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13186     {
13187       if (unformat (i, "%U", unformat_token, valid_chars, &name))
13188         vec_add1 (name, 0);
13189       else
13190         {
13191           errmsg ("parse error '%U'", format_unformat_error, i);
13192           return -99;
13193         }
13194     }
13195
13196   if (!vec_len (name))
13197     {
13198       errmsg ("profile name must be specified");
13199       return -99;
13200     }
13201
13202   if (vec_len (name) > 64)
13203     {
13204       errmsg ("profile name too long");
13205       return -99;
13206     }
13207
13208   M (IKEV2_INITIATE_SA_INIT, mp);
13209
13210   clib_memcpy (mp->name, name, vec_len (name));
13211   vec_free (name);
13212
13213   S (mp);
13214   W (ret);
13215   return ret;
13216 }
13217
13218 static int
13219 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
13220 {
13221   unformat_input_t *i = vam->input;
13222   vl_api_ikev2_initiate_del_ike_sa_t *mp;
13223   int ret;
13224   u64 ispi;
13225
13226
13227   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13228     {
13229       if (unformat (i, "%lx", &ispi))
13230         ;
13231       else
13232         {
13233           errmsg ("parse error '%U'", format_unformat_error, i);
13234           return -99;
13235         }
13236     }
13237
13238   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
13239
13240   mp->ispi = ispi;
13241
13242   S (mp);
13243   W (ret);
13244   return ret;
13245 }
13246
13247 static int
13248 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
13249 {
13250   unformat_input_t *i = vam->input;
13251   vl_api_ikev2_initiate_del_child_sa_t *mp;
13252   int ret;
13253   u32 ispi;
13254
13255
13256   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13257     {
13258       if (unformat (i, "%x", &ispi))
13259         ;
13260       else
13261         {
13262           errmsg ("parse error '%U'", format_unformat_error, i);
13263           return -99;
13264         }
13265     }
13266
13267   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
13268
13269   mp->ispi = ispi;
13270
13271   S (mp);
13272   W (ret);
13273   return ret;
13274 }
13275
13276 static int
13277 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
13278 {
13279   unformat_input_t *i = vam->input;
13280   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
13281   int ret;
13282   u32 ispi;
13283
13284
13285   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13286     {
13287       if (unformat (i, "%x", &ispi))
13288         ;
13289       else
13290         {
13291           errmsg ("parse error '%U'", format_unformat_error, i);
13292           return -99;
13293         }
13294     }
13295
13296   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
13297
13298   mp->ispi = ispi;
13299
13300   S (mp);
13301   W (ret);
13302   return ret;
13303 }
13304
13305 /*
13306  * MAP
13307  */
13308 static int
13309 api_map_add_domain (vat_main_t * vam)
13310 {
13311   unformat_input_t *i = vam->input;
13312   vl_api_map_add_domain_t *mp;
13313
13314   ip4_address_t ip4_prefix;
13315   ip6_address_t ip6_prefix;
13316   ip6_address_t ip6_src;
13317   u32 num_m_args = 0;
13318   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
13319     0, psid_length = 0;
13320   u8 is_translation = 0;
13321   u32 mtu = 0;
13322   u32 ip6_src_len = 128;
13323   int ret;
13324
13325   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13326     {
13327       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
13328                     &ip4_prefix, &ip4_prefix_len))
13329         num_m_args++;
13330       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
13331                          &ip6_prefix, &ip6_prefix_len))
13332         num_m_args++;
13333       else
13334         if (unformat
13335             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
13336              &ip6_src_len))
13337         num_m_args++;
13338       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
13339         num_m_args++;
13340       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
13341         num_m_args++;
13342       else if (unformat (i, "psid-offset %d", &psid_offset))
13343         num_m_args++;
13344       else if (unformat (i, "psid-len %d", &psid_length))
13345         num_m_args++;
13346       else if (unformat (i, "mtu %d", &mtu))
13347         num_m_args++;
13348       else if (unformat (i, "map-t"))
13349         is_translation = 1;
13350       else
13351         {
13352           clib_warning ("parse error '%U'", format_unformat_error, i);
13353           return -99;
13354         }
13355     }
13356
13357   if (num_m_args < 3)
13358     {
13359       errmsg ("mandatory argument(s) missing");
13360       return -99;
13361     }
13362
13363   /* Construct the API message */
13364   M (MAP_ADD_DOMAIN, mp);
13365
13366   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
13367   mp->ip4_prefix_len = ip4_prefix_len;
13368
13369   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
13370   mp->ip6_prefix_len = ip6_prefix_len;
13371
13372   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
13373   mp->ip6_src_prefix_len = ip6_src_len;
13374
13375   mp->ea_bits_len = ea_bits_len;
13376   mp->psid_offset = psid_offset;
13377   mp->psid_length = psid_length;
13378   mp->is_translation = is_translation;
13379   mp->mtu = htons (mtu);
13380
13381   /* send it... */
13382   S (mp);
13383
13384   /* Wait for a reply, return good/bad news  */
13385   W (ret);
13386   return ret;
13387 }
13388
13389 static int
13390 api_map_del_domain (vat_main_t * vam)
13391 {
13392   unformat_input_t *i = vam->input;
13393   vl_api_map_del_domain_t *mp;
13394
13395   u32 num_m_args = 0;
13396   u32 index;
13397   int ret;
13398
13399   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13400     {
13401       if (unformat (i, "index %d", &index))
13402         num_m_args++;
13403       else
13404         {
13405           clib_warning ("parse error '%U'", format_unformat_error, i);
13406           return -99;
13407         }
13408     }
13409
13410   if (num_m_args != 1)
13411     {
13412       errmsg ("mandatory argument(s) missing");
13413       return -99;
13414     }
13415
13416   /* Construct the API message */
13417   M (MAP_DEL_DOMAIN, mp);
13418
13419   mp->index = ntohl (index);
13420
13421   /* send it... */
13422   S (mp);
13423
13424   /* Wait for a reply, return good/bad news  */
13425   W (ret);
13426   return ret;
13427 }
13428
13429 static int
13430 api_map_add_del_rule (vat_main_t * vam)
13431 {
13432   unformat_input_t *i = vam->input;
13433   vl_api_map_add_del_rule_t *mp;
13434   u8 is_add = 1;
13435   ip6_address_t ip6_dst;
13436   u32 num_m_args = 0, index, psid = 0;
13437   int ret;
13438
13439   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13440     {
13441       if (unformat (i, "index %d", &index))
13442         num_m_args++;
13443       else if (unformat (i, "psid %d", &psid))
13444         num_m_args++;
13445       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
13446         num_m_args++;
13447       else if (unformat (i, "del"))
13448         {
13449           is_add = 0;
13450         }
13451       else
13452         {
13453           clib_warning ("parse error '%U'", format_unformat_error, i);
13454           return -99;
13455         }
13456     }
13457
13458   /* Construct the API message */
13459   M (MAP_ADD_DEL_RULE, mp);
13460
13461   mp->index = ntohl (index);
13462   mp->is_add = is_add;
13463   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
13464   mp->psid = ntohs (psid);
13465
13466   /* send it... */
13467   S (mp);
13468
13469   /* Wait for a reply, return good/bad news  */
13470   W (ret);
13471   return ret;
13472 }
13473
13474 static int
13475 api_map_domain_dump (vat_main_t * vam)
13476 {
13477   vl_api_map_domain_dump_t *mp;
13478   vl_api_control_ping_t *mp_ping;
13479   int ret;
13480
13481   /* Construct the API message */
13482   M (MAP_DOMAIN_DUMP, mp);
13483
13484   /* send it... */
13485   S (mp);
13486
13487   /* Use a control ping for synchronization */
13488   M (CONTROL_PING, mp_ping);
13489   S (mp_ping);
13490
13491   W (ret);
13492   return ret;
13493 }
13494
13495 static int
13496 api_map_rule_dump (vat_main_t * vam)
13497 {
13498   unformat_input_t *i = vam->input;
13499   vl_api_map_rule_dump_t *mp;
13500   vl_api_control_ping_t *mp_ping;
13501   u32 domain_index = ~0;
13502   int ret;
13503
13504   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13505     {
13506       if (unformat (i, "index %u", &domain_index))
13507         ;
13508       else
13509         break;
13510     }
13511
13512   if (domain_index == ~0)
13513     {
13514       clib_warning ("parse error: domain index expected");
13515       return -99;
13516     }
13517
13518   /* Construct the API message */
13519   M (MAP_RULE_DUMP, mp);
13520
13521   mp->domain_index = htonl (domain_index);
13522
13523   /* send it... */
13524   S (mp);
13525
13526   /* Use a control ping for synchronization */
13527   M (CONTROL_PING, mp_ping);
13528   S (mp_ping);
13529
13530   W (ret);
13531   return ret;
13532 }
13533
13534 static void vl_api_map_add_domain_reply_t_handler
13535   (vl_api_map_add_domain_reply_t * mp)
13536 {
13537   vat_main_t *vam = &vat_main;
13538   i32 retval = ntohl (mp->retval);
13539
13540   if (vam->async_mode)
13541     {
13542       vam->async_errors += (retval < 0);
13543     }
13544   else
13545     {
13546       vam->retval = retval;
13547       vam->result_ready = 1;
13548     }
13549 }
13550
13551 static void vl_api_map_add_domain_reply_t_handler_json
13552   (vl_api_map_add_domain_reply_t * mp)
13553 {
13554   vat_main_t *vam = &vat_main;
13555   vat_json_node_t node;
13556
13557   vat_json_init_object (&node);
13558   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
13559   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
13560
13561   vat_json_print (vam->ofp, &node);
13562   vat_json_free (&node);
13563
13564   vam->retval = ntohl (mp->retval);
13565   vam->result_ready = 1;
13566 }
13567
13568 static int
13569 api_get_first_msg_id (vat_main_t * vam)
13570 {
13571   vl_api_get_first_msg_id_t *mp;
13572   unformat_input_t *i = vam->input;
13573   u8 *name;
13574   u8 name_set = 0;
13575   int ret;
13576
13577   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13578     {
13579       if (unformat (i, "client %s", &name))
13580         name_set = 1;
13581       else
13582         break;
13583     }
13584
13585   if (name_set == 0)
13586     {
13587       errmsg ("missing client name");
13588       return -99;
13589     }
13590   vec_add1 (name, 0);
13591
13592   if (vec_len (name) > 63)
13593     {
13594       errmsg ("client name too long");
13595       return -99;
13596     }
13597
13598   M (GET_FIRST_MSG_ID, mp);
13599   clib_memcpy (mp->name, name, vec_len (name));
13600   S (mp);
13601   W (ret);
13602   return ret;
13603 }
13604
13605 static int
13606 api_cop_interface_enable_disable (vat_main_t * vam)
13607 {
13608   unformat_input_t *line_input = vam->input;
13609   vl_api_cop_interface_enable_disable_t *mp;
13610   u32 sw_if_index = ~0;
13611   u8 enable_disable = 1;
13612   int ret;
13613
13614   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13615     {
13616       if (unformat (line_input, "disable"))
13617         enable_disable = 0;
13618       if (unformat (line_input, "enable"))
13619         enable_disable = 1;
13620       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13621                          vam, &sw_if_index))
13622         ;
13623       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13624         ;
13625       else
13626         break;
13627     }
13628
13629   if (sw_if_index == ~0)
13630     {
13631       errmsg ("missing interface name or sw_if_index");
13632       return -99;
13633     }
13634
13635   /* Construct the API message */
13636   M (COP_INTERFACE_ENABLE_DISABLE, mp);
13637   mp->sw_if_index = ntohl (sw_if_index);
13638   mp->enable_disable = enable_disable;
13639
13640   /* send it... */
13641   S (mp);
13642   /* Wait for the reply */
13643   W (ret);
13644   return ret;
13645 }
13646
13647 static int
13648 api_cop_whitelist_enable_disable (vat_main_t * vam)
13649 {
13650   unformat_input_t *line_input = vam->input;
13651   vl_api_cop_whitelist_enable_disable_t *mp;
13652   u32 sw_if_index = ~0;
13653   u8 ip4 = 0, ip6 = 0, default_cop = 0;
13654   u32 fib_id = 0;
13655   int ret;
13656
13657   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13658     {
13659       if (unformat (line_input, "ip4"))
13660         ip4 = 1;
13661       else if (unformat (line_input, "ip6"))
13662         ip6 = 1;
13663       else if (unformat (line_input, "default"))
13664         default_cop = 1;
13665       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13666                          vam, &sw_if_index))
13667         ;
13668       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13669         ;
13670       else if (unformat (line_input, "fib-id %d", &fib_id))
13671         ;
13672       else
13673         break;
13674     }
13675
13676   if (sw_if_index == ~0)
13677     {
13678       errmsg ("missing interface name or sw_if_index");
13679       return -99;
13680     }
13681
13682   /* Construct the API message */
13683   M (COP_WHITELIST_ENABLE_DISABLE, mp);
13684   mp->sw_if_index = ntohl (sw_if_index);
13685   mp->fib_id = ntohl (fib_id);
13686   mp->ip4 = ip4;
13687   mp->ip6 = ip6;
13688   mp->default_cop = default_cop;
13689
13690   /* send it... */
13691   S (mp);
13692   /* Wait for the reply */
13693   W (ret);
13694   return ret;
13695 }
13696
13697 static int
13698 api_get_node_graph (vat_main_t * vam)
13699 {
13700   vl_api_get_node_graph_t *mp;
13701   int ret;
13702
13703   M (GET_NODE_GRAPH, mp);
13704
13705   /* send it... */
13706   S (mp);
13707   /* Wait for the reply */
13708   W (ret);
13709   return ret;
13710 }
13711
13712 /* *INDENT-OFF* */
13713 /** Used for parsing LISP eids */
13714 typedef CLIB_PACKED(struct{
13715   u8 addr[16];   /**< eid address */
13716   u32 len;       /**< prefix length if IP */
13717   u8 type;      /**< type of eid */
13718 }) lisp_eid_vat_t;
13719 /* *INDENT-ON* */
13720
13721 static uword
13722 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
13723 {
13724   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
13725
13726   memset (a, 0, sizeof (a[0]));
13727
13728   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
13729     {
13730       a->type = 0;              /* ipv4 type */
13731     }
13732   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
13733     {
13734       a->type = 1;              /* ipv6 type */
13735     }
13736   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
13737     {
13738       a->type = 2;              /* mac type */
13739     }
13740   else
13741     {
13742       return 0;
13743     }
13744
13745   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
13746     {
13747       return 0;
13748     }
13749
13750   return 1;
13751 }
13752
13753 static int
13754 lisp_eid_size_vat (u8 type)
13755 {
13756   switch (type)
13757     {
13758     case 0:
13759       return 4;
13760     case 1:
13761       return 16;
13762     case 2:
13763       return 6;
13764     }
13765   return 0;
13766 }
13767
13768 static void
13769 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
13770 {
13771   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
13772 }
13773
13774 static int
13775 api_one_add_del_locator_set (vat_main_t * vam)
13776 {
13777   unformat_input_t *input = vam->input;
13778   vl_api_one_add_del_locator_set_t *mp;
13779   u8 is_add = 1;
13780   u8 *locator_set_name = NULL;
13781   u8 locator_set_name_set = 0;
13782   vl_api_local_locator_t locator, *locators = 0;
13783   u32 sw_if_index, priority, weight;
13784   u32 data_len = 0;
13785
13786   int ret;
13787   /* Parse args required to build the message */
13788   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13789     {
13790       if (unformat (input, "del"))
13791         {
13792           is_add = 0;
13793         }
13794       else if (unformat (input, "locator-set %s", &locator_set_name))
13795         {
13796           locator_set_name_set = 1;
13797         }
13798       else if (unformat (input, "sw_if_index %u p %u w %u",
13799                          &sw_if_index, &priority, &weight))
13800         {
13801           locator.sw_if_index = htonl (sw_if_index);
13802           locator.priority = priority;
13803           locator.weight = weight;
13804           vec_add1 (locators, locator);
13805         }
13806       else
13807         if (unformat
13808             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
13809              &sw_if_index, &priority, &weight))
13810         {
13811           locator.sw_if_index = htonl (sw_if_index);
13812           locator.priority = priority;
13813           locator.weight = weight;
13814           vec_add1 (locators, locator);
13815         }
13816       else
13817         break;
13818     }
13819
13820   if (locator_set_name_set == 0)
13821     {
13822       errmsg ("missing locator-set name");
13823       vec_free (locators);
13824       return -99;
13825     }
13826
13827   if (vec_len (locator_set_name) > 64)
13828     {
13829       errmsg ("locator-set name too long");
13830       vec_free (locator_set_name);
13831       vec_free (locators);
13832       return -99;
13833     }
13834   vec_add1 (locator_set_name, 0);
13835
13836   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
13837
13838   /* Construct the API message */
13839   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
13840
13841   mp->is_add = is_add;
13842   clib_memcpy (mp->locator_set_name, locator_set_name,
13843                vec_len (locator_set_name));
13844   vec_free (locator_set_name);
13845
13846   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
13847   if (locators)
13848     clib_memcpy (mp->locators, locators, data_len);
13849   vec_free (locators);
13850
13851   /* send it... */
13852   S (mp);
13853
13854   /* Wait for a reply... */
13855   W (ret);
13856   return ret;
13857 }
13858
13859 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
13860
13861 static int
13862 api_one_add_del_locator (vat_main_t * vam)
13863 {
13864   unformat_input_t *input = vam->input;
13865   vl_api_one_add_del_locator_t *mp;
13866   u32 tmp_if_index = ~0;
13867   u32 sw_if_index = ~0;
13868   u8 sw_if_index_set = 0;
13869   u8 sw_if_index_if_name_set = 0;
13870   u32 priority = ~0;
13871   u8 priority_set = 0;
13872   u32 weight = ~0;
13873   u8 weight_set = 0;
13874   u8 is_add = 1;
13875   u8 *locator_set_name = NULL;
13876   u8 locator_set_name_set = 0;
13877   int ret;
13878
13879   /* Parse args required to build the message */
13880   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13881     {
13882       if (unformat (input, "del"))
13883         {
13884           is_add = 0;
13885         }
13886       else if (unformat (input, "locator-set %s", &locator_set_name))
13887         {
13888           locator_set_name_set = 1;
13889         }
13890       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
13891                          &tmp_if_index))
13892         {
13893           sw_if_index_if_name_set = 1;
13894           sw_if_index = tmp_if_index;
13895         }
13896       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
13897         {
13898           sw_if_index_set = 1;
13899           sw_if_index = tmp_if_index;
13900         }
13901       else if (unformat (input, "p %d", &priority))
13902         {
13903           priority_set = 1;
13904         }
13905       else if (unformat (input, "w %d", &weight))
13906         {
13907           weight_set = 1;
13908         }
13909       else
13910         break;
13911     }
13912
13913   if (locator_set_name_set == 0)
13914     {
13915       errmsg ("missing locator-set name");
13916       return -99;
13917     }
13918
13919   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
13920     {
13921       errmsg ("missing sw_if_index");
13922       vec_free (locator_set_name);
13923       return -99;
13924     }
13925
13926   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
13927     {
13928       errmsg ("cannot use both params interface name and sw_if_index");
13929       vec_free (locator_set_name);
13930       return -99;
13931     }
13932
13933   if (priority_set == 0)
13934     {
13935       errmsg ("missing locator-set priority");
13936       vec_free (locator_set_name);
13937       return -99;
13938     }
13939
13940   if (weight_set == 0)
13941     {
13942       errmsg ("missing locator-set weight");
13943       vec_free (locator_set_name);
13944       return -99;
13945     }
13946
13947   if (vec_len (locator_set_name) > 64)
13948     {
13949       errmsg ("locator-set name too long");
13950       vec_free (locator_set_name);
13951       return -99;
13952     }
13953   vec_add1 (locator_set_name, 0);
13954
13955   /* Construct the API message */
13956   M (ONE_ADD_DEL_LOCATOR, mp);
13957
13958   mp->is_add = is_add;
13959   mp->sw_if_index = ntohl (sw_if_index);
13960   mp->priority = priority;
13961   mp->weight = weight;
13962   clib_memcpy (mp->locator_set_name, locator_set_name,
13963                vec_len (locator_set_name));
13964   vec_free (locator_set_name);
13965
13966   /* send it... */
13967   S (mp);
13968
13969   /* Wait for a reply... */
13970   W (ret);
13971   return ret;
13972 }
13973
13974 #define api_lisp_add_del_locator api_one_add_del_locator
13975
13976 uword
13977 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
13978 {
13979   u32 *key_id = va_arg (*args, u32 *);
13980   u8 *s = 0;
13981
13982   if (unformat (input, "%s", &s))
13983     {
13984       if (!strcmp ((char *) s, "sha1"))
13985         key_id[0] = HMAC_SHA_1_96;
13986       else if (!strcmp ((char *) s, "sha256"))
13987         key_id[0] = HMAC_SHA_256_128;
13988       else
13989         {
13990           clib_warning ("invalid key_id: '%s'", s);
13991           key_id[0] = HMAC_NO_KEY;
13992         }
13993     }
13994   else
13995     return 0;
13996
13997   vec_free (s);
13998   return 1;
13999 }
14000
14001 static int
14002 api_one_add_del_local_eid (vat_main_t * vam)
14003 {
14004   unformat_input_t *input = vam->input;
14005   vl_api_one_add_del_local_eid_t *mp;
14006   u8 is_add = 1;
14007   u8 eid_set = 0;
14008   lisp_eid_vat_t _eid, *eid = &_eid;
14009   u8 *locator_set_name = 0;
14010   u8 locator_set_name_set = 0;
14011   u32 vni = 0;
14012   u16 key_id = 0;
14013   u8 *key = 0;
14014   int ret;
14015
14016   /* Parse args required to build the message */
14017   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14018     {
14019       if (unformat (input, "del"))
14020         {
14021           is_add = 0;
14022         }
14023       else if (unformat (input, "vni %d", &vni))
14024         {
14025           ;
14026         }
14027       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14028         {
14029           eid_set = 1;
14030         }
14031       else if (unformat (input, "locator-set %s", &locator_set_name))
14032         {
14033           locator_set_name_set = 1;
14034         }
14035       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14036         ;
14037       else if (unformat (input, "secret-key %_%v%_", &key))
14038         ;
14039       else
14040         break;
14041     }
14042
14043   if (locator_set_name_set == 0)
14044     {
14045       errmsg ("missing locator-set name");
14046       return -99;
14047     }
14048
14049   if (0 == eid_set)
14050     {
14051       errmsg ("EID address not set!");
14052       vec_free (locator_set_name);
14053       return -99;
14054     }
14055
14056   if (key && (0 == key_id))
14057     {
14058       errmsg ("invalid key_id!");
14059       return -99;
14060     }
14061
14062   if (vec_len (key) > 64)
14063     {
14064       errmsg ("key too long");
14065       vec_free (key);
14066       return -99;
14067     }
14068
14069   if (vec_len (locator_set_name) > 64)
14070     {
14071       errmsg ("locator-set name too long");
14072       vec_free (locator_set_name);
14073       return -99;
14074     }
14075   vec_add1 (locator_set_name, 0);
14076
14077   /* Construct the API message */
14078   M (ONE_ADD_DEL_LOCAL_EID, mp);
14079
14080   mp->is_add = is_add;
14081   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14082   mp->eid_type = eid->type;
14083   mp->prefix_len = eid->len;
14084   mp->vni = clib_host_to_net_u32 (vni);
14085   mp->key_id = clib_host_to_net_u16 (key_id);
14086   clib_memcpy (mp->locator_set_name, locator_set_name,
14087                vec_len (locator_set_name));
14088   clib_memcpy (mp->key, key, vec_len (key));
14089
14090   vec_free (locator_set_name);
14091   vec_free (key);
14092
14093   /* send it... */
14094   S (mp);
14095
14096   /* Wait for a reply... */
14097   W (ret);
14098   return ret;
14099 }
14100
14101 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14102
14103 static int
14104 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14105 {
14106   u32 dp_table = 0, vni = 0;;
14107   unformat_input_t *input = vam->input;
14108   vl_api_gpe_add_del_fwd_entry_t *mp;
14109   u8 is_add = 1;
14110   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14111   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14112   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14113   u32 action = ~0, w;
14114   ip4_address_t rmt_rloc4, lcl_rloc4;
14115   ip6_address_t rmt_rloc6, lcl_rloc6;
14116   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14117   int ret;
14118
14119   memset (&rloc, 0, sizeof (rloc));
14120
14121   /* Parse args required to build the message */
14122   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14123     {
14124       if (unformat (input, "del"))
14125         is_add = 0;
14126       else if (unformat (input, "add"))
14127         is_add = 1;
14128       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14129         {
14130           rmt_eid_set = 1;
14131         }
14132       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14133         {
14134           lcl_eid_set = 1;
14135         }
14136       else if (unformat (input, "vrf %d", &dp_table))
14137         ;
14138       else if (unformat (input, "bd %d", &dp_table))
14139         ;
14140       else if (unformat (input, "vni %d", &vni))
14141         ;
14142       else if (unformat (input, "w %d", &w))
14143         {
14144           if (!curr_rloc)
14145             {
14146               errmsg ("No RLOC configured for setting priority/weight!");
14147               return -99;
14148             }
14149           curr_rloc->weight = w;
14150         }
14151       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14152                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14153         {
14154           rloc.is_ip4 = 1;
14155
14156           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
14157           rloc.weight = 0;
14158           vec_add1 (lcl_locs, rloc);
14159
14160           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
14161           vec_add1 (rmt_locs, rloc);
14162           /* weight saved in rmt loc */
14163           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14164         }
14165       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14166                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14167         {
14168           rloc.is_ip4 = 0;
14169           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
14170           rloc.weight = 0;
14171           vec_add1 (lcl_locs, rloc);
14172
14173           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
14174           vec_add1 (rmt_locs, rloc);
14175           /* weight saved in rmt loc */
14176           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14177         }
14178       else if (unformat (input, "action %d", &action))
14179         {
14180           ;
14181         }
14182       else
14183         {
14184           clib_warning ("parse error '%U'", format_unformat_error, input);
14185           return -99;
14186         }
14187     }
14188
14189   if (!rmt_eid_set)
14190     {
14191       errmsg ("remote eid addresses not set");
14192       return -99;
14193     }
14194
14195   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14196     {
14197       errmsg ("eid types don't match");
14198       return -99;
14199     }
14200
14201   if (0 == rmt_locs && (u32) ~ 0 == action)
14202     {
14203       errmsg ("action not set for negative mapping");
14204       return -99;
14205     }
14206
14207   /* Construct the API message */
14208   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14209       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14210
14211   mp->is_add = is_add;
14212   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
14213   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
14214   mp->eid_type = rmt_eid->type;
14215   mp->dp_table = clib_host_to_net_u32 (dp_table);
14216   mp->vni = clib_host_to_net_u32 (vni);
14217   mp->rmt_len = rmt_eid->len;
14218   mp->lcl_len = lcl_eid->len;
14219   mp->action = action;
14220
14221   if (0 != rmt_locs && 0 != lcl_locs)
14222     {
14223       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14224       clib_memcpy (mp->locs, lcl_locs,
14225                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14226
14227       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14228       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14229                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14230     }
14231   vec_free (lcl_locs);
14232   vec_free (rmt_locs);
14233
14234   /* send it... */
14235   S (mp);
14236
14237   /* Wait for a reply... */
14238   W (ret);
14239   return ret;
14240 }
14241
14242 static int
14243 api_one_add_del_map_server (vat_main_t * vam)
14244 {
14245   unformat_input_t *input = vam->input;
14246   vl_api_one_add_del_map_server_t *mp;
14247   u8 is_add = 1;
14248   u8 ipv4_set = 0;
14249   u8 ipv6_set = 0;
14250   ip4_address_t ipv4;
14251   ip6_address_t ipv6;
14252   int ret;
14253
14254   /* Parse args required to build the message */
14255   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14256     {
14257       if (unformat (input, "del"))
14258         {
14259           is_add = 0;
14260         }
14261       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14262         {
14263           ipv4_set = 1;
14264         }
14265       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14266         {
14267           ipv6_set = 1;
14268         }
14269       else
14270         break;
14271     }
14272
14273   if (ipv4_set && ipv6_set)
14274     {
14275       errmsg ("both eid v4 and v6 addresses set");
14276       return -99;
14277     }
14278
14279   if (!ipv4_set && !ipv6_set)
14280     {
14281       errmsg ("eid addresses not set");
14282       return -99;
14283     }
14284
14285   /* Construct the API message */
14286   M (ONE_ADD_DEL_MAP_SERVER, mp);
14287
14288   mp->is_add = is_add;
14289   if (ipv6_set)
14290     {
14291       mp->is_ipv6 = 1;
14292       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14293     }
14294   else
14295     {
14296       mp->is_ipv6 = 0;
14297       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14298     }
14299
14300   /* send it... */
14301   S (mp);
14302
14303   /* Wait for a reply... */
14304   W (ret);
14305   return ret;
14306 }
14307
14308 #define api_lisp_add_del_map_server api_one_add_del_map_server
14309
14310 static int
14311 api_one_add_del_map_resolver (vat_main_t * vam)
14312 {
14313   unformat_input_t *input = vam->input;
14314   vl_api_one_add_del_map_resolver_t *mp;
14315   u8 is_add = 1;
14316   u8 ipv4_set = 0;
14317   u8 ipv6_set = 0;
14318   ip4_address_t ipv4;
14319   ip6_address_t ipv6;
14320   int ret;
14321
14322   /* Parse args required to build the message */
14323   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14324     {
14325       if (unformat (input, "del"))
14326         {
14327           is_add = 0;
14328         }
14329       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14330         {
14331           ipv4_set = 1;
14332         }
14333       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14334         {
14335           ipv6_set = 1;
14336         }
14337       else
14338         break;
14339     }
14340
14341   if (ipv4_set && ipv6_set)
14342     {
14343       errmsg ("both eid v4 and v6 addresses set");
14344       return -99;
14345     }
14346
14347   if (!ipv4_set && !ipv6_set)
14348     {
14349       errmsg ("eid addresses not set");
14350       return -99;
14351     }
14352
14353   /* Construct the API message */
14354   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14355
14356   mp->is_add = is_add;
14357   if (ipv6_set)
14358     {
14359       mp->is_ipv6 = 1;
14360       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14361     }
14362   else
14363     {
14364       mp->is_ipv6 = 0;
14365       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14366     }
14367
14368   /* send it... */
14369   S (mp);
14370
14371   /* Wait for a reply... */
14372   W (ret);
14373   return ret;
14374 }
14375
14376 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14377
14378 static int
14379 api_lisp_gpe_enable_disable (vat_main_t * vam)
14380 {
14381   unformat_input_t *input = vam->input;
14382   vl_api_gpe_enable_disable_t *mp;
14383   u8 is_set = 0;
14384   u8 is_en = 1;
14385   int ret;
14386
14387   /* Parse args required to build the message */
14388   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14389     {
14390       if (unformat (input, "enable"))
14391         {
14392           is_set = 1;
14393           is_en = 1;
14394         }
14395       else if (unformat (input, "disable"))
14396         {
14397           is_set = 1;
14398           is_en = 0;
14399         }
14400       else
14401         break;
14402     }
14403
14404   if (is_set == 0)
14405     {
14406       errmsg ("Value not set");
14407       return -99;
14408     }
14409
14410   /* Construct the API message */
14411   M (GPE_ENABLE_DISABLE, mp);
14412
14413   mp->is_en = is_en;
14414
14415   /* send it... */
14416   S (mp);
14417
14418   /* Wait for a reply... */
14419   W (ret);
14420   return ret;
14421 }
14422
14423 static int
14424 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14425 {
14426   unformat_input_t *input = vam->input;
14427   vl_api_one_rloc_probe_enable_disable_t *mp;
14428   u8 is_set = 0;
14429   u8 is_en = 0;
14430   int ret;
14431
14432   /* Parse args required to build the message */
14433   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14434     {
14435       if (unformat (input, "enable"))
14436         {
14437           is_set = 1;
14438           is_en = 1;
14439         }
14440       else if (unformat (input, "disable"))
14441         is_set = 1;
14442       else
14443         break;
14444     }
14445
14446   if (!is_set)
14447     {
14448       errmsg ("Value not set");
14449       return -99;
14450     }
14451
14452   /* Construct the API message */
14453   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14454
14455   mp->is_enabled = is_en;
14456
14457   /* send it... */
14458   S (mp);
14459
14460   /* Wait for a reply... */
14461   W (ret);
14462   return ret;
14463 }
14464
14465 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14466
14467 static int
14468 api_one_map_register_enable_disable (vat_main_t * vam)
14469 {
14470   unformat_input_t *input = vam->input;
14471   vl_api_one_map_register_enable_disable_t *mp;
14472   u8 is_set = 0;
14473   u8 is_en = 0;
14474   int ret;
14475
14476   /* Parse args required to build the message */
14477   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14478     {
14479       if (unformat (input, "enable"))
14480         {
14481           is_set = 1;
14482           is_en = 1;
14483         }
14484       else if (unformat (input, "disable"))
14485         is_set = 1;
14486       else
14487         break;
14488     }
14489
14490   if (!is_set)
14491     {
14492       errmsg ("Value not set");
14493       return -99;
14494     }
14495
14496   /* Construct the API message */
14497   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14498
14499   mp->is_enabled = is_en;
14500
14501   /* send it... */
14502   S (mp);
14503
14504   /* Wait for a reply... */
14505   W (ret);
14506   return ret;
14507 }
14508
14509 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14510
14511 static int
14512 api_one_enable_disable (vat_main_t * vam)
14513 {
14514   unformat_input_t *input = vam->input;
14515   vl_api_one_enable_disable_t *mp;
14516   u8 is_set = 0;
14517   u8 is_en = 0;
14518   int ret;
14519
14520   /* Parse args required to build the message */
14521   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14522     {
14523       if (unformat (input, "enable"))
14524         {
14525           is_set = 1;
14526           is_en = 1;
14527         }
14528       else if (unformat (input, "disable"))
14529         {
14530           is_set = 1;
14531         }
14532       else
14533         break;
14534     }
14535
14536   if (!is_set)
14537     {
14538       errmsg ("Value not set");
14539       return -99;
14540     }
14541
14542   /* Construct the API message */
14543   M (ONE_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 #define api_lisp_enable_disable api_one_enable_disable
14556
14557 static int
14558 api_show_one_map_register_state (vat_main_t * vam)
14559 {
14560   vl_api_show_one_map_register_state_t *mp;
14561   int ret;
14562
14563   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
14564
14565   /* send */
14566   S (mp);
14567
14568   /* wait for reply */
14569   W (ret);
14570   return ret;
14571 }
14572
14573 #define api_show_lisp_map_register_state api_show_one_map_register_state
14574
14575 static int
14576 api_show_one_rloc_probe_state (vat_main_t * vam)
14577 {
14578   vl_api_show_one_rloc_probe_state_t *mp;
14579   int ret;
14580
14581   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
14582
14583   /* send */
14584   S (mp);
14585
14586   /* wait for reply */
14587   W (ret);
14588   return ret;
14589 }
14590
14591 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
14592
14593 static int
14594 api_one_stats_enable_disable (vat_main_t * vam)
14595 {
14596   vl_api_one_stats_enable_disable_t *mp;
14597   unformat_input_t *input = vam->input;
14598   u8 is_set = 0;
14599   u8 is_en = 0;
14600   int ret;
14601
14602   /* Parse args required to build the message */
14603   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14604     {
14605       if (unformat (input, "enable"))
14606         {
14607           is_set = 1;
14608           is_en = 1;
14609         }
14610       else if (unformat (input, "disable"))
14611         {
14612           is_set = 1;
14613         }
14614       else
14615         break;
14616     }
14617
14618   if (!is_set)
14619     {
14620       errmsg ("Value not set");
14621       return -99;
14622     }
14623
14624   M (ONE_STATS_ENABLE_DISABLE, mp);
14625   mp->is_en = is_en;
14626
14627   /* send */
14628   S (mp);
14629
14630   /* wait for reply */
14631   W (ret);
14632   return ret;
14633 }
14634
14635 static int
14636 api_show_one_stats_enable_disable (vat_main_t * vam)
14637 {
14638   vl_api_show_one_stats_enable_disable_t *mp;
14639   int ret;
14640
14641   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
14642
14643   /* send */
14644   S (mp);
14645
14646   /* wait for reply */
14647   W (ret);
14648   return ret;
14649 }
14650
14651 static int
14652 api_show_one_map_request_mode (vat_main_t * vam)
14653 {
14654   vl_api_show_one_map_request_mode_t *mp;
14655   int ret;
14656
14657   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
14658
14659   /* send */
14660   S (mp);
14661
14662   /* wait for reply */
14663   W (ret);
14664   return ret;
14665 }
14666
14667 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
14668
14669 static int
14670 api_one_map_request_mode (vat_main_t * vam)
14671 {
14672   unformat_input_t *input = vam->input;
14673   vl_api_one_map_request_mode_t *mp;
14674   u8 mode = 0;
14675   int ret;
14676
14677   /* Parse args required to build the message */
14678   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14679     {
14680       if (unformat (input, "dst-only"))
14681         mode = 0;
14682       else if (unformat (input, "src-dst"))
14683         mode = 1;
14684       else
14685         {
14686           errmsg ("parse error '%U'", format_unformat_error, input);
14687           return -99;
14688         }
14689     }
14690
14691   M (ONE_MAP_REQUEST_MODE, mp);
14692
14693   mp->mode = mode;
14694
14695   /* send */
14696   S (mp);
14697
14698   /* wait for reply */
14699   W (ret);
14700   return ret;
14701 }
14702
14703 #define api_lisp_map_request_mode api_one_map_request_mode
14704
14705 /**
14706  * Enable/disable ONE proxy ITR.
14707  *
14708  * @param vam vpp API test context
14709  * @return return code
14710  */
14711 static int
14712 api_one_pitr_set_locator_set (vat_main_t * vam)
14713 {
14714   u8 ls_name_set = 0;
14715   unformat_input_t *input = vam->input;
14716   vl_api_one_pitr_set_locator_set_t *mp;
14717   u8 is_add = 1;
14718   u8 *ls_name = 0;
14719   int ret;
14720
14721   /* Parse args required to build the message */
14722   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14723     {
14724       if (unformat (input, "del"))
14725         is_add = 0;
14726       else if (unformat (input, "locator-set %s", &ls_name))
14727         ls_name_set = 1;
14728       else
14729         {
14730           errmsg ("parse error '%U'", format_unformat_error, input);
14731           return -99;
14732         }
14733     }
14734
14735   if (!ls_name_set)
14736     {
14737       errmsg ("locator-set name not set!");
14738       return -99;
14739     }
14740
14741   M (ONE_PITR_SET_LOCATOR_SET, mp);
14742
14743   mp->is_add = is_add;
14744   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
14745   vec_free (ls_name);
14746
14747   /* send */
14748   S (mp);
14749
14750   /* wait for reply */
14751   W (ret);
14752   return ret;
14753 }
14754
14755 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
14756
14757 static int
14758 api_show_one_pitr (vat_main_t * vam)
14759 {
14760   vl_api_show_one_pitr_t *mp;
14761   int ret;
14762
14763   if (!vam->json_output)
14764     {
14765       print (vam->ofp, "%=20s", "lisp status:");
14766     }
14767
14768   M (SHOW_ONE_PITR, mp);
14769   /* send it... */
14770   S (mp);
14771
14772   /* Wait for a reply... */
14773   W (ret);
14774   return ret;
14775 }
14776
14777 #define api_show_lisp_pitr api_show_one_pitr
14778
14779 static int
14780 api_one_use_petr (vat_main_t * vam)
14781 {
14782   unformat_input_t *input = vam->input;
14783   vl_api_one_use_petr_t *mp;
14784   u8 is_add = 0;
14785   ip_address_t ip;
14786   int ret;
14787
14788   memset (&ip, 0, sizeof (ip));
14789
14790   /* Parse args required to build the message */
14791   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14792     {
14793       if (unformat (input, "disable"))
14794         is_add = 0;
14795       else
14796         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
14797         {
14798           is_add = 1;
14799           ip_addr_version (&ip) = IP4;
14800         }
14801       else
14802         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
14803         {
14804           is_add = 1;
14805           ip_addr_version (&ip) = IP6;
14806         }
14807       else
14808         {
14809           errmsg ("parse error '%U'", format_unformat_error, input);
14810           return -99;
14811         }
14812     }
14813
14814   M (ONE_USE_PETR, mp);
14815
14816   mp->is_add = is_add;
14817   if (is_add)
14818     {
14819       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
14820       if (mp->is_ip4)
14821         clib_memcpy (mp->address, &ip, 4);
14822       else
14823         clib_memcpy (mp->address, &ip, 16);
14824     }
14825
14826   /* send */
14827   S (mp);
14828
14829   /* wait for reply */
14830   W (ret);
14831   return ret;
14832 }
14833
14834 #define api_lisp_use_petr api_one_use_petr
14835
14836 static int
14837 api_show_one_use_petr (vat_main_t * vam)
14838 {
14839   vl_api_show_one_use_petr_t *mp;
14840   int ret;
14841
14842   if (!vam->json_output)
14843     {
14844       print (vam->ofp, "%=20s", "Proxy-ETR status:");
14845     }
14846
14847   M (SHOW_ONE_USE_PETR, mp);
14848   /* send it... */
14849   S (mp);
14850
14851   /* Wait for a reply... */
14852   W (ret);
14853   return ret;
14854 }
14855
14856 #define api_show_lisp_use_petr api_show_one_use_petr
14857
14858 /**
14859  * Add/delete mapping between vni and vrf
14860  */
14861 static int
14862 api_one_eid_table_add_del_map (vat_main_t * vam)
14863 {
14864   unformat_input_t *input = vam->input;
14865   vl_api_one_eid_table_add_del_map_t *mp;
14866   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
14867   u32 vni, vrf, bd_index;
14868   int ret;
14869
14870   /* Parse args required to build the message */
14871   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14872     {
14873       if (unformat (input, "del"))
14874         is_add = 0;
14875       else if (unformat (input, "vrf %d", &vrf))
14876         vrf_set = 1;
14877       else if (unformat (input, "bd_index %d", &bd_index))
14878         bd_index_set = 1;
14879       else if (unformat (input, "vni %d", &vni))
14880         vni_set = 1;
14881       else
14882         break;
14883     }
14884
14885   if (!vni_set || (!vrf_set && !bd_index_set))
14886     {
14887       errmsg ("missing arguments!");
14888       return -99;
14889     }
14890
14891   if (vrf_set && bd_index_set)
14892     {
14893       errmsg ("error: both vrf and bd entered!");
14894       return -99;
14895     }
14896
14897   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
14898
14899   mp->is_add = is_add;
14900   mp->vni = htonl (vni);
14901   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
14902   mp->is_l2 = bd_index_set;
14903
14904   /* send */
14905   S (mp);
14906
14907   /* wait for reply */
14908   W (ret);
14909   return ret;
14910 }
14911
14912 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
14913
14914 uword
14915 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
14916 {
14917   u32 *action = va_arg (*args, u32 *);
14918   u8 *s = 0;
14919
14920   if (unformat (input, "%s", &s))
14921     {
14922       if (!strcmp ((char *) s, "no-action"))
14923         action[0] = 0;
14924       else if (!strcmp ((char *) s, "natively-forward"))
14925         action[0] = 1;
14926       else if (!strcmp ((char *) s, "send-map-request"))
14927         action[0] = 2;
14928       else if (!strcmp ((char *) s, "drop"))
14929         action[0] = 3;
14930       else
14931         {
14932           clib_warning ("invalid action: '%s'", s);
14933           action[0] = 3;
14934         }
14935     }
14936   else
14937     return 0;
14938
14939   vec_free (s);
14940   return 1;
14941 }
14942
14943 /**
14944  * Add/del remote mapping to/from ONE control plane
14945  *
14946  * @param vam vpp API test context
14947  * @return return code
14948  */
14949 static int
14950 api_one_add_del_remote_mapping (vat_main_t * vam)
14951 {
14952   unformat_input_t *input = vam->input;
14953   vl_api_one_add_del_remote_mapping_t *mp;
14954   u32 vni = 0;
14955   lisp_eid_vat_t _eid, *eid = &_eid;
14956   lisp_eid_vat_t _seid, *seid = &_seid;
14957   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
14958   u32 action = ~0, p, w, data_len;
14959   ip4_address_t rloc4;
14960   ip6_address_t rloc6;
14961   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
14962   int ret;
14963
14964   memset (&rloc, 0, sizeof (rloc));
14965
14966   /* Parse args required to build the message */
14967   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14968     {
14969       if (unformat (input, "del-all"))
14970         {
14971           del_all = 1;
14972         }
14973       else if (unformat (input, "del"))
14974         {
14975           is_add = 0;
14976         }
14977       else if (unformat (input, "add"))
14978         {
14979           is_add = 1;
14980         }
14981       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14982         {
14983           eid_set = 1;
14984         }
14985       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
14986         {
14987           seid_set = 1;
14988         }
14989       else if (unformat (input, "vni %d", &vni))
14990         {
14991           ;
14992         }
14993       else if (unformat (input, "p %d w %d", &p, &w))
14994         {
14995           if (!curr_rloc)
14996             {
14997               errmsg ("No RLOC configured for setting priority/weight!");
14998               return -99;
14999             }
15000           curr_rloc->priority = p;
15001           curr_rloc->weight = w;
15002         }
15003       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15004         {
15005           rloc.is_ip4 = 1;
15006           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
15007           vec_add1 (rlocs, rloc);
15008           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15009         }
15010       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15011         {
15012           rloc.is_ip4 = 0;
15013           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
15014           vec_add1 (rlocs, rloc);
15015           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15016         }
15017       else if (unformat (input, "action %U",
15018                          unformat_negative_mapping_action, &action))
15019         {
15020           ;
15021         }
15022       else
15023         {
15024           clib_warning ("parse error '%U'", format_unformat_error, input);
15025           return -99;
15026         }
15027     }
15028
15029   if (0 == eid_set)
15030     {
15031       errmsg ("missing params!");
15032       return -99;
15033     }
15034
15035   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15036     {
15037       errmsg ("no action set for negative map-reply!");
15038       return -99;
15039     }
15040
15041   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15042
15043   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15044   mp->is_add = is_add;
15045   mp->vni = htonl (vni);
15046   mp->action = (u8) action;
15047   mp->is_src_dst = seid_set;
15048   mp->eid_len = eid->len;
15049   mp->seid_len = seid->len;
15050   mp->del_all = del_all;
15051   mp->eid_type = eid->type;
15052   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15053   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
15054
15055   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15056   clib_memcpy (mp->rlocs, rlocs, data_len);
15057   vec_free (rlocs);
15058
15059   /* send it... */
15060   S (mp);
15061
15062   /* Wait for a reply... */
15063   W (ret);
15064   return ret;
15065 }
15066
15067 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15068
15069 /**
15070  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15071  * forwarding entries in data-plane accordingly.
15072  *
15073  * @param vam vpp API test context
15074  * @return return code
15075  */
15076 static int
15077 api_one_add_del_adjacency (vat_main_t * vam)
15078 {
15079   unformat_input_t *input = vam->input;
15080   vl_api_one_add_del_adjacency_t *mp;
15081   u32 vni = 0;
15082   ip4_address_t leid4, reid4;
15083   ip6_address_t leid6, reid6;
15084   u8 reid_mac[6] = { 0 };
15085   u8 leid_mac[6] = { 0 };
15086   u8 reid_type, leid_type;
15087   u32 leid_len = 0, reid_len = 0, len;
15088   u8 is_add = 1;
15089   int ret;
15090
15091   leid_type = reid_type = (u8) ~ 0;
15092
15093   /* Parse args required to build the message */
15094   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15095     {
15096       if (unformat (input, "del"))
15097         {
15098           is_add = 0;
15099         }
15100       else if (unformat (input, "add"))
15101         {
15102           is_add = 1;
15103         }
15104       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
15105                          &reid4, &len))
15106         {
15107           reid_type = 0;        /* ipv4 */
15108           reid_len = len;
15109         }
15110       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
15111                          &reid6, &len))
15112         {
15113           reid_type = 1;        /* ipv6 */
15114           reid_len = len;
15115         }
15116       else if (unformat (input, "reid %U", unformat_ethernet_address,
15117                          reid_mac))
15118         {
15119           reid_type = 2;        /* mac */
15120         }
15121       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
15122                          &leid4, &len))
15123         {
15124           leid_type = 0;        /* ipv4 */
15125           leid_len = len;
15126         }
15127       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
15128                          &leid6, &len))
15129         {
15130           leid_type = 1;        /* ipv6 */
15131           leid_len = len;
15132         }
15133       else if (unformat (input, "leid %U", unformat_ethernet_address,
15134                          leid_mac))
15135         {
15136           leid_type = 2;        /* mac */
15137         }
15138       else if (unformat (input, "vni %d", &vni))
15139         {
15140           ;
15141         }
15142       else
15143         {
15144           errmsg ("parse error '%U'", format_unformat_error, input);
15145           return -99;
15146         }
15147     }
15148
15149   if ((u8) ~ 0 == reid_type)
15150     {
15151       errmsg ("missing params!");
15152       return -99;
15153     }
15154
15155   if (leid_type != reid_type)
15156     {
15157       errmsg ("remote and local EIDs are of different types!");
15158       return -99;
15159     }
15160
15161   M (ONE_ADD_DEL_ADJACENCY, mp);
15162   mp->is_add = is_add;
15163   mp->vni = htonl (vni);
15164   mp->leid_len = leid_len;
15165   mp->reid_len = reid_len;
15166   mp->eid_type = reid_type;
15167
15168   switch (mp->eid_type)
15169     {
15170     case 0:
15171       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
15172       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
15173       break;
15174     case 1:
15175       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
15176       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
15177       break;
15178     case 2:
15179       clib_memcpy (mp->leid, leid_mac, 6);
15180       clib_memcpy (mp->reid, reid_mac, 6);
15181       break;
15182     default:
15183       errmsg ("unknown EID type %d!", mp->eid_type);
15184       return 0;
15185     }
15186
15187   /* send it... */
15188   S (mp);
15189
15190   /* Wait for a reply... */
15191   W (ret);
15192   return ret;
15193 }
15194
15195 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
15196
15197 uword
15198 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
15199 {
15200   u32 *mode = va_arg (*args, u32 *);
15201
15202   if (unformat (input, "lisp"))
15203     *mode = 0;
15204   else if (unformat (input, "vxlan"))
15205     *mode = 1;
15206   else
15207     return 0;
15208
15209   return 1;
15210 }
15211
15212 static int
15213 api_gpe_get_encap_mode (vat_main_t * vam)
15214 {
15215   vl_api_gpe_get_encap_mode_t *mp;
15216   int ret;
15217
15218   /* Construct the API message */
15219   M (GPE_GET_ENCAP_MODE, mp);
15220
15221   /* send it... */
15222   S (mp);
15223
15224   /* Wait for a reply... */
15225   W (ret);
15226   return ret;
15227 }
15228
15229 static int
15230 api_gpe_set_encap_mode (vat_main_t * vam)
15231 {
15232   unformat_input_t *input = vam->input;
15233   vl_api_gpe_set_encap_mode_t *mp;
15234   int ret;
15235   u32 mode = 0;
15236
15237   /* Parse args required to build the message */
15238   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15239     {
15240       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
15241         ;
15242       else
15243         break;
15244     }
15245
15246   /* Construct the API message */
15247   M (GPE_SET_ENCAP_MODE, mp);
15248
15249   mp->mode = mode;
15250
15251   /* send it... */
15252   S (mp);
15253
15254   /* Wait for a reply... */
15255   W (ret);
15256   return ret;
15257 }
15258
15259 static int
15260 api_lisp_gpe_add_del_iface (vat_main_t * vam)
15261 {
15262   unformat_input_t *input = vam->input;
15263   vl_api_gpe_add_del_iface_t *mp;
15264   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
15265   u32 dp_table = 0, vni = 0;
15266   int ret;
15267
15268   /* Parse args required to build the message */
15269   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15270     {
15271       if (unformat (input, "up"))
15272         {
15273           action_set = 1;
15274           is_add = 1;
15275         }
15276       else if (unformat (input, "down"))
15277         {
15278           action_set = 1;
15279           is_add = 0;
15280         }
15281       else if (unformat (input, "table_id %d", &dp_table))
15282         {
15283           dp_table_set = 1;
15284         }
15285       else if (unformat (input, "bd_id %d", &dp_table))
15286         {
15287           dp_table_set = 1;
15288           is_l2 = 1;
15289         }
15290       else if (unformat (input, "vni %d", &vni))
15291         {
15292           vni_set = 1;
15293         }
15294       else
15295         break;
15296     }
15297
15298   if (action_set == 0)
15299     {
15300       errmsg ("Action not set");
15301       return -99;
15302     }
15303   if (dp_table_set == 0 || vni_set == 0)
15304     {
15305       errmsg ("vni and dp_table must be set");
15306       return -99;
15307     }
15308
15309   /* Construct the API message */
15310   M (GPE_ADD_DEL_IFACE, mp);
15311
15312   mp->is_add = is_add;
15313   mp->dp_table = dp_table;
15314   mp->is_l2 = is_l2;
15315   mp->vni = vni;
15316
15317   /* send it... */
15318   S (mp);
15319
15320   /* Wait for a reply... */
15321   W (ret);
15322   return ret;
15323 }
15324
15325 /**
15326  * Add/del map request itr rlocs from ONE control plane and updates
15327  *
15328  * @param vam vpp API test context
15329  * @return return code
15330  */
15331 static int
15332 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
15333 {
15334   unformat_input_t *input = vam->input;
15335   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
15336   u8 *locator_set_name = 0;
15337   u8 locator_set_name_set = 0;
15338   u8 is_add = 1;
15339   int ret;
15340
15341   /* Parse args required to build the message */
15342   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15343     {
15344       if (unformat (input, "del"))
15345         {
15346           is_add = 0;
15347         }
15348       else if (unformat (input, "%_%v%_", &locator_set_name))
15349         {
15350           locator_set_name_set = 1;
15351         }
15352       else
15353         {
15354           clib_warning ("parse error '%U'", format_unformat_error, input);
15355           return -99;
15356         }
15357     }
15358
15359   if (is_add && !locator_set_name_set)
15360     {
15361       errmsg ("itr-rloc is not set!");
15362       return -99;
15363     }
15364
15365   if (is_add && vec_len (locator_set_name) > 64)
15366     {
15367       errmsg ("itr-rloc locator-set name too long");
15368       vec_free (locator_set_name);
15369       return -99;
15370     }
15371
15372   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
15373   mp->is_add = is_add;
15374   if (is_add)
15375     {
15376       clib_memcpy (mp->locator_set_name, locator_set_name,
15377                    vec_len (locator_set_name));
15378     }
15379   else
15380     {
15381       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
15382     }
15383   vec_free (locator_set_name);
15384
15385   /* send it... */
15386   S (mp);
15387
15388   /* Wait for a reply... */
15389   W (ret);
15390   return ret;
15391 }
15392
15393 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
15394
15395 static int
15396 api_one_locator_dump (vat_main_t * vam)
15397 {
15398   unformat_input_t *input = vam->input;
15399   vl_api_one_locator_dump_t *mp;
15400   vl_api_control_ping_t *mp_ping;
15401   u8 is_index_set = 0, is_name_set = 0;
15402   u8 *ls_name = 0;
15403   u32 ls_index = ~0;
15404   int ret;
15405
15406   /* Parse args required to build the message */
15407   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15408     {
15409       if (unformat (input, "ls_name %_%v%_", &ls_name))
15410         {
15411           is_name_set = 1;
15412         }
15413       else if (unformat (input, "ls_index %d", &ls_index))
15414         {
15415           is_index_set = 1;
15416         }
15417       else
15418         {
15419           errmsg ("parse error '%U'", format_unformat_error, input);
15420           return -99;
15421         }
15422     }
15423
15424   if (!is_index_set && !is_name_set)
15425     {
15426       errmsg ("error: expected one of index or name!");
15427       return -99;
15428     }
15429
15430   if (is_index_set && is_name_set)
15431     {
15432       errmsg ("error: only one param expected!");
15433       return -99;
15434     }
15435
15436   if (vec_len (ls_name) > 62)
15437     {
15438       errmsg ("error: locator set name too long!");
15439       return -99;
15440     }
15441
15442   if (!vam->json_output)
15443     {
15444       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
15445     }
15446
15447   M (ONE_LOCATOR_DUMP, mp);
15448   mp->is_index_set = is_index_set;
15449
15450   if (is_index_set)
15451     mp->ls_index = clib_host_to_net_u32 (ls_index);
15452   else
15453     {
15454       vec_add1 (ls_name, 0);
15455       strncpy ((char *) mp->ls_name, (char *) ls_name,
15456                sizeof (mp->ls_name) - 1);
15457     }
15458
15459   /* send it... */
15460   S (mp);
15461
15462   /* Use a control ping for synchronization */
15463   M (CONTROL_PING, mp_ping);
15464   S (mp_ping);
15465
15466   /* Wait for a reply... */
15467   W (ret);
15468   return ret;
15469 }
15470
15471 #define api_lisp_locator_dump api_one_locator_dump
15472
15473 static int
15474 api_one_locator_set_dump (vat_main_t * vam)
15475 {
15476   vl_api_one_locator_set_dump_t *mp;
15477   vl_api_control_ping_t *mp_ping;
15478   unformat_input_t *input = vam->input;
15479   u8 filter = 0;
15480   int ret;
15481
15482   /* Parse args required to build the message */
15483   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15484     {
15485       if (unformat (input, "local"))
15486         {
15487           filter = 1;
15488         }
15489       else if (unformat (input, "remote"))
15490         {
15491           filter = 2;
15492         }
15493       else
15494         {
15495           errmsg ("parse error '%U'", format_unformat_error, input);
15496           return -99;
15497         }
15498     }
15499
15500   if (!vam->json_output)
15501     {
15502       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
15503     }
15504
15505   M (ONE_LOCATOR_SET_DUMP, mp);
15506
15507   mp->filter = filter;
15508
15509   /* send it... */
15510   S (mp);
15511
15512   /* Use a control ping for synchronization */
15513   M (CONTROL_PING, mp_ping);
15514   S (mp_ping);
15515
15516   /* Wait for a reply... */
15517   W (ret);
15518   return ret;
15519 }
15520
15521 #define api_lisp_locator_set_dump api_one_locator_set_dump
15522
15523 static int
15524 api_one_eid_table_map_dump (vat_main_t * vam)
15525 {
15526   u8 is_l2 = 0;
15527   u8 mode_set = 0;
15528   unformat_input_t *input = vam->input;
15529   vl_api_one_eid_table_map_dump_t *mp;
15530   vl_api_control_ping_t *mp_ping;
15531   int ret;
15532
15533   /* Parse args required to build the message */
15534   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15535     {
15536       if (unformat (input, "l2"))
15537         {
15538           is_l2 = 1;
15539           mode_set = 1;
15540         }
15541       else if (unformat (input, "l3"))
15542         {
15543           is_l2 = 0;
15544           mode_set = 1;
15545         }
15546       else
15547         {
15548           errmsg ("parse error '%U'", format_unformat_error, input);
15549           return -99;
15550         }
15551     }
15552
15553   if (!mode_set)
15554     {
15555       errmsg ("expected one of 'l2' or 'l3' parameter!");
15556       return -99;
15557     }
15558
15559   if (!vam->json_output)
15560     {
15561       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
15562     }
15563
15564   M (ONE_EID_TABLE_MAP_DUMP, mp);
15565   mp->is_l2 = is_l2;
15566
15567   /* send it... */
15568   S (mp);
15569
15570   /* Use a control ping for synchronization */
15571   M (CONTROL_PING, mp_ping);
15572   S (mp_ping);
15573
15574   /* Wait for a reply... */
15575   W (ret);
15576   return ret;
15577 }
15578
15579 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
15580
15581 static int
15582 api_one_eid_table_vni_dump (vat_main_t * vam)
15583 {
15584   vl_api_one_eid_table_vni_dump_t *mp;
15585   vl_api_control_ping_t *mp_ping;
15586   int ret;
15587
15588   if (!vam->json_output)
15589     {
15590       print (vam->ofp, "VNI");
15591     }
15592
15593   M (ONE_EID_TABLE_VNI_DUMP, mp);
15594
15595   /* send it... */
15596   S (mp);
15597
15598   /* Use a control ping for synchronization */
15599   M (CONTROL_PING, mp_ping);
15600   S (mp_ping);
15601
15602   /* Wait for a reply... */
15603   W (ret);
15604   return ret;
15605 }
15606
15607 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
15608
15609 static int
15610 api_one_eid_table_dump (vat_main_t * vam)
15611 {
15612   unformat_input_t *i = vam->input;
15613   vl_api_one_eid_table_dump_t *mp;
15614   vl_api_control_ping_t *mp_ping;
15615   struct in_addr ip4;
15616   struct in6_addr ip6;
15617   u8 mac[6];
15618   u8 eid_type = ~0, eid_set = 0;
15619   u32 prefix_length = ~0, t, vni = 0;
15620   u8 filter = 0;
15621   int ret;
15622
15623   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15624     {
15625       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
15626         {
15627           eid_set = 1;
15628           eid_type = 0;
15629           prefix_length = t;
15630         }
15631       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
15632         {
15633           eid_set = 1;
15634           eid_type = 1;
15635           prefix_length = t;
15636         }
15637       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
15638         {
15639           eid_set = 1;
15640           eid_type = 2;
15641         }
15642       else if (unformat (i, "vni %d", &t))
15643         {
15644           vni = t;
15645         }
15646       else if (unformat (i, "local"))
15647         {
15648           filter = 1;
15649         }
15650       else if (unformat (i, "remote"))
15651         {
15652           filter = 2;
15653         }
15654       else
15655         {
15656           errmsg ("parse error '%U'", format_unformat_error, i);
15657           return -99;
15658         }
15659     }
15660
15661   if (!vam->json_output)
15662     {
15663       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
15664              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
15665     }
15666
15667   M (ONE_EID_TABLE_DUMP, mp);
15668
15669   mp->filter = filter;
15670   if (eid_set)
15671     {
15672       mp->eid_set = 1;
15673       mp->vni = htonl (vni);
15674       mp->eid_type = eid_type;
15675       switch (eid_type)
15676         {
15677         case 0:
15678           mp->prefix_length = prefix_length;
15679           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
15680           break;
15681         case 1:
15682           mp->prefix_length = prefix_length;
15683           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
15684           break;
15685         case 2:
15686           clib_memcpy (mp->eid, mac, sizeof (mac));
15687           break;
15688         default:
15689           errmsg ("unknown EID type %d!", eid_type);
15690           return -99;
15691         }
15692     }
15693
15694   /* send it... */
15695   S (mp);
15696
15697   /* Use a control ping for synchronization */
15698   M (CONTROL_PING, mp_ping);
15699   S (mp_ping);
15700
15701   /* Wait for a reply... */
15702   W (ret);
15703   return ret;
15704 }
15705
15706 #define api_lisp_eid_table_dump api_one_eid_table_dump
15707
15708 static int
15709 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
15710 {
15711   unformat_input_t *i = vam->input;
15712   vl_api_gpe_fwd_entries_get_t *mp;
15713   u8 vni_set = 0;
15714   u32 vni = ~0;
15715   int ret;
15716
15717   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15718     {
15719       if (unformat (i, "vni %d", &vni))
15720         {
15721           vni_set = 1;
15722         }
15723       else
15724         {
15725           errmsg ("parse error '%U'", format_unformat_error, i);
15726           return -99;
15727         }
15728     }
15729
15730   if (!vni_set)
15731     {
15732       errmsg ("vni not set!");
15733       return -99;
15734     }
15735
15736   if (!vam->json_output)
15737     {
15738       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
15739              "leid", "reid");
15740     }
15741
15742   M (GPE_FWD_ENTRIES_GET, mp);
15743   mp->vni = clib_host_to_net_u32 (vni);
15744
15745   /* send it... */
15746   S (mp);
15747
15748   /* Wait for a reply... */
15749   W (ret);
15750   return ret;
15751 }
15752
15753 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
15754 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
15755 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
15756 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
15757
15758 static int
15759 api_one_adjacencies_get (vat_main_t * vam)
15760 {
15761   unformat_input_t *i = vam->input;
15762   vl_api_one_adjacencies_get_t *mp;
15763   u8 vni_set = 0;
15764   u32 vni = ~0;
15765   int ret;
15766
15767   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15768     {
15769       if (unformat (i, "vni %d", &vni))
15770         {
15771           vni_set = 1;
15772         }
15773       else
15774         {
15775           errmsg ("parse error '%U'", format_unformat_error, i);
15776           return -99;
15777         }
15778     }
15779
15780   if (!vni_set)
15781     {
15782       errmsg ("vni not set!");
15783       return -99;
15784     }
15785
15786   if (!vam->json_output)
15787     {
15788       print (vam->ofp, "%s %40s", "leid", "reid");
15789     }
15790
15791   M (ONE_ADJACENCIES_GET, mp);
15792   mp->vni = clib_host_to_net_u32 (vni);
15793
15794   /* send it... */
15795   S (mp);
15796
15797   /* Wait for a reply... */
15798   W (ret);
15799   return ret;
15800 }
15801
15802 #define api_lisp_adjacencies_get api_one_adjacencies_get
15803
15804 static int
15805 api_one_map_server_dump (vat_main_t * vam)
15806 {
15807   vl_api_one_map_server_dump_t *mp;
15808   vl_api_control_ping_t *mp_ping;
15809   int ret;
15810
15811   if (!vam->json_output)
15812     {
15813       print (vam->ofp, "%=20s", "Map server");
15814     }
15815
15816   M (ONE_MAP_SERVER_DUMP, mp);
15817   /* send it... */
15818   S (mp);
15819
15820   /* Use a control ping for synchronization */
15821   M (CONTROL_PING, mp_ping);
15822   S (mp_ping);
15823
15824   /* Wait for a reply... */
15825   W (ret);
15826   return ret;
15827 }
15828
15829 #define api_lisp_map_server_dump api_one_map_server_dump
15830
15831 static int
15832 api_one_map_resolver_dump (vat_main_t * vam)
15833 {
15834   vl_api_one_map_resolver_dump_t *mp;
15835   vl_api_control_ping_t *mp_ping;
15836   int ret;
15837
15838   if (!vam->json_output)
15839     {
15840       print (vam->ofp, "%=20s", "Map resolver");
15841     }
15842
15843   M (ONE_MAP_RESOLVER_DUMP, mp);
15844   /* send it... */
15845   S (mp);
15846
15847   /* Use a control ping for synchronization */
15848   M (CONTROL_PING, mp_ping);
15849   S (mp_ping);
15850
15851   /* Wait for a reply... */
15852   W (ret);
15853   return ret;
15854 }
15855
15856 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
15857
15858 static int
15859 api_one_stats_dump (vat_main_t * vam)
15860 {
15861   vl_api_one_stats_dump_t *mp;
15862   vl_api_control_ping_t *mp_ping;
15863   int ret;
15864
15865   M (ONE_STATS_DUMP, mp);
15866   /* send it... */
15867   S (mp);
15868
15869   /* Use a control ping for synchronization */
15870   M (CONTROL_PING, mp_ping);
15871   S (mp_ping);
15872
15873   /* Wait for a reply... */
15874   W (ret);
15875   return ret;
15876 }
15877
15878 static int
15879 api_show_one_status (vat_main_t * vam)
15880 {
15881   vl_api_show_one_status_t *mp;
15882   int ret;
15883
15884   if (!vam->json_output)
15885     {
15886       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
15887     }
15888
15889   M (SHOW_ONE_STATUS, mp);
15890   /* send it... */
15891   S (mp);
15892   /* Wait for a reply... */
15893   W (ret);
15894   return ret;
15895 }
15896
15897 #define api_show_lisp_status api_show_one_status
15898
15899 static int
15900 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
15901 {
15902   vl_api_gpe_fwd_entry_path_dump_t *mp;
15903   vl_api_control_ping_t *mp_ping;
15904   unformat_input_t *i = vam->input;
15905   u32 fwd_entry_index = ~0;
15906   int ret;
15907
15908   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15909     {
15910       if (unformat (i, "index %d", &fwd_entry_index))
15911         ;
15912       else
15913         break;
15914     }
15915
15916   if (~0 == fwd_entry_index)
15917     {
15918       errmsg ("no index specified!");
15919       return -99;
15920     }
15921
15922   if (!vam->json_output)
15923     {
15924       print (vam->ofp, "first line");
15925     }
15926
15927   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
15928
15929   /* send it... */
15930   S (mp);
15931   /* Use a control ping for synchronization */
15932   M (CONTROL_PING, mp_ping);
15933   S (mp_ping);
15934
15935   /* Wait for a reply... */
15936   W (ret);
15937   return ret;
15938 }
15939
15940 static int
15941 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
15942 {
15943   vl_api_one_get_map_request_itr_rlocs_t *mp;
15944   int ret;
15945
15946   if (!vam->json_output)
15947     {
15948       print (vam->ofp, "%=20s", "itr-rlocs:");
15949     }
15950
15951   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
15952   /* send it... */
15953   S (mp);
15954   /* Wait for a reply... */
15955   W (ret);
15956   return ret;
15957 }
15958
15959 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
15960
15961 static int
15962 api_af_packet_create (vat_main_t * vam)
15963 {
15964   unformat_input_t *i = vam->input;
15965   vl_api_af_packet_create_t *mp;
15966   u8 *host_if_name = 0;
15967   u8 hw_addr[6];
15968   u8 random_hw_addr = 1;
15969   int ret;
15970
15971   memset (hw_addr, 0, sizeof (hw_addr));
15972
15973   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15974     {
15975       if (unformat (i, "name %s", &host_if_name))
15976         vec_add1 (host_if_name, 0);
15977       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15978         random_hw_addr = 0;
15979       else
15980         break;
15981     }
15982
15983   if (!vec_len (host_if_name))
15984     {
15985       errmsg ("host-interface name must be specified");
15986       return -99;
15987     }
15988
15989   if (vec_len (host_if_name) > 64)
15990     {
15991       errmsg ("host-interface name too long");
15992       return -99;
15993     }
15994
15995   M (AF_PACKET_CREATE, mp);
15996
15997   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15998   clib_memcpy (mp->hw_addr, hw_addr, 6);
15999   mp->use_random_hw_addr = random_hw_addr;
16000   vec_free (host_if_name);
16001
16002   S (mp);
16003
16004   /* *INDENT-OFF* */
16005   W2 (ret,
16006       ({
16007         if (ret == 0)
16008           fprintf (vam->ofp ? vam->ofp : stderr,
16009                    " new sw_if_index = %d\n", vam->sw_if_index);
16010       }));
16011   /* *INDENT-ON* */
16012   return ret;
16013 }
16014
16015 static int
16016 api_af_packet_delete (vat_main_t * vam)
16017 {
16018   unformat_input_t *i = vam->input;
16019   vl_api_af_packet_delete_t *mp;
16020   u8 *host_if_name = 0;
16021   int ret;
16022
16023   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16024     {
16025       if (unformat (i, "name %s", &host_if_name))
16026         vec_add1 (host_if_name, 0);
16027       else
16028         break;
16029     }
16030
16031   if (!vec_len (host_if_name))
16032     {
16033       errmsg ("host-interface name must be specified");
16034       return -99;
16035     }
16036
16037   if (vec_len (host_if_name) > 64)
16038     {
16039       errmsg ("host-interface name too long");
16040       return -99;
16041     }
16042
16043   M (AF_PACKET_DELETE, mp);
16044
16045   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
16046   vec_free (host_if_name);
16047
16048   S (mp);
16049   W (ret);
16050   return ret;
16051 }
16052
16053 static int
16054 api_policer_add_del (vat_main_t * vam)
16055 {
16056   unformat_input_t *i = vam->input;
16057   vl_api_policer_add_del_t *mp;
16058   u8 is_add = 1;
16059   u8 *name = 0;
16060   u32 cir = 0;
16061   u32 eir = 0;
16062   u64 cb = 0;
16063   u64 eb = 0;
16064   u8 rate_type = 0;
16065   u8 round_type = 0;
16066   u8 type = 0;
16067   u8 color_aware = 0;
16068   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
16069   int ret;
16070
16071   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
16072   conform_action.dscp = 0;
16073   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
16074   exceed_action.dscp = 0;
16075   violate_action.action_type = SSE2_QOS_ACTION_DROP;
16076   violate_action.dscp = 0;
16077
16078   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16079     {
16080       if (unformat (i, "del"))
16081         is_add = 0;
16082       else if (unformat (i, "name %s", &name))
16083         vec_add1 (name, 0);
16084       else if (unformat (i, "cir %u", &cir))
16085         ;
16086       else if (unformat (i, "eir %u", &eir))
16087         ;
16088       else if (unformat (i, "cb %u", &cb))
16089         ;
16090       else if (unformat (i, "eb %u", &eb))
16091         ;
16092       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
16093                          &rate_type))
16094         ;
16095       else if (unformat (i, "round_type %U", unformat_policer_round_type,
16096                          &round_type))
16097         ;
16098       else if (unformat (i, "type %U", unformat_policer_type, &type))
16099         ;
16100       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
16101                          &conform_action))
16102         ;
16103       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
16104                          &exceed_action))
16105         ;
16106       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
16107                          &violate_action))
16108         ;
16109       else if (unformat (i, "color-aware"))
16110         color_aware = 1;
16111       else
16112         break;
16113     }
16114
16115   if (!vec_len (name))
16116     {
16117       errmsg ("policer name must be specified");
16118       return -99;
16119     }
16120
16121   if (vec_len (name) > 64)
16122     {
16123       errmsg ("policer name too long");
16124       return -99;
16125     }
16126
16127   M (POLICER_ADD_DEL, mp);
16128
16129   clib_memcpy (mp->name, name, vec_len (name));
16130   vec_free (name);
16131   mp->is_add = is_add;
16132   mp->cir = cir;
16133   mp->eir = eir;
16134   mp->cb = cb;
16135   mp->eb = eb;
16136   mp->rate_type = rate_type;
16137   mp->round_type = round_type;
16138   mp->type = type;
16139   mp->conform_action_type = conform_action.action_type;
16140   mp->conform_dscp = conform_action.dscp;
16141   mp->exceed_action_type = exceed_action.action_type;
16142   mp->exceed_dscp = exceed_action.dscp;
16143   mp->violate_action_type = violate_action.action_type;
16144   mp->violate_dscp = violate_action.dscp;
16145   mp->color_aware = color_aware;
16146
16147   S (mp);
16148   W (ret);
16149   return ret;
16150 }
16151
16152 static int
16153 api_policer_dump (vat_main_t * vam)
16154 {
16155   unformat_input_t *i = vam->input;
16156   vl_api_policer_dump_t *mp;
16157   vl_api_control_ping_t *mp_ping;
16158   u8 *match_name = 0;
16159   u8 match_name_valid = 0;
16160   int ret;
16161
16162   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16163     {
16164       if (unformat (i, "name %s", &match_name))
16165         {
16166           vec_add1 (match_name, 0);
16167           match_name_valid = 1;
16168         }
16169       else
16170         break;
16171     }
16172
16173   M (POLICER_DUMP, mp);
16174   mp->match_name_valid = match_name_valid;
16175   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
16176   vec_free (match_name);
16177   /* send it... */
16178   S (mp);
16179
16180   /* Use a control ping for synchronization */
16181   M (CONTROL_PING, mp_ping);
16182   S (mp_ping);
16183
16184   /* Wait for a reply... */
16185   W (ret);
16186   return ret;
16187 }
16188
16189 static int
16190 api_policer_classify_set_interface (vat_main_t * vam)
16191 {
16192   unformat_input_t *i = vam->input;
16193   vl_api_policer_classify_set_interface_t *mp;
16194   u32 sw_if_index;
16195   int sw_if_index_set;
16196   u32 ip4_table_index = ~0;
16197   u32 ip6_table_index = ~0;
16198   u32 l2_table_index = ~0;
16199   u8 is_add = 1;
16200   int ret;
16201
16202   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16203     {
16204       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16205         sw_if_index_set = 1;
16206       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16207         sw_if_index_set = 1;
16208       else if (unformat (i, "del"))
16209         is_add = 0;
16210       else if (unformat (i, "ip4-table %d", &ip4_table_index))
16211         ;
16212       else if (unformat (i, "ip6-table %d", &ip6_table_index))
16213         ;
16214       else if (unformat (i, "l2-table %d", &l2_table_index))
16215         ;
16216       else
16217         {
16218           clib_warning ("parse error '%U'", format_unformat_error, i);
16219           return -99;
16220         }
16221     }
16222
16223   if (sw_if_index_set == 0)
16224     {
16225       errmsg ("missing interface name or sw_if_index");
16226       return -99;
16227     }
16228
16229   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
16230
16231   mp->sw_if_index = ntohl (sw_if_index);
16232   mp->ip4_table_index = ntohl (ip4_table_index);
16233   mp->ip6_table_index = ntohl (ip6_table_index);
16234   mp->l2_table_index = ntohl (l2_table_index);
16235   mp->is_add = is_add;
16236
16237   S (mp);
16238   W (ret);
16239   return ret;
16240 }
16241
16242 static int
16243 api_policer_classify_dump (vat_main_t * vam)
16244 {
16245   unformat_input_t *i = vam->input;
16246   vl_api_policer_classify_dump_t *mp;
16247   vl_api_control_ping_t *mp_ping;
16248   u8 type = POLICER_CLASSIFY_N_TABLES;
16249   int ret;
16250
16251   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
16252     ;
16253   else
16254     {
16255       errmsg ("classify table type must be specified");
16256       return -99;
16257     }
16258
16259   if (!vam->json_output)
16260     {
16261       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
16262     }
16263
16264   M (POLICER_CLASSIFY_DUMP, mp);
16265   mp->type = type;
16266   /* send it... */
16267   S (mp);
16268
16269   /* Use a control ping for synchronization */
16270   M (CONTROL_PING, mp_ping);
16271   S (mp_ping);
16272
16273   /* Wait for a reply... */
16274   W (ret);
16275   return ret;
16276 }
16277
16278 static int
16279 api_netmap_create (vat_main_t * vam)
16280 {
16281   unformat_input_t *i = vam->input;
16282   vl_api_netmap_create_t *mp;
16283   u8 *if_name = 0;
16284   u8 hw_addr[6];
16285   u8 random_hw_addr = 1;
16286   u8 is_pipe = 0;
16287   u8 is_master = 0;
16288   int ret;
16289
16290   memset (hw_addr, 0, sizeof (hw_addr));
16291
16292   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16293     {
16294       if (unformat (i, "name %s", &if_name))
16295         vec_add1 (if_name, 0);
16296       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
16297         random_hw_addr = 0;
16298       else if (unformat (i, "pipe"))
16299         is_pipe = 1;
16300       else if (unformat (i, "master"))
16301         is_master = 1;
16302       else if (unformat (i, "slave"))
16303         is_master = 0;
16304       else
16305         break;
16306     }
16307
16308   if (!vec_len (if_name))
16309     {
16310       errmsg ("interface name must be specified");
16311       return -99;
16312     }
16313
16314   if (vec_len (if_name) > 64)
16315     {
16316       errmsg ("interface name too long");
16317       return -99;
16318     }
16319
16320   M (NETMAP_CREATE, mp);
16321
16322   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
16323   clib_memcpy (mp->hw_addr, hw_addr, 6);
16324   mp->use_random_hw_addr = random_hw_addr;
16325   mp->is_pipe = is_pipe;
16326   mp->is_master = is_master;
16327   vec_free (if_name);
16328
16329   S (mp);
16330   W (ret);
16331   return ret;
16332 }
16333
16334 static int
16335 api_netmap_delete (vat_main_t * vam)
16336 {
16337   unformat_input_t *i = vam->input;
16338   vl_api_netmap_delete_t *mp;
16339   u8 *if_name = 0;
16340   int ret;
16341
16342   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16343     {
16344       if (unformat (i, "name %s", &if_name))
16345         vec_add1 (if_name, 0);
16346       else
16347         break;
16348     }
16349
16350   if (!vec_len (if_name))
16351     {
16352       errmsg ("interface name must be specified");
16353       return -99;
16354     }
16355
16356   if (vec_len (if_name) > 64)
16357     {
16358       errmsg ("interface name too long");
16359       return -99;
16360     }
16361
16362   M (NETMAP_DELETE, mp);
16363
16364   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
16365   vec_free (if_name);
16366
16367   S (mp);
16368   W (ret);
16369   return ret;
16370 }
16371
16372 static void
16373 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
16374 {
16375   if (fp->afi == IP46_TYPE_IP6)
16376     print (vam->ofp,
16377            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16378            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16379            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16380            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16381            format_ip6_address, fp->next_hop);
16382   else if (fp->afi == IP46_TYPE_IP4)
16383     print (vam->ofp,
16384            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16385            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16386            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16387            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16388            format_ip4_address, fp->next_hop);
16389 }
16390
16391 static void
16392 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
16393                                  vl_api_fib_path2_t * fp)
16394 {
16395   struct in_addr ip4;
16396   struct in6_addr ip6;
16397
16398   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16399   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16400   vat_json_object_add_uint (node, "is_local", fp->is_local);
16401   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16402   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16403   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16404   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16405   if (fp->afi == IP46_TYPE_IP4)
16406     {
16407       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16408       vat_json_object_add_ip4 (node, "next_hop", ip4);
16409     }
16410   else if (fp->afi == IP46_TYPE_IP6)
16411     {
16412       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16413       vat_json_object_add_ip6 (node, "next_hop", ip6);
16414     }
16415 }
16416
16417 static void
16418 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
16419 {
16420   vat_main_t *vam = &vat_main;
16421   int count = ntohl (mp->mt_count);
16422   vl_api_fib_path2_t *fp;
16423   i32 i;
16424
16425   print (vam->ofp, "[%d]: sw_if_index %d via:",
16426          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
16427   fp = mp->mt_paths;
16428   for (i = 0; i < count; i++)
16429     {
16430       vl_api_mpls_fib_path_print (vam, fp);
16431       fp++;
16432     }
16433
16434   print (vam->ofp, "");
16435 }
16436
16437 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
16438 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
16439
16440 static void
16441 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
16442 {
16443   vat_main_t *vam = &vat_main;
16444   vat_json_node_t *node = NULL;
16445   int count = ntohl (mp->mt_count);
16446   vl_api_fib_path2_t *fp;
16447   i32 i;
16448
16449   if (VAT_JSON_ARRAY != vam->json_tree.type)
16450     {
16451       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16452       vat_json_init_array (&vam->json_tree);
16453     }
16454   node = vat_json_array_add (&vam->json_tree);
16455
16456   vat_json_init_object (node);
16457   vat_json_object_add_uint (node, "tunnel_index",
16458                             ntohl (mp->mt_tunnel_index));
16459   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
16460
16461   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
16462
16463   fp = mp->mt_paths;
16464   for (i = 0; i < count; i++)
16465     {
16466       vl_api_mpls_fib_path_json_print (node, fp);
16467       fp++;
16468     }
16469 }
16470
16471 static int
16472 api_mpls_tunnel_dump (vat_main_t * vam)
16473 {
16474   vl_api_mpls_tunnel_dump_t *mp;
16475   vl_api_control_ping_t *mp_ping;
16476   i32 index = -1;
16477   int ret;
16478
16479   /* Parse args required to build the message */
16480   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
16481     {
16482       if (!unformat (vam->input, "tunnel_index %d", &index))
16483         {
16484           index = -1;
16485           break;
16486         }
16487     }
16488
16489   print (vam->ofp, "  tunnel_index %d", index);
16490
16491   M (MPLS_TUNNEL_DUMP, mp);
16492   mp->tunnel_index = htonl (index);
16493   S (mp);
16494
16495   /* Use a control ping for synchronization */
16496   M (CONTROL_PING, mp_ping);
16497   S (mp_ping);
16498
16499   W (ret);
16500   return ret;
16501 }
16502
16503 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
16504 #define vl_api_mpls_fib_details_t_print vl_noop_handler
16505
16506
16507 static void
16508 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
16509 {
16510   vat_main_t *vam = &vat_main;
16511   int count = ntohl (mp->count);
16512   vl_api_fib_path2_t *fp;
16513   int i;
16514
16515   print (vam->ofp,
16516          "table-id %d, label %u, ess_bit %u",
16517          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
16518   fp = mp->path;
16519   for (i = 0; i < count; i++)
16520     {
16521       vl_api_mpls_fib_path_print (vam, fp);
16522       fp++;
16523     }
16524 }
16525
16526 static void vl_api_mpls_fib_details_t_handler_json
16527   (vl_api_mpls_fib_details_t * mp)
16528 {
16529   vat_main_t *vam = &vat_main;
16530   int count = ntohl (mp->count);
16531   vat_json_node_t *node = NULL;
16532   vl_api_fib_path2_t *fp;
16533   int i;
16534
16535   if (VAT_JSON_ARRAY != vam->json_tree.type)
16536     {
16537       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16538       vat_json_init_array (&vam->json_tree);
16539     }
16540   node = vat_json_array_add (&vam->json_tree);
16541
16542   vat_json_init_object (node);
16543   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16544   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
16545   vat_json_object_add_uint (node, "label", ntohl (mp->label));
16546   vat_json_object_add_uint (node, "path_count", count);
16547   fp = mp->path;
16548   for (i = 0; i < count; i++)
16549     {
16550       vl_api_mpls_fib_path_json_print (node, fp);
16551       fp++;
16552     }
16553 }
16554
16555 static int
16556 api_mpls_fib_dump (vat_main_t * vam)
16557 {
16558   vl_api_mpls_fib_dump_t *mp;
16559   vl_api_control_ping_t *mp_ping;
16560   int ret;
16561
16562   M (MPLS_FIB_DUMP, mp);
16563   S (mp);
16564
16565   /* Use a control ping for synchronization */
16566   M (CONTROL_PING, mp_ping);
16567   S (mp_ping);
16568
16569   W (ret);
16570   return ret;
16571 }
16572
16573 #define vl_api_ip_fib_details_t_endian vl_noop_handler
16574 #define vl_api_ip_fib_details_t_print vl_noop_handler
16575
16576 static void
16577 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
16578 {
16579   vat_main_t *vam = &vat_main;
16580   int count = ntohl (mp->count);
16581   vl_api_fib_path_t *fp;
16582   int i;
16583
16584   print (vam->ofp,
16585          "table-id %d, prefix %U/%d",
16586          ntohl (mp->table_id), format_ip4_address, mp->address,
16587          mp->address_length);
16588   fp = mp->path;
16589   for (i = 0; i < count; i++)
16590     {
16591       if (fp->afi == IP46_TYPE_IP6)
16592         print (vam->ofp,
16593                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16594                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16595                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16596                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16597                format_ip6_address, fp->next_hop);
16598       else if (fp->afi == IP46_TYPE_IP4)
16599         print (vam->ofp,
16600                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16601                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16602                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16603                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16604                format_ip4_address, fp->next_hop);
16605       fp++;
16606     }
16607 }
16608
16609 static void vl_api_ip_fib_details_t_handler_json
16610   (vl_api_ip_fib_details_t * mp)
16611 {
16612   vat_main_t *vam = &vat_main;
16613   int count = ntohl (mp->count);
16614   vat_json_node_t *node = NULL;
16615   struct in_addr ip4;
16616   struct in6_addr ip6;
16617   vl_api_fib_path_t *fp;
16618   int i;
16619
16620   if (VAT_JSON_ARRAY != vam->json_tree.type)
16621     {
16622       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16623       vat_json_init_array (&vam->json_tree);
16624     }
16625   node = vat_json_array_add (&vam->json_tree);
16626
16627   vat_json_init_object (node);
16628   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16629   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
16630   vat_json_object_add_ip4 (node, "prefix", ip4);
16631   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16632   vat_json_object_add_uint (node, "path_count", count);
16633   fp = mp->path;
16634   for (i = 0; i < count; i++)
16635     {
16636       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16637       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16638       vat_json_object_add_uint (node, "is_local", fp->is_local);
16639       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16640       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16641       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16642       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16643       if (fp->afi == IP46_TYPE_IP4)
16644         {
16645           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16646           vat_json_object_add_ip4 (node, "next_hop", ip4);
16647         }
16648       else if (fp->afi == IP46_TYPE_IP6)
16649         {
16650           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16651           vat_json_object_add_ip6 (node, "next_hop", ip6);
16652         }
16653     }
16654 }
16655
16656 static int
16657 api_ip_fib_dump (vat_main_t * vam)
16658 {
16659   vl_api_ip_fib_dump_t *mp;
16660   vl_api_control_ping_t *mp_ping;
16661   int ret;
16662
16663   M (IP_FIB_DUMP, mp);
16664   S (mp);
16665
16666   /* Use a control ping for synchronization */
16667   M (CONTROL_PING, mp_ping);
16668   S (mp_ping);
16669
16670   W (ret);
16671   return ret;
16672 }
16673
16674 static int
16675 api_ip_mfib_dump (vat_main_t * vam)
16676 {
16677   vl_api_ip_mfib_dump_t *mp;
16678   vl_api_control_ping_t *mp_ping;
16679   int ret;
16680
16681   M (IP_MFIB_DUMP, mp);
16682   S (mp);
16683
16684   /* Use a control ping for synchronization */
16685   M (CONTROL_PING, mp_ping);
16686   S (mp_ping);
16687
16688   W (ret);
16689   return ret;
16690 }
16691
16692 static void vl_api_ip_neighbor_details_t_handler
16693   (vl_api_ip_neighbor_details_t * mp)
16694 {
16695   vat_main_t *vam = &vat_main;
16696
16697   print (vam->ofp, "%c %U %U",
16698          (mp->is_static) ? 'S' : 'D',
16699          format_ethernet_address, &mp->mac_address,
16700          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
16701          &mp->ip_address);
16702 }
16703
16704 static void vl_api_ip_neighbor_details_t_handler_json
16705   (vl_api_ip_neighbor_details_t * mp)
16706 {
16707
16708   vat_main_t *vam = &vat_main;
16709   vat_json_node_t *node;
16710   struct in_addr ip4;
16711   struct in6_addr ip6;
16712
16713   if (VAT_JSON_ARRAY != vam->json_tree.type)
16714     {
16715       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16716       vat_json_init_array (&vam->json_tree);
16717     }
16718   node = vat_json_array_add (&vam->json_tree);
16719
16720   vat_json_init_object (node);
16721   vat_json_object_add_string_copy (node, "flag",
16722                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
16723                                    "dynamic");
16724
16725   vat_json_object_add_string_copy (node, "link_layer",
16726                                    format (0, "%U", format_ethernet_address,
16727                                            &mp->mac_address));
16728
16729   if (mp->is_ipv6)
16730     {
16731       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
16732       vat_json_object_add_ip6 (node, "ip_address", ip6);
16733     }
16734   else
16735     {
16736       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
16737       vat_json_object_add_ip4 (node, "ip_address", ip4);
16738     }
16739 }
16740
16741 static int
16742 api_ip_neighbor_dump (vat_main_t * vam)
16743 {
16744   unformat_input_t *i = vam->input;
16745   vl_api_ip_neighbor_dump_t *mp;
16746   vl_api_control_ping_t *mp_ping;
16747   u8 is_ipv6 = 0;
16748   u32 sw_if_index = ~0;
16749   int ret;
16750
16751   /* Parse args required to build the message */
16752   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16753     {
16754       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16755         ;
16756       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16757         ;
16758       else if (unformat (i, "ip6"))
16759         is_ipv6 = 1;
16760       else
16761         break;
16762     }
16763
16764   if (sw_if_index == ~0)
16765     {
16766       errmsg ("missing interface name or sw_if_index");
16767       return -99;
16768     }
16769
16770   M (IP_NEIGHBOR_DUMP, mp);
16771   mp->is_ipv6 = (u8) is_ipv6;
16772   mp->sw_if_index = ntohl (sw_if_index);
16773   S (mp);
16774
16775   /* Use a control ping for synchronization */
16776   M (CONTROL_PING, mp_ping);
16777   S (mp_ping);
16778
16779   W (ret);
16780   return ret;
16781 }
16782
16783 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
16784 #define vl_api_ip6_fib_details_t_print vl_noop_handler
16785
16786 static void
16787 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
16788 {
16789   vat_main_t *vam = &vat_main;
16790   int count = ntohl (mp->count);
16791   vl_api_fib_path_t *fp;
16792   int i;
16793
16794   print (vam->ofp,
16795          "table-id %d, prefix %U/%d",
16796          ntohl (mp->table_id), format_ip6_address, mp->address,
16797          mp->address_length);
16798   fp = mp->path;
16799   for (i = 0; i < count; i++)
16800     {
16801       if (fp->afi == IP46_TYPE_IP6)
16802         print (vam->ofp,
16803                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16804                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16805                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16806                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16807                format_ip6_address, fp->next_hop);
16808       else if (fp->afi == IP46_TYPE_IP4)
16809         print (vam->ofp,
16810                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16811                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16812                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16813                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16814                format_ip4_address, fp->next_hop);
16815       fp++;
16816     }
16817 }
16818
16819 static void vl_api_ip6_fib_details_t_handler_json
16820   (vl_api_ip6_fib_details_t * mp)
16821 {
16822   vat_main_t *vam = &vat_main;
16823   int count = ntohl (mp->count);
16824   vat_json_node_t *node = NULL;
16825   struct in_addr ip4;
16826   struct in6_addr ip6;
16827   vl_api_fib_path_t *fp;
16828   int i;
16829
16830   if (VAT_JSON_ARRAY != vam->json_tree.type)
16831     {
16832       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16833       vat_json_init_array (&vam->json_tree);
16834     }
16835   node = vat_json_array_add (&vam->json_tree);
16836
16837   vat_json_init_object (node);
16838   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16839   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
16840   vat_json_object_add_ip6 (node, "prefix", ip6);
16841   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16842   vat_json_object_add_uint (node, "path_count", count);
16843   fp = mp->path;
16844   for (i = 0; i < count; i++)
16845     {
16846       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16847       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16848       vat_json_object_add_uint (node, "is_local", fp->is_local);
16849       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16850       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16851       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16852       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16853       if (fp->afi == IP46_TYPE_IP4)
16854         {
16855           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16856           vat_json_object_add_ip4 (node, "next_hop", ip4);
16857         }
16858       else if (fp->afi == IP46_TYPE_IP6)
16859         {
16860           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16861           vat_json_object_add_ip6 (node, "next_hop", ip6);
16862         }
16863     }
16864 }
16865
16866 static int
16867 api_ip6_fib_dump (vat_main_t * vam)
16868 {
16869   vl_api_ip6_fib_dump_t *mp;
16870   vl_api_control_ping_t *mp_ping;
16871   int ret;
16872
16873   M (IP6_FIB_DUMP, mp);
16874   S (mp);
16875
16876   /* Use a control ping for synchronization */
16877   M (CONTROL_PING, mp_ping);
16878   S (mp_ping);
16879
16880   W (ret);
16881   return ret;
16882 }
16883
16884 static int
16885 api_ip6_mfib_dump (vat_main_t * vam)
16886 {
16887   vl_api_ip6_mfib_dump_t *mp;
16888   vl_api_control_ping_t *mp_ping;
16889   int ret;
16890
16891   M (IP6_MFIB_DUMP, mp);
16892   S (mp);
16893
16894   /* Use a control ping for synchronization */
16895   M (CONTROL_PING, mp_ping);
16896   S (mp_ping);
16897
16898   W (ret);
16899   return ret;
16900 }
16901
16902 int
16903 api_classify_table_ids (vat_main_t * vam)
16904 {
16905   vl_api_classify_table_ids_t *mp;
16906   int ret;
16907
16908   /* Construct the API message */
16909   M (CLASSIFY_TABLE_IDS, mp);
16910   mp->context = 0;
16911
16912   S (mp);
16913   W (ret);
16914   return ret;
16915 }
16916
16917 int
16918 api_classify_table_by_interface (vat_main_t * vam)
16919 {
16920   unformat_input_t *input = vam->input;
16921   vl_api_classify_table_by_interface_t *mp;
16922
16923   u32 sw_if_index = ~0;
16924   int ret;
16925   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16926     {
16927       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16928         ;
16929       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16930         ;
16931       else
16932         break;
16933     }
16934   if (sw_if_index == ~0)
16935     {
16936       errmsg ("missing interface name or sw_if_index");
16937       return -99;
16938     }
16939
16940   /* Construct the API message */
16941   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
16942   mp->context = 0;
16943   mp->sw_if_index = ntohl (sw_if_index);
16944
16945   S (mp);
16946   W (ret);
16947   return ret;
16948 }
16949
16950 int
16951 api_classify_table_info (vat_main_t * vam)
16952 {
16953   unformat_input_t *input = vam->input;
16954   vl_api_classify_table_info_t *mp;
16955
16956   u32 table_id = ~0;
16957   int ret;
16958   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16959     {
16960       if (unformat (input, "table_id %d", &table_id))
16961         ;
16962       else
16963         break;
16964     }
16965   if (table_id == ~0)
16966     {
16967       errmsg ("missing table id");
16968       return -99;
16969     }
16970
16971   /* Construct the API message */
16972   M (CLASSIFY_TABLE_INFO, mp);
16973   mp->context = 0;
16974   mp->table_id = ntohl (table_id);
16975
16976   S (mp);
16977   W (ret);
16978   return ret;
16979 }
16980
16981 int
16982 api_classify_session_dump (vat_main_t * vam)
16983 {
16984   unformat_input_t *input = vam->input;
16985   vl_api_classify_session_dump_t *mp;
16986   vl_api_control_ping_t *mp_ping;
16987
16988   u32 table_id = ~0;
16989   int ret;
16990   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16991     {
16992       if (unformat (input, "table_id %d", &table_id))
16993         ;
16994       else
16995         break;
16996     }
16997   if (table_id == ~0)
16998     {
16999       errmsg ("missing table id");
17000       return -99;
17001     }
17002
17003   /* Construct the API message */
17004   M (CLASSIFY_SESSION_DUMP, mp);
17005   mp->context = 0;
17006   mp->table_id = ntohl (table_id);
17007   S (mp);
17008
17009   /* Use a control ping for synchronization */
17010   M (CONTROL_PING, mp_ping);
17011   S (mp_ping);
17012
17013   W (ret);
17014   return ret;
17015 }
17016
17017 static void
17018 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
17019 {
17020   vat_main_t *vam = &vat_main;
17021
17022   print (vam->ofp, "collector_address %U, collector_port %d, "
17023          "src_address %U, vrf_id %d, path_mtu %u, "
17024          "template_interval %u, udp_checksum %d",
17025          format_ip4_address, mp->collector_address,
17026          ntohs (mp->collector_port),
17027          format_ip4_address, mp->src_address,
17028          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
17029          ntohl (mp->template_interval), mp->udp_checksum);
17030
17031   vam->retval = 0;
17032   vam->result_ready = 1;
17033 }
17034
17035 static void
17036   vl_api_ipfix_exporter_details_t_handler_json
17037   (vl_api_ipfix_exporter_details_t * mp)
17038 {
17039   vat_main_t *vam = &vat_main;
17040   vat_json_node_t node;
17041   struct in_addr collector_address;
17042   struct in_addr src_address;
17043
17044   vat_json_init_object (&node);
17045   clib_memcpy (&collector_address, &mp->collector_address,
17046                sizeof (collector_address));
17047   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
17048   vat_json_object_add_uint (&node, "collector_port",
17049                             ntohs (mp->collector_port));
17050   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
17051   vat_json_object_add_ip4 (&node, "src_address", src_address);
17052   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
17053   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
17054   vat_json_object_add_uint (&node, "template_interval",
17055                             ntohl (mp->template_interval));
17056   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
17057
17058   vat_json_print (vam->ofp, &node);
17059   vat_json_free (&node);
17060   vam->retval = 0;
17061   vam->result_ready = 1;
17062 }
17063
17064 int
17065 api_ipfix_exporter_dump (vat_main_t * vam)
17066 {
17067   vl_api_ipfix_exporter_dump_t *mp;
17068   int ret;
17069
17070   /* Construct the API message */
17071   M (IPFIX_EXPORTER_DUMP, mp);
17072   mp->context = 0;
17073
17074   S (mp);
17075   W (ret);
17076   return ret;
17077 }
17078
17079 static int
17080 api_ipfix_classify_stream_dump (vat_main_t * vam)
17081 {
17082   vl_api_ipfix_classify_stream_dump_t *mp;
17083   int ret;
17084
17085   /* Construct the API message */
17086   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
17087   mp->context = 0;
17088
17089   S (mp);
17090   W (ret);
17091   return ret;
17092   /* NOTREACHED */
17093   return 0;
17094 }
17095
17096 static void
17097   vl_api_ipfix_classify_stream_details_t_handler
17098   (vl_api_ipfix_classify_stream_details_t * mp)
17099 {
17100   vat_main_t *vam = &vat_main;
17101   print (vam->ofp, "domain_id %d, src_port %d",
17102          ntohl (mp->domain_id), ntohs (mp->src_port));
17103   vam->retval = 0;
17104   vam->result_ready = 1;
17105 }
17106
17107 static void
17108   vl_api_ipfix_classify_stream_details_t_handler_json
17109   (vl_api_ipfix_classify_stream_details_t * mp)
17110 {
17111   vat_main_t *vam = &vat_main;
17112   vat_json_node_t node;
17113
17114   vat_json_init_object (&node);
17115   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
17116   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
17117
17118   vat_json_print (vam->ofp, &node);
17119   vat_json_free (&node);
17120   vam->retval = 0;
17121   vam->result_ready = 1;
17122 }
17123
17124 static int
17125 api_ipfix_classify_table_dump (vat_main_t * vam)
17126 {
17127   vl_api_ipfix_classify_table_dump_t *mp;
17128   vl_api_control_ping_t *mp_ping;
17129   int ret;
17130
17131   if (!vam->json_output)
17132     {
17133       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
17134              "transport_protocol");
17135     }
17136
17137   /* Construct the API message */
17138   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
17139
17140   /* send it... */
17141   S (mp);
17142
17143   /* Use a control ping for synchronization */
17144   M (CONTROL_PING, mp_ping);
17145   S (mp_ping);
17146
17147   W (ret);
17148   return ret;
17149 }
17150
17151 static void
17152   vl_api_ipfix_classify_table_details_t_handler
17153   (vl_api_ipfix_classify_table_details_t * mp)
17154 {
17155   vat_main_t *vam = &vat_main;
17156   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
17157          mp->transport_protocol);
17158 }
17159
17160 static void
17161   vl_api_ipfix_classify_table_details_t_handler_json
17162   (vl_api_ipfix_classify_table_details_t * mp)
17163 {
17164   vat_json_node_t *node = NULL;
17165   vat_main_t *vam = &vat_main;
17166
17167   if (VAT_JSON_ARRAY != vam->json_tree.type)
17168     {
17169       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17170       vat_json_init_array (&vam->json_tree);
17171     }
17172
17173   node = vat_json_array_add (&vam->json_tree);
17174   vat_json_init_object (node);
17175
17176   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
17177   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
17178   vat_json_object_add_uint (node, "transport_protocol",
17179                             mp->transport_protocol);
17180 }
17181
17182 static int
17183 api_sw_interface_span_enable_disable (vat_main_t * vam)
17184 {
17185   unformat_input_t *i = vam->input;
17186   vl_api_sw_interface_span_enable_disable_t *mp;
17187   u32 src_sw_if_index = ~0;
17188   u32 dst_sw_if_index = ~0;
17189   u8 state = 3;
17190   int ret;
17191
17192   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17193     {
17194       if (unformat
17195           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
17196         ;
17197       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
17198         ;
17199       else
17200         if (unformat
17201             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
17202         ;
17203       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
17204         ;
17205       else if (unformat (i, "disable"))
17206         state = 0;
17207       else if (unformat (i, "rx"))
17208         state = 1;
17209       else if (unformat (i, "tx"))
17210         state = 2;
17211       else if (unformat (i, "both"))
17212         state = 3;
17213       else
17214         break;
17215     }
17216
17217   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
17218
17219   mp->sw_if_index_from = htonl (src_sw_if_index);
17220   mp->sw_if_index_to = htonl (dst_sw_if_index);
17221   mp->state = state;
17222
17223   S (mp);
17224   W (ret);
17225   return ret;
17226 }
17227
17228 static void
17229 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
17230                                             * mp)
17231 {
17232   vat_main_t *vam = &vat_main;
17233   u8 *sw_if_from_name = 0;
17234   u8 *sw_if_to_name = 0;
17235   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
17236   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
17237   char *states[] = { "none", "rx", "tx", "both" };
17238   hash_pair_t *p;
17239
17240   /* *INDENT-OFF* */
17241   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
17242   ({
17243     if ((u32) p->value[0] == sw_if_index_from)
17244       {
17245         sw_if_from_name = (u8 *)(p->key);
17246         if (sw_if_to_name)
17247           break;
17248       }
17249     if ((u32) p->value[0] == sw_if_index_to)
17250       {
17251         sw_if_to_name = (u8 *)(p->key);
17252         if (sw_if_from_name)
17253           break;
17254       }
17255   }));
17256   /* *INDENT-ON* */
17257   print (vam->ofp, "%20s => %20s (%s)",
17258          sw_if_from_name, sw_if_to_name, states[mp->state]);
17259 }
17260
17261 static void
17262   vl_api_sw_interface_span_details_t_handler_json
17263   (vl_api_sw_interface_span_details_t * mp)
17264 {
17265   vat_main_t *vam = &vat_main;
17266   vat_json_node_t *node = NULL;
17267   u8 *sw_if_from_name = 0;
17268   u8 *sw_if_to_name = 0;
17269   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
17270   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
17271   hash_pair_t *p;
17272
17273   /* *INDENT-OFF* */
17274   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
17275   ({
17276     if ((u32) p->value[0] == sw_if_index_from)
17277       {
17278         sw_if_from_name = (u8 *)(p->key);
17279         if (sw_if_to_name)
17280           break;
17281       }
17282     if ((u32) p->value[0] == sw_if_index_to)
17283       {
17284         sw_if_to_name = (u8 *)(p->key);
17285         if (sw_if_from_name)
17286           break;
17287       }
17288   }));
17289   /* *INDENT-ON* */
17290
17291   if (VAT_JSON_ARRAY != vam->json_tree.type)
17292     {
17293       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17294       vat_json_init_array (&vam->json_tree);
17295     }
17296   node = vat_json_array_add (&vam->json_tree);
17297
17298   vat_json_init_object (node);
17299   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
17300   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
17301   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
17302   if (0 != sw_if_to_name)
17303     {
17304       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
17305     }
17306   vat_json_object_add_uint (node, "state", mp->state);
17307 }
17308
17309 static int
17310 api_sw_interface_span_dump (vat_main_t * vam)
17311 {
17312   vl_api_sw_interface_span_dump_t *mp;
17313   vl_api_control_ping_t *mp_ping;
17314   int ret;
17315
17316   M (SW_INTERFACE_SPAN_DUMP, mp);
17317   S (mp);
17318
17319   /* Use a control ping for synchronization */
17320   M (CONTROL_PING, mp_ping);
17321   S (mp_ping);
17322
17323   W (ret);
17324   return ret;
17325 }
17326
17327 int
17328 api_pg_create_interface (vat_main_t * vam)
17329 {
17330   unformat_input_t *input = vam->input;
17331   vl_api_pg_create_interface_t *mp;
17332
17333   u32 if_id = ~0;
17334   int ret;
17335   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17336     {
17337       if (unformat (input, "if_id %d", &if_id))
17338         ;
17339       else
17340         break;
17341     }
17342   if (if_id == ~0)
17343     {
17344       errmsg ("missing pg interface index");
17345       return -99;
17346     }
17347
17348   /* Construct the API message */
17349   M (PG_CREATE_INTERFACE, mp);
17350   mp->context = 0;
17351   mp->interface_id = ntohl (if_id);
17352
17353   S (mp);
17354   W (ret);
17355   return ret;
17356 }
17357
17358 int
17359 api_pg_capture (vat_main_t * vam)
17360 {
17361   unformat_input_t *input = vam->input;
17362   vl_api_pg_capture_t *mp;
17363
17364   u32 if_id = ~0;
17365   u8 enable = 1;
17366   u32 count = 1;
17367   u8 pcap_file_set = 0;
17368   u8 *pcap_file = 0;
17369   int ret;
17370   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17371     {
17372       if (unformat (input, "if_id %d", &if_id))
17373         ;
17374       else if (unformat (input, "pcap %s", &pcap_file))
17375         pcap_file_set = 1;
17376       else if (unformat (input, "count %d", &count))
17377         ;
17378       else if (unformat (input, "disable"))
17379         enable = 0;
17380       else
17381         break;
17382     }
17383   if (if_id == ~0)
17384     {
17385       errmsg ("missing pg interface index");
17386       return -99;
17387     }
17388   if (pcap_file_set > 0)
17389     {
17390       if (vec_len (pcap_file) > 255)
17391         {
17392           errmsg ("pcap file name is too long");
17393           return -99;
17394         }
17395     }
17396
17397   u32 name_len = vec_len (pcap_file);
17398   /* Construct the API message */
17399   M (PG_CAPTURE, mp);
17400   mp->context = 0;
17401   mp->interface_id = ntohl (if_id);
17402   mp->is_enabled = enable;
17403   mp->count = ntohl (count);
17404   mp->pcap_name_length = ntohl (name_len);
17405   if (pcap_file_set != 0)
17406     {
17407       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
17408     }
17409   vec_free (pcap_file);
17410
17411   S (mp);
17412   W (ret);
17413   return ret;
17414 }
17415
17416 int
17417 api_pg_enable_disable (vat_main_t * vam)
17418 {
17419   unformat_input_t *input = vam->input;
17420   vl_api_pg_enable_disable_t *mp;
17421
17422   u8 enable = 1;
17423   u8 stream_name_set = 0;
17424   u8 *stream_name = 0;
17425   int ret;
17426   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17427     {
17428       if (unformat (input, "stream %s", &stream_name))
17429         stream_name_set = 1;
17430       else if (unformat (input, "disable"))
17431         enable = 0;
17432       else
17433         break;
17434     }
17435
17436   if (stream_name_set > 0)
17437     {
17438       if (vec_len (stream_name) > 255)
17439         {
17440           errmsg ("stream name too long");
17441           return -99;
17442         }
17443     }
17444
17445   u32 name_len = vec_len (stream_name);
17446   /* Construct the API message */
17447   M (PG_ENABLE_DISABLE, mp);
17448   mp->context = 0;
17449   mp->is_enabled = enable;
17450   if (stream_name_set != 0)
17451     {
17452       mp->stream_name_length = ntohl (name_len);
17453       clib_memcpy (mp->stream_name, stream_name, name_len);
17454     }
17455   vec_free (stream_name);
17456
17457   S (mp);
17458   W (ret);
17459   return ret;
17460 }
17461
17462 int
17463 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
17464 {
17465   unformat_input_t *input = vam->input;
17466   vl_api_ip_source_and_port_range_check_add_del_t *mp;
17467
17468   u16 *low_ports = 0;
17469   u16 *high_ports = 0;
17470   u16 this_low;
17471   u16 this_hi;
17472   ip4_address_t ip4_addr;
17473   ip6_address_t ip6_addr;
17474   u32 length;
17475   u32 tmp, tmp2;
17476   u8 prefix_set = 0;
17477   u32 vrf_id = ~0;
17478   u8 is_add = 1;
17479   u8 is_ipv6 = 0;
17480   int ret;
17481
17482   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17483     {
17484       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
17485         {
17486           prefix_set = 1;
17487         }
17488       else
17489         if (unformat
17490             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
17491         {
17492           prefix_set = 1;
17493           is_ipv6 = 1;
17494         }
17495       else if (unformat (input, "vrf %d", &vrf_id))
17496         ;
17497       else if (unformat (input, "del"))
17498         is_add = 0;
17499       else if (unformat (input, "port %d", &tmp))
17500         {
17501           if (tmp == 0 || tmp > 65535)
17502             {
17503               errmsg ("port %d out of range", tmp);
17504               return -99;
17505             }
17506           this_low = tmp;
17507           this_hi = this_low + 1;
17508           vec_add1 (low_ports, this_low);
17509           vec_add1 (high_ports, this_hi);
17510         }
17511       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
17512         {
17513           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
17514             {
17515               errmsg ("incorrect range parameters");
17516               return -99;
17517             }
17518           this_low = tmp;
17519           /* Note: in debug CLI +1 is added to high before
17520              passing to real fn that does "the work"
17521              (ip_source_and_port_range_check_add_del).
17522              This fn is a wrapper around the binary API fn a
17523              control plane will call, which expects this increment
17524              to have occurred. Hence letting the binary API control
17525              plane fn do the increment for consistency between VAT
17526              and other control planes.
17527            */
17528           this_hi = tmp2;
17529           vec_add1 (low_ports, this_low);
17530           vec_add1 (high_ports, this_hi);
17531         }
17532       else
17533         break;
17534     }
17535
17536   if (prefix_set == 0)
17537     {
17538       errmsg ("<address>/<mask> not specified");
17539       return -99;
17540     }
17541
17542   if (vrf_id == ~0)
17543     {
17544       errmsg ("VRF ID required, not specified");
17545       return -99;
17546     }
17547
17548   if (vrf_id == 0)
17549     {
17550       errmsg
17551         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17552       return -99;
17553     }
17554
17555   if (vec_len (low_ports) == 0)
17556     {
17557       errmsg ("At least one port or port range required");
17558       return -99;
17559     }
17560
17561   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
17562
17563   mp->is_add = is_add;
17564
17565   if (is_ipv6)
17566     {
17567       mp->is_ipv6 = 1;
17568       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
17569     }
17570   else
17571     {
17572       mp->is_ipv6 = 0;
17573       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
17574     }
17575
17576   mp->mask_length = length;
17577   mp->number_of_ranges = vec_len (low_ports);
17578
17579   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
17580   vec_free (low_ports);
17581
17582   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
17583   vec_free (high_ports);
17584
17585   mp->vrf_id = ntohl (vrf_id);
17586
17587   S (mp);
17588   W (ret);
17589   return ret;
17590 }
17591
17592 int
17593 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
17594 {
17595   unformat_input_t *input = vam->input;
17596   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
17597   u32 sw_if_index = ~0;
17598   int vrf_set = 0;
17599   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
17600   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
17601   u8 is_add = 1;
17602   int ret;
17603
17604   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17605     {
17606       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17607         ;
17608       else if (unformat (input, "sw_if_index %d", &sw_if_index))
17609         ;
17610       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
17611         vrf_set = 1;
17612       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
17613         vrf_set = 1;
17614       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
17615         vrf_set = 1;
17616       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
17617         vrf_set = 1;
17618       else if (unformat (input, "del"))
17619         is_add = 0;
17620       else
17621         break;
17622     }
17623
17624   if (sw_if_index == ~0)
17625     {
17626       errmsg ("Interface required but not specified");
17627       return -99;
17628     }
17629
17630   if (vrf_set == 0)
17631     {
17632       errmsg ("VRF ID required but not specified");
17633       return -99;
17634     }
17635
17636   if (tcp_out_vrf_id == 0
17637       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
17638     {
17639       errmsg
17640         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17641       return -99;
17642     }
17643
17644   /* Construct the API message */
17645   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
17646
17647   mp->sw_if_index = ntohl (sw_if_index);
17648   mp->is_add = is_add;
17649   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
17650   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
17651   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
17652   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
17653
17654   /* send it... */
17655   S (mp);
17656
17657   /* Wait for a reply... */
17658   W (ret);
17659   return ret;
17660 }
17661
17662 static int
17663 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
17664 {
17665   unformat_input_t *i = vam->input;
17666   vl_api_ipsec_gre_add_del_tunnel_t *mp;
17667   u32 local_sa_id = 0;
17668   u32 remote_sa_id = 0;
17669   ip4_address_t src_address;
17670   ip4_address_t dst_address;
17671   u8 is_add = 1;
17672   int ret;
17673
17674   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17675     {
17676       if (unformat (i, "local_sa %d", &local_sa_id))
17677         ;
17678       else if (unformat (i, "remote_sa %d", &remote_sa_id))
17679         ;
17680       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
17681         ;
17682       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
17683         ;
17684       else if (unformat (i, "del"))
17685         is_add = 0;
17686       else
17687         {
17688           clib_warning ("parse error '%U'", format_unformat_error, i);
17689           return -99;
17690         }
17691     }
17692
17693   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
17694
17695   mp->local_sa_id = ntohl (local_sa_id);
17696   mp->remote_sa_id = ntohl (remote_sa_id);
17697   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
17698   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
17699   mp->is_add = is_add;
17700
17701   S (mp);
17702   W (ret);
17703   return ret;
17704 }
17705
17706 static int
17707 api_punt (vat_main_t * vam)
17708 {
17709   unformat_input_t *i = vam->input;
17710   vl_api_punt_t *mp;
17711   u32 ipv = ~0;
17712   u32 protocol = ~0;
17713   u32 port = ~0;
17714   int is_add = 1;
17715   int ret;
17716
17717   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17718     {
17719       if (unformat (i, "ip %d", &ipv))
17720         ;
17721       else if (unformat (i, "protocol %d", &protocol))
17722         ;
17723       else if (unformat (i, "port %d", &port))
17724         ;
17725       else if (unformat (i, "del"))
17726         is_add = 0;
17727       else
17728         {
17729           clib_warning ("parse error '%U'", format_unformat_error, i);
17730           return -99;
17731         }
17732     }
17733
17734   M (PUNT, mp);
17735
17736   mp->is_add = (u8) is_add;
17737   mp->ipv = (u8) ipv;
17738   mp->l4_protocol = (u8) protocol;
17739   mp->l4_port = htons ((u16) port);
17740
17741   S (mp);
17742   W (ret);
17743   return ret;
17744 }
17745
17746 static void vl_api_ipsec_gre_tunnel_details_t_handler
17747   (vl_api_ipsec_gre_tunnel_details_t * mp)
17748 {
17749   vat_main_t *vam = &vat_main;
17750
17751   print (vam->ofp, "%11d%15U%15U%14d%14d",
17752          ntohl (mp->sw_if_index),
17753          format_ip4_address, &mp->src_address,
17754          format_ip4_address, &mp->dst_address,
17755          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
17756 }
17757
17758 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
17759   (vl_api_ipsec_gre_tunnel_details_t * mp)
17760 {
17761   vat_main_t *vam = &vat_main;
17762   vat_json_node_t *node = NULL;
17763   struct in_addr ip4;
17764
17765   if (VAT_JSON_ARRAY != vam->json_tree.type)
17766     {
17767       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17768       vat_json_init_array (&vam->json_tree);
17769     }
17770   node = vat_json_array_add (&vam->json_tree);
17771
17772   vat_json_init_object (node);
17773   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17774   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
17775   vat_json_object_add_ip4 (node, "src_address", ip4);
17776   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
17777   vat_json_object_add_ip4 (node, "dst_address", ip4);
17778   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
17779   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
17780 }
17781
17782 static int
17783 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
17784 {
17785   unformat_input_t *i = vam->input;
17786   vl_api_ipsec_gre_tunnel_dump_t *mp;
17787   vl_api_control_ping_t *mp_ping;
17788   u32 sw_if_index;
17789   u8 sw_if_index_set = 0;
17790   int ret;
17791
17792   /* Parse args required to build the message */
17793   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17794     {
17795       if (unformat (i, "sw_if_index %d", &sw_if_index))
17796         sw_if_index_set = 1;
17797       else
17798         break;
17799     }
17800
17801   if (sw_if_index_set == 0)
17802     {
17803       sw_if_index = ~0;
17804     }
17805
17806   if (!vam->json_output)
17807     {
17808       print (vam->ofp, "%11s%15s%15s%14s%14s",
17809              "sw_if_index", "src_address", "dst_address",
17810              "local_sa_id", "remote_sa_id");
17811     }
17812
17813   /* Get list of gre-tunnel interfaces */
17814   M (IPSEC_GRE_TUNNEL_DUMP, mp);
17815
17816   mp->sw_if_index = htonl (sw_if_index);
17817
17818   S (mp);
17819
17820   /* Use a control ping for synchronization */
17821   M (CONTROL_PING, mp_ping);
17822   S (mp_ping);
17823
17824   W (ret);
17825   return ret;
17826 }
17827
17828 static int
17829 api_delete_subif (vat_main_t * vam)
17830 {
17831   unformat_input_t *i = vam->input;
17832   vl_api_delete_subif_t *mp;
17833   u32 sw_if_index = ~0;
17834   int ret;
17835
17836   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17837     {
17838       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17839         ;
17840       if (unformat (i, "sw_if_index %d", &sw_if_index))
17841         ;
17842       else
17843         break;
17844     }
17845
17846   if (sw_if_index == ~0)
17847     {
17848       errmsg ("missing sw_if_index");
17849       return -99;
17850     }
17851
17852   /* Construct the API message */
17853   M (DELETE_SUBIF, mp);
17854   mp->sw_if_index = ntohl (sw_if_index);
17855
17856   S (mp);
17857   W (ret);
17858   return ret;
17859 }
17860
17861 #define foreach_pbb_vtr_op      \
17862 _("disable",  L2_VTR_DISABLED)  \
17863 _("pop",  L2_VTR_POP_2)         \
17864 _("push",  L2_VTR_PUSH_2)
17865
17866 static int
17867 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
17868 {
17869   unformat_input_t *i = vam->input;
17870   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
17871   u32 sw_if_index = ~0, vtr_op = ~0;
17872   u16 outer_tag = ~0;
17873   u8 dmac[6], smac[6];
17874   u8 dmac_set = 0, smac_set = 0;
17875   u16 vlanid = 0;
17876   u32 sid = ~0;
17877   u32 tmp;
17878   int ret;
17879
17880   /* Shut up coverity */
17881   memset (dmac, 0, sizeof (dmac));
17882   memset (smac, 0, sizeof (smac));
17883
17884   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17885     {
17886       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17887         ;
17888       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17889         ;
17890       else if (unformat (i, "vtr_op %d", &vtr_op))
17891         ;
17892 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
17893       foreach_pbb_vtr_op
17894 #undef _
17895         else if (unformat (i, "translate_pbb_stag"))
17896         {
17897           if (unformat (i, "%d", &tmp))
17898             {
17899               vtr_op = L2_VTR_TRANSLATE_2_1;
17900               outer_tag = tmp;
17901             }
17902           else
17903             {
17904               errmsg
17905                 ("translate_pbb_stag operation requires outer tag definition");
17906               return -99;
17907             }
17908         }
17909       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
17910         dmac_set++;
17911       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
17912         smac_set++;
17913       else if (unformat (i, "sid %d", &sid))
17914         ;
17915       else if (unformat (i, "vlanid %d", &tmp))
17916         vlanid = tmp;
17917       else
17918         {
17919           clib_warning ("parse error '%U'", format_unformat_error, i);
17920           return -99;
17921         }
17922     }
17923
17924   if ((sw_if_index == ~0) || (vtr_op == ~0))
17925     {
17926       errmsg ("missing sw_if_index or vtr operation");
17927       return -99;
17928     }
17929   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
17930       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
17931     {
17932       errmsg
17933         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
17934       return -99;
17935     }
17936
17937   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
17938   mp->sw_if_index = ntohl (sw_if_index);
17939   mp->vtr_op = ntohl (vtr_op);
17940   mp->outer_tag = ntohs (outer_tag);
17941   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
17942   clib_memcpy (mp->b_smac, smac, sizeof (smac));
17943   mp->b_vlanid = ntohs (vlanid);
17944   mp->i_sid = ntohl (sid);
17945
17946   S (mp);
17947   W (ret);
17948   return ret;
17949 }
17950
17951 static int
17952 api_flow_classify_set_interface (vat_main_t * vam)
17953 {
17954   unformat_input_t *i = vam->input;
17955   vl_api_flow_classify_set_interface_t *mp;
17956   u32 sw_if_index;
17957   int sw_if_index_set;
17958   u32 ip4_table_index = ~0;
17959   u32 ip6_table_index = ~0;
17960   u8 is_add = 1;
17961   int ret;
17962
17963   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17964     {
17965       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17966         sw_if_index_set = 1;
17967       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17968         sw_if_index_set = 1;
17969       else if (unformat (i, "del"))
17970         is_add = 0;
17971       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17972         ;
17973       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17974         ;
17975       else
17976         {
17977           clib_warning ("parse error '%U'", format_unformat_error, i);
17978           return -99;
17979         }
17980     }
17981
17982   if (sw_if_index_set == 0)
17983     {
17984       errmsg ("missing interface name or sw_if_index");
17985       return -99;
17986     }
17987
17988   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
17989
17990   mp->sw_if_index = ntohl (sw_if_index);
17991   mp->ip4_table_index = ntohl (ip4_table_index);
17992   mp->ip6_table_index = ntohl (ip6_table_index);
17993   mp->is_add = is_add;
17994
17995   S (mp);
17996   W (ret);
17997   return ret;
17998 }
17999
18000 static int
18001 api_flow_classify_dump (vat_main_t * vam)
18002 {
18003   unformat_input_t *i = vam->input;
18004   vl_api_flow_classify_dump_t *mp;
18005   vl_api_control_ping_t *mp_ping;
18006   u8 type = FLOW_CLASSIFY_N_TABLES;
18007   int ret;
18008
18009   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
18010     ;
18011   else
18012     {
18013       errmsg ("classify table type must be specified");
18014       return -99;
18015     }
18016
18017   if (!vam->json_output)
18018     {
18019       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18020     }
18021
18022   M (FLOW_CLASSIFY_DUMP, mp);
18023   mp->type = type;
18024   /* send it... */
18025   S (mp);
18026
18027   /* Use a control ping for synchronization */
18028   M (CONTROL_PING, mp_ping);
18029   S (mp_ping);
18030
18031   /* Wait for a reply... */
18032   W (ret);
18033   return ret;
18034 }
18035
18036 static int
18037 api_feature_enable_disable (vat_main_t * vam)
18038 {
18039   unformat_input_t *i = vam->input;
18040   vl_api_feature_enable_disable_t *mp;
18041   u8 *arc_name = 0;
18042   u8 *feature_name = 0;
18043   u32 sw_if_index = ~0;
18044   u8 enable = 1;
18045   int ret;
18046
18047   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18048     {
18049       if (unformat (i, "arc_name %s", &arc_name))
18050         ;
18051       else if (unformat (i, "feature_name %s", &feature_name))
18052         ;
18053       else
18054         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18055         ;
18056       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18057         ;
18058       else if (unformat (i, "disable"))
18059         enable = 0;
18060       else
18061         break;
18062     }
18063
18064   if (arc_name == 0)
18065     {
18066       errmsg ("missing arc name");
18067       return -99;
18068     }
18069   if (vec_len (arc_name) > 63)
18070     {
18071       errmsg ("arc name too long");
18072     }
18073
18074   if (feature_name == 0)
18075     {
18076       errmsg ("missing feature name");
18077       return -99;
18078     }
18079   if (vec_len (feature_name) > 63)
18080     {
18081       errmsg ("feature name too long");
18082     }
18083
18084   if (sw_if_index == ~0)
18085     {
18086       errmsg ("missing interface name or sw_if_index");
18087       return -99;
18088     }
18089
18090   /* Construct the API message */
18091   M (FEATURE_ENABLE_DISABLE, mp);
18092   mp->sw_if_index = ntohl (sw_if_index);
18093   mp->enable = enable;
18094   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
18095   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
18096   vec_free (arc_name);
18097   vec_free (feature_name);
18098
18099   S (mp);
18100   W (ret);
18101   return ret;
18102 }
18103
18104 static int
18105 api_sw_interface_tag_add_del (vat_main_t * vam)
18106 {
18107   unformat_input_t *i = vam->input;
18108   vl_api_sw_interface_tag_add_del_t *mp;
18109   u32 sw_if_index = ~0;
18110   u8 *tag = 0;
18111   u8 enable = 1;
18112   int ret;
18113
18114   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18115     {
18116       if (unformat (i, "tag %s", &tag))
18117         ;
18118       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18119         ;
18120       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18121         ;
18122       else if (unformat (i, "del"))
18123         enable = 0;
18124       else
18125         break;
18126     }
18127
18128   if (sw_if_index == ~0)
18129     {
18130       errmsg ("missing interface name or sw_if_index");
18131       return -99;
18132     }
18133
18134   if (enable && (tag == 0))
18135     {
18136       errmsg ("no tag specified");
18137       return -99;
18138     }
18139
18140   /* Construct the API message */
18141   M (SW_INTERFACE_TAG_ADD_DEL, mp);
18142   mp->sw_if_index = ntohl (sw_if_index);
18143   mp->is_add = enable;
18144   if (enable)
18145     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
18146   vec_free (tag);
18147
18148   S (mp);
18149   W (ret);
18150   return ret;
18151 }
18152
18153 static void vl_api_l2_xconnect_details_t_handler
18154   (vl_api_l2_xconnect_details_t * mp)
18155 {
18156   vat_main_t *vam = &vat_main;
18157
18158   print (vam->ofp, "%15d%15d",
18159          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
18160 }
18161
18162 static void vl_api_l2_xconnect_details_t_handler_json
18163   (vl_api_l2_xconnect_details_t * mp)
18164 {
18165   vat_main_t *vam = &vat_main;
18166   vat_json_node_t *node = NULL;
18167
18168   if (VAT_JSON_ARRAY != vam->json_tree.type)
18169     {
18170       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18171       vat_json_init_array (&vam->json_tree);
18172     }
18173   node = vat_json_array_add (&vam->json_tree);
18174
18175   vat_json_init_object (node);
18176   vat_json_object_add_uint (node, "rx_sw_if_index",
18177                             ntohl (mp->rx_sw_if_index));
18178   vat_json_object_add_uint (node, "tx_sw_if_index",
18179                             ntohl (mp->tx_sw_if_index));
18180 }
18181
18182 static int
18183 api_l2_xconnect_dump (vat_main_t * vam)
18184 {
18185   vl_api_l2_xconnect_dump_t *mp;
18186   vl_api_control_ping_t *mp_ping;
18187   int ret;
18188
18189   if (!vam->json_output)
18190     {
18191       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
18192     }
18193
18194   M (L2_XCONNECT_DUMP, mp);
18195
18196   S (mp);
18197
18198   /* Use a control ping for synchronization */
18199   M (CONTROL_PING, mp_ping);
18200   S (mp_ping);
18201
18202   W (ret);
18203   return ret;
18204 }
18205
18206 static int
18207 api_sw_interface_set_mtu (vat_main_t * vam)
18208 {
18209   unformat_input_t *i = vam->input;
18210   vl_api_sw_interface_set_mtu_t *mp;
18211   u32 sw_if_index = ~0;
18212   u32 mtu = 0;
18213   int ret;
18214
18215   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18216     {
18217       if (unformat (i, "mtu %d", &mtu))
18218         ;
18219       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18220         ;
18221       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18222         ;
18223       else
18224         break;
18225     }
18226
18227   if (sw_if_index == ~0)
18228     {
18229       errmsg ("missing interface name or sw_if_index");
18230       return -99;
18231     }
18232
18233   if (mtu == 0)
18234     {
18235       errmsg ("no mtu specified");
18236       return -99;
18237     }
18238
18239   /* Construct the API message */
18240   M (SW_INTERFACE_SET_MTU, mp);
18241   mp->sw_if_index = ntohl (sw_if_index);
18242   mp->mtu = ntohs ((u16) mtu);
18243
18244   S (mp);
18245   W (ret);
18246   return ret;
18247 }
18248
18249
18250 static int
18251 q_or_quit (vat_main_t * vam)
18252 {
18253 #if VPP_API_TEST_BUILTIN == 0
18254   longjmp (vam->jump_buf, 1);
18255 #endif
18256   return 0;                     /* not so much */
18257 }
18258
18259 static int
18260 q (vat_main_t * vam)
18261 {
18262   return q_or_quit (vam);
18263 }
18264
18265 static int
18266 quit (vat_main_t * vam)
18267 {
18268   return q_or_quit (vam);
18269 }
18270
18271 static int
18272 comment (vat_main_t * vam)
18273 {
18274   return 0;
18275 }
18276
18277 static int
18278 cmd_cmp (void *a1, void *a2)
18279 {
18280   u8 **c1 = a1;
18281   u8 **c2 = a2;
18282
18283   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
18284 }
18285
18286 static int
18287 help (vat_main_t * vam)
18288 {
18289   u8 **cmds = 0;
18290   u8 *name = 0;
18291   hash_pair_t *p;
18292   unformat_input_t *i = vam->input;
18293   int j;
18294
18295   if (unformat (i, "%s", &name))
18296     {
18297       uword *hs;
18298
18299       vec_add1 (name, 0);
18300
18301       hs = hash_get_mem (vam->help_by_name, name);
18302       if (hs)
18303         print (vam->ofp, "usage: %s %s", name, hs[0]);
18304       else
18305         print (vam->ofp, "No such msg / command '%s'", name);
18306       vec_free (name);
18307       return 0;
18308     }
18309
18310   print (vam->ofp, "Help is available for the following:");
18311
18312     /* *INDENT-OFF* */
18313     hash_foreach_pair (p, vam->function_by_name,
18314     ({
18315       vec_add1 (cmds, (u8 *)(p->key));
18316     }));
18317     /* *INDENT-ON* */
18318
18319   vec_sort_with_function (cmds, cmd_cmp);
18320
18321   for (j = 0; j < vec_len (cmds); j++)
18322     print (vam->ofp, "%s", cmds[j]);
18323
18324   vec_free (cmds);
18325   return 0;
18326 }
18327
18328 static int
18329 set (vat_main_t * vam)
18330 {
18331   u8 *name = 0, *value = 0;
18332   unformat_input_t *i = vam->input;
18333
18334   if (unformat (i, "%s", &name))
18335     {
18336       /* The input buffer is a vector, not a string. */
18337       value = vec_dup (i->buffer);
18338       vec_delete (value, i->index, 0);
18339       /* Almost certainly has a trailing newline */
18340       if (value[vec_len (value) - 1] == '\n')
18341         value[vec_len (value) - 1] = 0;
18342       /* Make sure it's a proper string, one way or the other */
18343       vec_add1 (value, 0);
18344       (void) clib_macro_set_value (&vam->macro_main,
18345                                    (char *) name, (char *) value);
18346     }
18347   else
18348     errmsg ("usage: set <name> <value>");
18349
18350   vec_free (name);
18351   vec_free (value);
18352   return 0;
18353 }
18354
18355 static int
18356 unset (vat_main_t * vam)
18357 {
18358   u8 *name = 0;
18359
18360   if (unformat (vam->input, "%s", &name))
18361     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
18362       errmsg ("unset: %s wasn't set", name);
18363   vec_free (name);
18364   return 0;
18365 }
18366
18367 typedef struct
18368 {
18369   u8 *name;
18370   u8 *value;
18371 } macro_sort_t;
18372
18373
18374 static int
18375 macro_sort_cmp (void *a1, void *a2)
18376 {
18377   macro_sort_t *s1 = a1;
18378   macro_sort_t *s2 = a2;
18379
18380   return strcmp ((char *) (s1->name), (char *) (s2->name));
18381 }
18382
18383 static int
18384 dump_macro_table (vat_main_t * vam)
18385 {
18386   macro_sort_t *sort_me = 0, *sm;
18387   int i;
18388   hash_pair_t *p;
18389
18390     /* *INDENT-OFF* */
18391     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
18392     ({
18393       vec_add2 (sort_me, sm, 1);
18394       sm->name = (u8 *)(p->key);
18395       sm->value = (u8 *) (p->value[0]);
18396     }));
18397     /* *INDENT-ON* */
18398
18399   vec_sort_with_function (sort_me, macro_sort_cmp);
18400
18401   if (vec_len (sort_me))
18402     print (vam->ofp, "%-15s%s", "Name", "Value");
18403   else
18404     print (vam->ofp, "The macro table is empty...");
18405
18406   for (i = 0; i < vec_len (sort_me); i++)
18407     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
18408   return 0;
18409 }
18410
18411 static int
18412 dump_node_table (vat_main_t * vam)
18413 {
18414   int i, j;
18415   vlib_node_t *node, *next_node;
18416
18417   if (vec_len (vam->graph_nodes) == 0)
18418     {
18419       print (vam->ofp, "Node table empty, issue get_node_graph...");
18420       return 0;
18421     }
18422
18423   for (i = 0; i < vec_len (vam->graph_nodes); i++)
18424     {
18425       node = vam->graph_nodes[i];
18426       print (vam->ofp, "[%d] %s", i, node->name);
18427       for (j = 0; j < vec_len (node->next_nodes); j++)
18428         {
18429           if (node->next_nodes[j] != ~0)
18430             {
18431               next_node = vam->graph_nodes[node->next_nodes[j]];
18432               print (vam->ofp, "  [%d] %s", j, next_node->name);
18433             }
18434         }
18435     }
18436   return 0;
18437 }
18438
18439 static int
18440 value_sort_cmp (void *a1, void *a2)
18441 {
18442   name_sort_t *n1 = a1;
18443   name_sort_t *n2 = a2;
18444
18445   if (n1->value < n2->value)
18446     return -1;
18447   if (n1->value > n2->value)
18448     return 1;
18449   return 0;
18450 }
18451
18452
18453 static int
18454 dump_msg_api_table (vat_main_t * vam)
18455 {
18456   api_main_t *am = &api_main;
18457   name_sort_t *nses = 0, *ns;
18458   hash_pair_t *hp;
18459   int i;
18460
18461   /* *INDENT-OFF* */
18462   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
18463   ({
18464     vec_add2 (nses, ns, 1);
18465     ns->name = (u8 *)(hp->key);
18466     ns->value = (u32) hp->value[0];
18467   }));
18468   /* *INDENT-ON* */
18469
18470   vec_sort_with_function (nses, value_sort_cmp);
18471
18472   for (i = 0; i < vec_len (nses); i++)
18473     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
18474   vec_free (nses);
18475   return 0;
18476 }
18477
18478 static int
18479 get_msg_id (vat_main_t * vam)
18480 {
18481   u8 *name_and_crc;
18482   u32 message_index;
18483
18484   if (unformat (vam->input, "%s", &name_and_crc))
18485     {
18486       message_index = vl_api_get_msg_index (name_and_crc);
18487       if (message_index == ~0)
18488         {
18489           print (vam->ofp, " '%s' not found", name_and_crc);
18490           return 0;
18491         }
18492       print (vam->ofp, " '%s' has message index %d",
18493              name_and_crc, message_index);
18494       return 0;
18495     }
18496   errmsg ("name_and_crc required...");
18497   return 0;
18498 }
18499
18500 static int
18501 search_node_table (vat_main_t * vam)
18502 {
18503   unformat_input_t *line_input = vam->input;
18504   u8 *node_to_find;
18505   int j;
18506   vlib_node_t *node, *next_node;
18507   uword *p;
18508
18509   if (vam->graph_node_index_by_name == 0)
18510     {
18511       print (vam->ofp, "Node table empty, issue get_node_graph...");
18512       return 0;
18513     }
18514
18515   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
18516     {
18517       if (unformat (line_input, "%s", &node_to_find))
18518         {
18519           vec_add1 (node_to_find, 0);
18520           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
18521           if (p == 0)
18522             {
18523               print (vam->ofp, "%s not found...", node_to_find);
18524               goto out;
18525             }
18526           node = vam->graph_nodes[p[0]];
18527           print (vam->ofp, "[%d] %s", p[0], node->name);
18528           for (j = 0; j < vec_len (node->next_nodes); j++)
18529             {
18530               if (node->next_nodes[j] != ~0)
18531                 {
18532                   next_node = vam->graph_nodes[node->next_nodes[j]];
18533                   print (vam->ofp, "  [%d] %s", j, next_node->name);
18534                 }
18535             }
18536         }
18537
18538       else
18539         {
18540           clib_warning ("parse error '%U'", format_unformat_error,
18541                         line_input);
18542           return -99;
18543         }
18544
18545     out:
18546       vec_free (node_to_find);
18547
18548     }
18549
18550   return 0;
18551 }
18552
18553
18554 static int
18555 script (vat_main_t * vam)
18556 {
18557 #if (VPP_API_TEST_BUILTIN==0)
18558   u8 *s = 0;
18559   char *save_current_file;
18560   unformat_input_t save_input;
18561   jmp_buf save_jump_buf;
18562   u32 save_line_number;
18563
18564   FILE *new_fp, *save_ifp;
18565
18566   if (unformat (vam->input, "%s", &s))
18567     {
18568       new_fp = fopen ((char *) s, "r");
18569       if (new_fp == 0)
18570         {
18571           errmsg ("Couldn't open script file %s", s);
18572           vec_free (s);
18573           return -99;
18574         }
18575     }
18576   else
18577     {
18578       errmsg ("Missing script name");
18579       return -99;
18580     }
18581
18582   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
18583   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
18584   save_ifp = vam->ifp;
18585   save_line_number = vam->input_line_number;
18586   save_current_file = (char *) vam->current_file;
18587
18588   vam->input_line_number = 0;
18589   vam->ifp = new_fp;
18590   vam->current_file = s;
18591   do_one_file (vam);
18592
18593   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
18594   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
18595   vam->ifp = save_ifp;
18596   vam->input_line_number = save_line_number;
18597   vam->current_file = (u8 *) save_current_file;
18598   vec_free (s);
18599
18600   return 0;
18601 #else
18602   clib_warning ("use the exec command...");
18603   return -99;
18604 #endif
18605 }
18606
18607 static int
18608 echo (vat_main_t * vam)
18609 {
18610   print (vam->ofp, "%v", vam->input->buffer);
18611   return 0;
18612 }
18613
18614 /* List of API message constructors, CLI names map to api_xxx */
18615 #define foreach_vpe_api_msg                                             \
18616 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
18617 _(sw_interface_dump,"")                                                 \
18618 _(sw_interface_set_flags,                                               \
18619   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
18620 _(sw_interface_add_del_address,                                         \
18621   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
18622 _(sw_interface_set_table,                                               \
18623   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
18624 _(sw_interface_set_mpls_enable,                                         \
18625   "<intfc> | sw_if_index [disable | dis]")                              \
18626 _(sw_interface_set_vpath,                                               \
18627   "<intfc> | sw_if_index <id> enable | disable")                        \
18628 _(sw_interface_set_vxlan_bypass,                                        \
18629   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
18630 _(sw_interface_set_l2_xconnect,                                         \
18631   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18632   "enable | disable")                                                   \
18633 _(sw_interface_set_l2_bridge,                                           \
18634   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
18635   "[shg <split-horizon-group>] [bvi]\n"                                 \
18636   "enable | disable")                                                   \
18637 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
18638 _(bridge_domain_add_del,                                                \
18639   "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") \
18640 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
18641 _(l2fib_add_del,                                                        \
18642   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
18643 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
18644 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
18645 _(l2_flags,                                                             \
18646   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
18647 _(bridge_flags,                                                         \
18648   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
18649 _(tap_connect,                                                          \
18650   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
18651 _(tap_modify,                                                           \
18652   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
18653 _(tap_delete,                                                           \
18654   "<vpp-if-name> | sw_if_index <id>")                                   \
18655 _(sw_interface_tap_dump, "")                                            \
18656 _(ip_add_del_route,                                                     \
18657   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
18658   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
18659   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
18660   "[multipath] [count <n>]")                                            \
18661 _(ip_mroute_add_del,                                                    \
18662   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
18663   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
18664 _(mpls_route_add_del,                                                   \
18665   "<label> <eos> via <addr> [table-id <n>]\n"                           \
18666   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
18667   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
18668   "[multipath] [count <n>]")                                            \
18669 _(mpls_ip_bind_unbind,                                                  \
18670   "<label> <addr/len>")                                                 \
18671 _(mpls_tunnel_add_del,                                                  \
18672   " via <addr> [table-id <n>]\n"                                        \
18673   "sw_if_index <id>] [l2]  [del]")                                      \
18674 _(proxy_arp_add_del,                                                    \
18675   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
18676 _(proxy_arp_intfc_enable_disable,                                       \
18677   "<intfc> | sw_if_index <id> enable | disable")                        \
18678 _(sw_interface_set_unnumbered,                                          \
18679   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
18680 _(ip_neighbor_add_del,                                                  \
18681   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
18682   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
18683 _(reset_vrf, "vrf <id> [ipv6]")                                         \
18684 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
18685 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
18686   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
18687   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
18688   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
18689 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
18690 _(reset_fib, "vrf <n> [ipv6]")                                          \
18691 _(dhcp_proxy_config,                                                    \
18692   "svr <v46-address> src <v46-address>\n"                               \
18693    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
18694 _(dhcp_proxy_set_vss,                                                   \
18695   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
18696 _(dhcp_proxy_dump, "ip6")                                               \
18697 _(dhcp_client_config,                                                   \
18698   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
18699 _(set_ip_flow_hash,                                                     \
18700   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
18701 _(sw_interface_ip6_enable_disable,                                      \
18702   "<intfc> | sw_if_index <id> enable | disable")                        \
18703 _(sw_interface_ip6_set_link_local_address,                              \
18704   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
18705 _(ip6nd_proxy_add_del,                                                  \
18706   "<intfc> | sw_if_index <id> <ip6-address>")                           \
18707 _(ip6nd_proxy_dump, "")                                                 \
18708 _(sw_interface_ip6nd_ra_prefix,                                         \
18709   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
18710   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
18711   "[nolink] [isno]")                                                    \
18712 _(sw_interface_ip6nd_ra_config,                                         \
18713   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
18714   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
18715   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
18716 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
18717 _(l2_patch_add_del,                                                     \
18718   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18719   "enable | disable")                                                   \
18720 _(sr_localsid_add_del,                                                  \
18721   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
18722   "fib-table <num> (end.psp) sw_if_index <num>")                        \
18723 _(classify_add_del_table,                                               \
18724   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
18725   " [del] [del-chain] mask <mask-value>\n"                              \
18726   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
18727   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
18728 _(classify_add_del_session,                                             \
18729   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
18730   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
18731   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
18732   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
18733 _(classify_set_interface_ip_table,                                      \
18734   "<intfc> | sw_if_index <nn> table <nn>")                              \
18735 _(classify_set_interface_l2_tables,                                     \
18736   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18737   "  [other-table <nn>]")                                               \
18738 _(get_node_index, "node <node-name")                                    \
18739 _(add_node_next, "node <node-name> next <next-node-name>")              \
18740 _(l2tpv3_create_tunnel,                                                 \
18741   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
18742   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
18743   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
18744 _(l2tpv3_set_tunnel_cookies,                                            \
18745   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
18746   "[new_remote_cookie <nn>]\n")                                         \
18747 _(l2tpv3_interface_enable_disable,                                      \
18748   "<intfc> | sw_if_index <nn> enable | disable")                        \
18749 _(l2tpv3_set_lookup_key,                                                \
18750   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
18751 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
18752 _(vxlan_add_del_tunnel,                                                 \
18753   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
18754   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
18755   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
18756 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
18757 _(gre_add_del_tunnel,                                                   \
18758   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
18759 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
18760 _(l2_fib_clear_table, "")                                               \
18761 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
18762 _(l2_interface_vlan_tag_rewrite,                                        \
18763   "<intfc> | sw_if_index <nn> \n"                                       \
18764   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
18765   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
18766 _(create_vhost_user_if,                                                 \
18767         "socket <filename> [server] [renumber <dev_instance>] "         \
18768         "[mac <mac_address>] "                                          \
18769         "[mode <interrupt | polling>]")                                 \
18770 _(modify_vhost_user_if,                                                 \
18771         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
18772         "[server] [renumber <dev_instance>] "                           \
18773         "[mode <interrupt | polling>]")                                 \
18774 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
18775 _(sw_interface_vhost_user_dump, "")                                     \
18776 _(show_version, "")                                                     \
18777 _(vxlan_gpe_add_del_tunnel,                                             \
18778   "local <addr> remote <addr> vni <nn>\n"                               \
18779     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
18780   "[next-ethernet] [next-nsh]\n")                                       \
18781 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
18782 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
18783 _(interface_name_renumber,                                              \
18784   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
18785 _(input_acl_set_interface,                                              \
18786   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18787   "  [l2-table <nn>] [del]")                                            \
18788 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
18789 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
18790 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
18791 _(ip_dump, "ipv4 | ipv6")                                               \
18792 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
18793 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
18794   "  spid_id <n> ")                                                     \
18795 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
18796   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
18797   "  integ_alg <alg> integ_key <hex>")                                  \
18798 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
18799   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
18800   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
18801   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
18802 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
18803 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
18804 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
18805   "(auth_data 0x<data> | auth_data <data>)")                            \
18806 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
18807   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
18808 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
18809   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
18810   "(local|remote)")                                                     \
18811 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
18812 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
18813 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18814 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18815 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
18816 _(ikev2_initiate_sa_init, "<profile_name>")                             \
18817 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
18818 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
18819 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
18820 _(delete_loopback,"sw_if_index <nn>")                                   \
18821 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
18822 _(map_add_domain,                                                       \
18823   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
18824   "ip6-src <ip6addr> "                                                  \
18825   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
18826 _(map_del_domain, "index <n>")                                          \
18827 _(map_add_del_rule,                                                     \
18828   "index <n> psid <n> dst <ip6addr> [del]")                             \
18829 _(map_domain_dump, "")                                                  \
18830 _(map_rule_dump, "index <map-domain>")                                  \
18831 _(want_interface_events,  "enable|disable")                             \
18832 _(want_stats,"enable|disable")                                          \
18833 _(get_first_msg_id, "client <name>")                                    \
18834 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
18835 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
18836   "fib-id <nn> [ip4][ip6][default]")                                    \
18837 _(get_node_graph, " ")                                                  \
18838 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
18839 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
18840 _(ioam_disable, "")                                                     \
18841 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
18842                             " sw_if_index <sw_if_index> p <priority> "  \
18843                             "w <weight>] [del]")                        \
18844 _(one_add_del_locator, "locator-set <locator_name> "                    \
18845                         "iface <intf> | sw_if_index <sw_if_index> "     \
18846                         "p <priority> w <weight> [del]")                \
18847 _(one_add_del_local_eid,"vni <vni> eid "                                \
18848                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
18849                          "locator-set <locator_name> [del]"             \
18850                          "[key-id sha1|sha256 secret-key <secret-key>]")\
18851 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
18852 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
18853 _(one_enable_disable, "enable|disable")                                 \
18854 _(one_map_register_enable_disable, "enable|disable")                    \
18855 _(one_rloc_probe_enable_disable, "enable|disable")                      \
18856 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
18857                                "[seid <seid>] "                         \
18858                                "rloc <locator> p <prio> "               \
18859                                "w <weight> [rloc <loc> ... ] "          \
18860                                "action <action> [del-all]")             \
18861 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
18862                           "<local-eid>")                                \
18863 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
18864 _(one_use_petr, "ip-address> | disable")                                \
18865 _(one_map_request_mode, "src-dst|dst-only")                             \
18866 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
18867 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
18868 _(one_locator_set_dump, "[local | remote]")                             \
18869 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
18870 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
18871                        "[local] | [remote]")                            \
18872 _(one_stats_enable_disable, "enable|disalbe")                           \
18873 _(show_one_stats_enable_disable, "")                                    \
18874 _(one_eid_table_vni_dump, "")                                           \
18875 _(one_eid_table_map_dump, "l2|l3")                                      \
18876 _(one_map_resolver_dump, "")                                            \
18877 _(one_map_server_dump, "")                                              \
18878 _(one_adjacencies_get, "vni <vni>")                                     \
18879 _(show_one_rloc_probe_state, "")                                        \
18880 _(show_one_map_register_state, "")                                      \
18881 _(show_one_status, "")                                                  \
18882 _(one_stats_dump, "")                                                   \
18883 _(one_get_map_request_itr_rlocs, "")                                    \
18884 _(show_one_pitr, "")                                                    \
18885 _(show_one_use_petr, "")                                                \
18886 _(show_one_map_request_mode, "")                                        \
18887 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
18888                             " sw_if_index <sw_if_index> p <priority> "  \
18889                             "w <weight>] [del]")                        \
18890 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
18891                         "iface <intf> | sw_if_index <sw_if_index> "     \
18892                         "p <priority> w <weight> [del]")                \
18893 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
18894                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
18895                          "locator-set <locator_name> [del]"             \
18896                          "[key-id sha1|sha256 secret-key <secret-key>]") \
18897 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
18898 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
18899 _(lisp_enable_disable, "enable|disable")                                \
18900 _(lisp_map_register_enable_disable, "enable|disable")                   \
18901 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
18902 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
18903                                "[seid <seid>] "                         \
18904                                "rloc <locator> p <prio> "               \
18905                                "w <weight> [rloc <loc> ... ] "          \
18906                                "action <action> [del-all]")             \
18907 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
18908                           "<local-eid>")                                \
18909 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
18910 _(lisp_use_petr, "<ip-address> | disable")                              \
18911 _(lisp_map_request_mode, "src-dst|dst-only")                            \
18912 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
18913 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
18914 _(lisp_locator_set_dump, "[local | remote]")                            \
18915 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
18916 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
18917                        "[local] | [remote]")                            \
18918 _(lisp_eid_table_vni_dump, "")                                          \
18919 _(lisp_eid_table_map_dump, "l2|l3")                                     \
18920 _(lisp_map_resolver_dump, "")                                           \
18921 _(lisp_map_server_dump, "")                                             \
18922 _(lisp_adjacencies_get, "vni <vni>")                                    \
18923 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
18924 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
18925 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
18926 _(gpe_get_encap_mode, "")                                               \
18927 _(lisp_gpe_add_del_iface, "up|down")                                    \
18928 _(lisp_gpe_enable_disable, "enable|disable")                            \
18929 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
18930   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
18931 _(show_lisp_rloc_probe_state, "")                                       \
18932 _(show_lisp_map_register_state, "")                                     \
18933 _(show_lisp_status, "")                                                 \
18934 _(lisp_get_map_request_itr_rlocs, "")                                   \
18935 _(show_lisp_pitr, "")                                                   \
18936 _(show_lisp_use_petr, "")                                               \
18937 _(show_lisp_map_request_mode, "")                                       \
18938 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
18939 _(af_packet_delete, "name <host interface name>")                       \
18940 _(policer_add_del, "name <policer name> <params> [del]")                \
18941 _(policer_dump, "[name <policer name>]")                                \
18942 _(policer_classify_set_interface,                                       \
18943   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18944   "  [l2-table <nn>] [del]")                                            \
18945 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
18946 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
18947     "[master|slave]")                                                   \
18948 _(netmap_delete, "name <interface name>")                               \
18949 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
18950 _(mpls_fib_dump, "")                                                    \
18951 _(classify_table_ids, "")                                               \
18952 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
18953 _(classify_table_info, "table_id <nn>")                                 \
18954 _(classify_session_dump, "table_id <nn>")                               \
18955 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
18956     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
18957     "[template_interval <nn>] [udp_checksum]")                          \
18958 _(ipfix_exporter_dump, "")                                              \
18959 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
18960 _(ipfix_classify_stream_dump, "")                                       \
18961 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
18962 _(ipfix_classify_table_dump, "")                                        \
18963 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
18964 _(sw_interface_span_dump, "")                                           \
18965 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
18966 _(pg_create_interface, "if_id <nn>")                                    \
18967 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
18968 _(pg_enable_disable, "[stream <id>] disable")                           \
18969 _(ip_source_and_port_range_check_add_del,                               \
18970   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
18971 _(ip_source_and_port_range_check_interface_add_del,                     \
18972   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
18973   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
18974 _(ipsec_gre_add_del_tunnel,                                             \
18975   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
18976 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
18977 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
18978 _(l2_interface_pbb_tag_rewrite,                                         \
18979   "<intfc> | sw_if_index <nn> \n"                                       \
18980   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
18981   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
18982 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
18983 _(flow_classify_set_interface,                                          \
18984   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
18985 _(flow_classify_dump, "type [ip4|ip6]")                                 \
18986 _(ip_fib_dump, "")                                                      \
18987 _(ip_mfib_dump, "")                                                     \
18988 _(ip6_fib_dump, "")                                                     \
18989 _(ip6_mfib_dump, "")                                                    \
18990 _(feature_enable_disable, "arc_name <arc_name> "                        \
18991   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
18992 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
18993 "[disable]")                                                            \
18994 _(l2_xconnect_dump, "")                                                 \
18995 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
18996 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
18997 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
18998
18999 /* List of command functions, CLI names map directly to functions */
19000 #define foreach_cli_function                                    \
19001 _(comment, "usage: comment <ignore-rest-of-line>")              \
19002 _(dump_interface_table, "usage: dump_interface_table")          \
19003 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
19004 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
19005 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
19006 _(dump_stats_table, "usage: dump_stats_table")                  \
19007 _(dump_macro_table, "usage: dump_macro_table ")                 \
19008 _(dump_node_table, "usage: dump_node_table")                    \
19009 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
19010 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
19011 _(echo, "usage: echo <message>")                                \
19012 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
19013 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
19014 _(help, "usage: help")                                          \
19015 _(q, "usage: quit")                                             \
19016 _(quit, "usage: quit")                                          \
19017 _(search_node_table, "usage: search_node_table <name>...")      \
19018 _(set, "usage: set <variable-name> <value>")                    \
19019 _(script, "usage: script <file-name>")                          \
19020 _(unset, "usage: unset <variable-name>")
19021
19022 #define _(N,n)                                  \
19023     static void vl_api_##n##_t_handler_uni      \
19024     (vl_api_##n##_t * mp)                       \
19025     {                                           \
19026         vat_main_t * vam = &vat_main;           \
19027         if (vam->json_output) {                 \
19028             vl_api_##n##_t_handler_json(mp);    \
19029         } else {                                \
19030             vl_api_##n##_t_handler(mp);         \
19031         }                                       \
19032     }
19033 foreach_vpe_api_reply_msg;
19034 #if VPP_API_TEST_BUILTIN == 0
19035 foreach_standalone_reply_msg;
19036 #endif
19037 #undef _
19038
19039 void
19040 vat_api_hookup (vat_main_t * vam)
19041 {
19042 #define _(N,n)                                                  \
19043     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
19044                            vl_api_##n##_t_handler_uni,          \
19045                            vl_noop_handler,                     \
19046                            vl_api_##n##_t_endian,               \
19047                            vl_api_##n##_t_print,                \
19048                            sizeof(vl_api_##n##_t), 1);
19049   foreach_vpe_api_reply_msg;
19050 #if VPP_API_TEST_BUILTIN == 0
19051   foreach_standalone_reply_msg;
19052 #endif
19053 #undef _
19054
19055 #if (VPP_API_TEST_BUILTIN==0)
19056   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
19057
19058   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
19059
19060   vam->function_by_name = hash_create_string (0, sizeof (uword));
19061
19062   vam->help_by_name = hash_create_string (0, sizeof (uword));
19063 #endif
19064
19065   /* API messages we can send */
19066 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
19067   foreach_vpe_api_msg;
19068 #undef _
19069
19070   /* Help strings */
19071 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
19072   foreach_vpe_api_msg;
19073 #undef _
19074
19075   /* CLI functions */
19076 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
19077   foreach_cli_function;
19078 #undef _
19079
19080   /* Help strings */
19081 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
19082   foreach_cli_function;
19083 #undef _
19084 }
19085
19086 #if VPP_API_TEST_BUILTIN
19087 static clib_error_t *
19088 vat_api_hookup_shim (vlib_main_t * vm)
19089 {
19090   vat_api_hookup (&vat_main);
19091   return 0;
19092 }
19093
19094 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
19095 #endif
19096
19097 /*
19098  * fd.io coding-style-patch-verification: ON
19099  *
19100  * Local Variables:
19101  * eval: (c-set-style "gnu")
19102  * End:
19103  */