API: Cleaning up message naming that does not follow the conventions
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/l2/l2_input.h>
26 #include <vnet/l2tp/l2tp.h>
27 #include <vnet/vxlan/vxlan.h>
28 #include <vnet/gre/gre.h>
29 #include <vnet/vxlan-gpe/vxlan_gpe.h>
30 #include <vnet/lisp-gpe/lisp_gpe.h>
31
32 #include <vpp/api/vpe_msg_enum.h>
33 #include <vnet/l2/l2_classify.h>
34 #include <vnet/l2/l2_vtr.h>
35 #include <vnet/classify/input_acl.h>
36 #include <vnet/classify/policer_classify.h>
37 #include <vnet/classify/flow_classify.h>
38 #include <vnet/mpls/mpls.h>
39 #include <vnet/ipsec/ipsec.h>
40 #include <vnet/ipsec/ikev2.h>
41 #include <inttypes.h>
42 #include <vnet/map/map.h>
43 #include <vnet/cop/cop.h>
44 #include <vnet/ip/ip6_hop_by_hop.h>
45 #include <vnet/ip/ip_source_and_port_range_check.h>
46 #include <vnet/policer/xlate.h>
47 #include <vnet/span/span.h>
48 #include <vnet/policer/policer.h>
49 #include <vnet/policer/police.h>
50 #include <vnet/mfib/mfib_types.h>
51
52 #include "vat/json_format.h"
53
54 #include <inttypes.h>
55 #include <sys/stat.h>
56
57 #define vl_typedefs             /* define message structures */
58 #include <vpp/api/vpe_all_api_h.h>
59 #undef vl_typedefs
60
61 /* declare message handlers for each api */
62
63 #define vl_endianfun            /* define message structures */
64 #include <vpp/api/vpe_all_api_h.h>
65 #undef vl_endianfun
66
67 /* instantiate all the print functions we know about */
68 #define vl_print(handle, ...)
69 #define vl_printfun
70 #include <vpp/api/vpe_all_api_h.h>
71 #undef vl_printfun
72
73 #define __plugin_msg_base 0
74 #include <vlibapi/vat_helper_macros.h>
75
76 f64
77 vat_time_now (vat_main_t * vam)
78 {
79 #if VPP_API_TEST_BUILTIN
80   return vlib_time_now (vam->vlib_main);
81 #else
82   return clib_time_now (&vam->clib_time);
83 #endif
84 }
85
86 void
87 errmsg (char *fmt, ...)
88 {
89   vat_main_t *vam = &vat_main;
90   va_list va;
91   u8 *s;
92
93   va_start (va, fmt);
94   s = va_format (0, fmt, &va);
95   va_end (va);
96
97   vec_add1 (s, 0);
98
99 #if VPP_API_TEST_BUILTIN
100   vlib_cli_output (vam->vlib_main, (char *) s);
101 #else
102   {
103     if (vam->ifp != stdin)
104       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
105                vam->input_line_number);
106     fformat (vam->ofp, (char *) s);
107     fflush (vam->ofp);
108   }
109 #endif
110
111   vec_free (s);
112 }
113
114 #if VPP_API_TEST_BUILTIN == 0
115 static uword
116 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
117 {
118   vat_main_t *vam = va_arg (*args, vat_main_t *);
119   u32 *result = va_arg (*args, u32 *);
120   u8 *if_name;
121   uword *p;
122
123   if (!unformat (input, "%s", &if_name))
124     return 0;
125
126   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
127   if (p == 0)
128     return 0;
129   *result = p[0];
130   return 1;
131 }
132
133 /* Parse an IP4 address %d.%d.%d.%d. */
134 uword
135 unformat_ip4_address (unformat_input_t * input, va_list * args)
136 {
137   u8 *result = va_arg (*args, u8 *);
138   unsigned a[4];
139
140   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
141     return 0;
142
143   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
144     return 0;
145
146   result[0] = a[0];
147   result[1] = a[1];
148   result[2] = a[2];
149   result[3] = a[3];
150
151   return 1;
152 }
153
154 uword
155 unformat_ethernet_address (unformat_input_t * input, va_list * args)
156 {
157   u8 *result = va_arg (*args, u8 *);
158   u32 i, a[6];
159
160   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
161                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
162     return 0;
163
164   /* Check range. */
165   for (i = 0; i < 6; i++)
166     if (a[i] >= (1 << 8))
167       return 0;
168
169   for (i = 0; i < 6; i++)
170     result[i] = a[i];
171
172   return 1;
173 }
174
175 /* Returns ethernet type as an int in host byte order. */
176 uword
177 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
178                                         va_list * args)
179 {
180   u16 *result = va_arg (*args, u16 *);
181   int type;
182
183   /* Numeric type. */
184   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
185     {
186       if (type >= (1 << 16))
187         return 0;
188       *result = type;
189       return 1;
190     }
191   return 0;
192 }
193
194 /* Parse an IP6 address. */
195 uword
196 unformat_ip6_address (unformat_input_t * input, va_list * args)
197 {
198   ip6_address_t *result = va_arg (*args, ip6_address_t *);
199   u16 hex_quads[8];
200   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
201   uword c, n_colon, double_colon_index;
202
203   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
204   double_colon_index = ARRAY_LEN (hex_quads);
205   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
206     {
207       hex_digit = 16;
208       if (c >= '0' && c <= '9')
209         hex_digit = c - '0';
210       else if (c >= 'a' && c <= 'f')
211         hex_digit = c + 10 - 'a';
212       else if (c >= 'A' && c <= 'F')
213         hex_digit = c + 10 - 'A';
214       else if (c == ':' && n_colon < 2)
215         n_colon++;
216       else
217         {
218           unformat_put_input (input);
219           break;
220         }
221
222       /* Too many hex quads. */
223       if (n_hex_quads >= ARRAY_LEN (hex_quads))
224         return 0;
225
226       if (hex_digit < 16)
227         {
228           hex_quad = (hex_quad << 4) | hex_digit;
229
230           /* Hex quad must fit in 16 bits. */
231           if (n_hex_digits >= 4)
232             return 0;
233
234           n_colon = 0;
235           n_hex_digits++;
236         }
237
238       /* Save position of :: */
239       if (n_colon == 2)
240         {
241           /* More than one :: ? */
242           if (double_colon_index < ARRAY_LEN (hex_quads))
243             return 0;
244           double_colon_index = n_hex_quads;
245         }
246
247       if (n_colon > 0 && n_hex_digits > 0)
248         {
249           hex_quads[n_hex_quads++] = hex_quad;
250           hex_quad = 0;
251           n_hex_digits = 0;
252         }
253     }
254
255   if (n_hex_digits > 0)
256     hex_quads[n_hex_quads++] = hex_quad;
257
258   {
259     word i;
260
261     /* Expand :: to appropriate number of zero hex quads. */
262     if (double_colon_index < ARRAY_LEN (hex_quads))
263       {
264         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
265
266         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
267           hex_quads[n_zero + i] = hex_quads[i];
268
269         for (i = 0; i < n_zero; i++)
270           hex_quads[double_colon_index + i] = 0;
271
272         n_hex_quads = ARRAY_LEN (hex_quads);
273       }
274
275     /* Too few hex quads given. */
276     if (n_hex_quads < ARRAY_LEN (hex_quads))
277       return 0;
278
279     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
280       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
281
282     return 1;
283   }
284 }
285
286 uword
287 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
288 {
289   u32 *r = va_arg (*args, u32 *);
290
291   if (0);
292 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
293   foreach_ipsec_policy_action
294 #undef _
295     else
296     return 0;
297   return 1;
298 }
299
300 uword
301 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
302 {
303   u32 *r = va_arg (*args, u32 *);
304
305   if (0);
306 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
307   foreach_ipsec_crypto_alg
308 #undef _
309     else
310     return 0;
311   return 1;
312 }
313
314 u8 *
315 format_ipsec_crypto_alg (u8 * s, va_list * args)
316 {
317   u32 i = va_arg (*args, u32);
318   u8 *t = 0;
319
320   switch (i)
321     {
322 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
323       foreach_ipsec_crypto_alg
324 #undef _
325     default:
326       return format (s, "unknown");
327     }
328   return format (s, "%s", t);
329 }
330
331 uword
332 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
333 {
334   u32 *r = va_arg (*args, u32 *);
335
336   if (0);
337 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
338   foreach_ipsec_integ_alg
339 #undef _
340     else
341     return 0;
342   return 1;
343 }
344
345 u8 *
346 format_ipsec_integ_alg (u8 * s, va_list * args)
347 {
348   u32 i = va_arg (*args, u32);
349   u8 *t = 0;
350
351   switch (i)
352     {
353 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
354       foreach_ipsec_integ_alg
355 #undef _
356     default:
357       return format (s, "unknown");
358     }
359   return format (s, "%s", t);
360 }
361
362 uword
363 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
364 {
365   u32 *r = va_arg (*args, u32 *);
366
367   if (0);
368 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
369   foreach_ikev2_auth_method
370 #undef _
371     else
372     return 0;
373   return 1;
374 }
375
376 uword
377 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
378 {
379   u32 *r = va_arg (*args, u32 *);
380
381   if (0);
382 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
383   foreach_ikev2_id_type
384 #undef _
385     else
386     return 0;
387   return 1;
388 }
389 #else /* VPP_API_TEST_BUILTIN == 1 */
390 static uword
391 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
392 {
393   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
394   vnet_main_t *vnm = vnet_get_main ();
395   u32 *result = va_arg (*args, u32 *);
396   u32 sw_if_index;
397
398   if (!unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
399     return 0;
400
401   *result = sw_if_index;
402   return 1;
403 }
404 #endif /* VPP_API_TEST_BUILTIN */
405
406 #define VHOST_USER_POLLING_MODE   0
407 #define VHOST_USER_INTERRUPT_MODE 1
408 #define VHOST_USER_ADAPTIVE_MODE  2
409
410 static u8 *
411 api_format_vhost_user_operation_mode (u8 * s, va_list * va)
412 {
413   int operation_mode = va_arg (*va, int);
414
415   switch (operation_mode)
416     {
417     case VHOST_USER_POLLING_MODE:
418       s = format (s, "%-9s", "polling");
419       break;
420     case VHOST_USER_INTERRUPT_MODE:
421       s = format (s, "%-9s", "interrupt");
422       break;
423     default:
424       s = format (s, "%-9s", "invalid");
425     }
426   return s;
427 }
428
429 static uword
430 api_unformat_vhost_user_operation_mode (unformat_input_t * input,
431                                         va_list * args)
432 {
433   u8 *operation_mode = va_arg (*args, u8 *);
434   uword rc = 1;
435
436   if (unformat (input, "interrupt"))
437     *operation_mode = VHOST_USER_INTERRUPT_MODE;
438   else if (unformat (input, "polling"))
439     *operation_mode = VHOST_USER_POLLING_MODE;
440   else
441     rc = 0;
442
443   return rc;
444 }
445
446 static uword
447 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
448 {
449   u8 *r = va_arg (*args, u8 *);
450
451   if (unformat (input, "kbps"))
452     *r = SSE2_QOS_RATE_KBPS;
453   else if (unformat (input, "pps"))
454     *r = SSE2_QOS_RATE_PPS;
455   else
456     return 0;
457   return 1;
458 }
459
460 static uword
461 unformat_policer_round_type (unformat_input_t * input, va_list * args)
462 {
463   u8 *r = va_arg (*args, u8 *);
464
465   if (unformat (input, "closest"))
466     *r = SSE2_QOS_ROUND_TO_CLOSEST;
467   else if (unformat (input, "up"))
468     *r = SSE2_QOS_ROUND_TO_UP;
469   else if (unformat (input, "down"))
470     *r = SSE2_QOS_ROUND_TO_DOWN;
471   else
472     return 0;
473   return 1;
474 }
475
476 static uword
477 unformat_policer_type (unformat_input_t * input, va_list * args)
478 {
479   u8 *r = va_arg (*args, u8 *);
480
481   if (unformat (input, "1r2c"))
482     *r = SSE2_QOS_POLICER_TYPE_1R2C;
483   else if (unformat (input, "1r3c"))
484     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
485   else if (unformat (input, "2r3c-2698"))
486     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
487   else if (unformat (input, "2r3c-4115"))
488     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
489   else if (unformat (input, "2r3c-mef5cf1"))
490     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
491   else
492     return 0;
493   return 1;
494 }
495
496 static uword
497 unformat_dscp (unformat_input_t * input, va_list * va)
498 {
499   u8 *r = va_arg (*va, u8 *);
500
501   if (0);
502 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
503   foreach_vnet_dscp
504 #undef _
505     else
506     return 0;
507   return 1;
508 }
509
510 static uword
511 unformat_policer_action_type (unformat_input_t * input, va_list * va)
512 {
513   sse2_qos_pol_action_params_st *a
514     = va_arg (*va, sse2_qos_pol_action_params_st *);
515
516   if (unformat (input, "drop"))
517     a->action_type = SSE2_QOS_ACTION_DROP;
518   else if (unformat (input, "transmit"))
519     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
520   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
521     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
522   else
523     return 0;
524   return 1;
525 }
526
527 static uword
528 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
529 {
530   u32 *r = va_arg (*va, u32 *);
531   u32 tid;
532
533   if (unformat (input, "ip4"))
534     tid = POLICER_CLASSIFY_TABLE_IP4;
535   else if (unformat (input, "ip6"))
536     tid = POLICER_CLASSIFY_TABLE_IP6;
537   else if (unformat (input, "l2"))
538     tid = POLICER_CLASSIFY_TABLE_L2;
539   else
540     return 0;
541
542   *r = tid;
543   return 1;
544 }
545
546 static uword
547 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
548 {
549   u32 *r = va_arg (*va, u32 *);
550   u32 tid;
551
552   if (unformat (input, "ip4"))
553     tid = FLOW_CLASSIFY_TABLE_IP4;
554   else if (unformat (input, "ip6"))
555     tid = FLOW_CLASSIFY_TABLE_IP6;
556   else
557     return 0;
558
559   *r = tid;
560   return 1;
561 }
562
563 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
564 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
565 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
566 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
567
568 #if (VPP_API_TEST_BUILTIN==0)
569 uword
570 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
571 {
572   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
573   mfib_itf_attribute_t attr;
574
575   old = *iflags;
576   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
577   {
578     if (unformat (input, mfib_itf_flag_long_names[attr]))
579       *iflags |= (1 << attr);
580   }
581   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
582   {
583     if (unformat (input, mfib_itf_flag_names[attr]))
584       *iflags |= (1 << attr);
585   }
586
587   return (old == *iflags ? 0 : 1);
588 }
589
590 uword
591 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
592 {
593   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
594   mfib_entry_attribute_t attr;
595
596   old = *eflags;
597   FOR_EACH_MFIB_ATTRIBUTE (attr)
598   {
599     if (unformat (input, mfib_flag_long_names[attr]))
600       *eflags |= (1 << attr);
601   }
602   FOR_EACH_MFIB_ATTRIBUTE (attr)
603   {
604     if (unformat (input, mfib_flag_names[attr]))
605       *eflags |= (1 << attr);
606   }
607
608   return (old == *eflags ? 0 : 1);
609 }
610
611 u8 *
612 format_ip4_address (u8 * s, va_list * args)
613 {
614   u8 *a = va_arg (*args, u8 *);
615   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
616 }
617
618 u8 *
619 format_ip6_address (u8 * s, va_list * args)
620 {
621   ip6_address_t *a = va_arg (*args, ip6_address_t *);
622   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
623
624   i_max_n_zero = ARRAY_LEN (a->as_u16);
625   max_n_zeros = 0;
626   i_first_zero = i_max_n_zero;
627   n_zeros = 0;
628   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
629     {
630       u32 is_zero = a->as_u16[i] == 0;
631       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
632         {
633           i_first_zero = i;
634           n_zeros = 0;
635         }
636       n_zeros += is_zero;
637       if ((!is_zero && n_zeros > max_n_zeros)
638           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
639         {
640           i_max_n_zero = i_first_zero;
641           max_n_zeros = n_zeros;
642           i_first_zero = ARRAY_LEN (a->as_u16);
643           n_zeros = 0;
644         }
645     }
646
647   last_double_colon = 0;
648   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
649     {
650       if (i == i_max_n_zero && max_n_zeros > 1)
651         {
652           s = format (s, "::");
653           i += max_n_zeros - 1;
654           last_double_colon = 1;
655         }
656       else
657         {
658           s = format (s, "%s%x",
659                       (last_double_colon || i == 0) ? "" : ":",
660                       clib_net_to_host_u16 (a->as_u16[i]));
661           last_double_colon = 0;
662         }
663     }
664
665   return s;
666 }
667
668 /* Format an IP46 address. */
669 u8 *
670 format_ip46_address (u8 * s, va_list * args)
671 {
672   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
673   ip46_type_t type = va_arg (*args, ip46_type_t);
674   int is_ip4 = 1;
675
676   switch (type)
677     {
678     case IP46_TYPE_ANY:
679       is_ip4 = ip46_address_is_ip4 (ip46);
680       break;
681     case IP46_TYPE_IP4:
682       is_ip4 = 1;
683       break;
684     case IP46_TYPE_IP6:
685       is_ip4 = 0;
686       break;
687     }
688
689   return is_ip4 ?
690     format (s, "%U", format_ip4_address, &ip46->ip4) :
691     format (s, "%U", format_ip6_address, &ip46->ip6);
692 }
693
694 u8 *
695 format_ethernet_address (u8 * s, va_list * args)
696 {
697   u8 *a = va_arg (*args, u8 *);
698
699   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
700                  a[0], a[1], a[2], a[3], a[4], a[5]);
701 }
702 #endif
703
704 static void
705 increment_v4_address (ip4_address_t * a)
706 {
707   u32 v;
708
709   v = ntohl (a->as_u32) + 1;
710   a->as_u32 = ntohl (v);
711 }
712
713 static void
714 increment_v6_address (ip6_address_t * a)
715 {
716   u64 v0, v1;
717
718   v0 = clib_net_to_host_u64 (a->as_u64[0]);
719   v1 = clib_net_to_host_u64 (a->as_u64[1]);
720
721   v1 += 1;
722   if (v1 == 0)
723     v0 += 1;
724   a->as_u64[0] = clib_net_to_host_u64 (v0);
725   a->as_u64[1] = clib_net_to_host_u64 (v1);
726 }
727
728 static void
729 increment_mac_address (u64 * mac)
730 {
731   u64 tmp = *mac;
732
733   tmp = clib_net_to_host_u64 (tmp);
734   tmp += 1 << 16;               /* skip unused (least significant) octets */
735   tmp = clib_host_to_net_u64 (tmp);
736   *mac = tmp;
737 }
738
739 static void vl_api_create_loopback_reply_t_handler
740   (vl_api_create_loopback_reply_t * mp)
741 {
742   vat_main_t *vam = &vat_main;
743   i32 retval = ntohl (mp->retval);
744
745   vam->retval = retval;
746   vam->regenerate_interface_table = 1;
747   vam->sw_if_index = ntohl (mp->sw_if_index);
748   vam->result_ready = 1;
749 }
750
751 static void vl_api_create_loopback_reply_t_handler_json
752   (vl_api_create_loopback_reply_t * mp)
753 {
754   vat_main_t *vam = &vat_main;
755   vat_json_node_t node;
756
757   vat_json_init_object (&node);
758   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
759   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
760
761   vat_json_print (vam->ofp, &node);
762   vat_json_free (&node);
763   vam->retval = ntohl (mp->retval);
764   vam->result_ready = 1;
765 }
766
767 static void vl_api_create_loopback_instance_reply_t_handler
768   (vl_api_create_loopback_instance_reply_t * mp)
769 {
770   vat_main_t *vam = &vat_main;
771   i32 retval = ntohl (mp->retval);
772
773   vam->retval = retval;
774   vam->regenerate_interface_table = 1;
775   vam->sw_if_index = ntohl (mp->sw_if_index);
776   vam->result_ready = 1;
777 }
778
779 static void vl_api_create_loopback_instance_reply_t_handler_json
780   (vl_api_create_loopback_instance_reply_t * mp)
781 {
782   vat_main_t *vam = &vat_main;
783   vat_json_node_t node;
784
785   vat_json_init_object (&node);
786   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
787   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
788
789   vat_json_print (vam->ofp, &node);
790   vat_json_free (&node);
791   vam->retval = ntohl (mp->retval);
792   vam->result_ready = 1;
793 }
794
795 static void vl_api_af_packet_create_reply_t_handler
796   (vl_api_af_packet_create_reply_t * mp)
797 {
798   vat_main_t *vam = &vat_main;
799   i32 retval = ntohl (mp->retval);
800
801   vam->retval = retval;
802   vam->regenerate_interface_table = 1;
803   vam->sw_if_index = ntohl (mp->sw_if_index);
804   vam->result_ready = 1;
805 }
806
807 static void vl_api_af_packet_create_reply_t_handler_json
808   (vl_api_af_packet_create_reply_t * mp)
809 {
810   vat_main_t *vam = &vat_main;
811   vat_json_node_t node;
812
813   vat_json_init_object (&node);
814   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
815   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
816
817   vat_json_print (vam->ofp, &node);
818   vat_json_free (&node);
819
820   vam->retval = ntohl (mp->retval);
821   vam->result_ready = 1;
822 }
823
824 static void vl_api_create_vlan_subif_reply_t_handler
825   (vl_api_create_vlan_subif_reply_t * mp)
826 {
827   vat_main_t *vam = &vat_main;
828   i32 retval = ntohl (mp->retval);
829
830   vam->retval = retval;
831   vam->regenerate_interface_table = 1;
832   vam->sw_if_index = ntohl (mp->sw_if_index);
833   vam->result_ready = 1;
834 }
835
836 static void vl_api_create_vlan_subif_reply_t_handler_json
837   (vl_api_create_vlan_subif_reply_t * mp)
838 {
839   vat_main_t *vam = &vat_main;
840   vat_json_node_t node;
841
842   vat_json_init_object (&node);
843   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
844   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
845
846   vat_json_print (vam->ofp, &node);
847   vat_json_free (&node);
848
849   vam->retval = ntohl (mp->retval);
850   vam->result_ready = 1;
851 }
852
853 static void vl_api_create_subif_reply_t_handler
854   (vl_api_create_subif_reply_t * mp)
855 {
856   vat_main_t *vam = &vat_main;
857   i32 retval = ntohl (mp->retval);
858
859   vam->retval = retval;
860   vam->regenerate_interface_table = 1;
861   vam->sw_if_index = ntohl (mp->sw_if_index);
862   vam->result_ready = 1;
863 }
864
865 static void vl_api_create_subif_reply_t_handler_json
866   (vl_api_create_subif_reply_t * mp)
867 {
868   vat_main_t *vam = &vat_main;
869   vat_json_node_t node;
870
871   vat_json_init_object (&node);
872   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
873   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
874
875   vat_json_print (vam->ofp, &node);
876   vat_json_free (&node);
877
878   vam->retval = ntohl (mp->retval);
879   vam->result_ready = 1;
880 }
881
882 static void vl_api_interface_name_renumber_reply_t_handler
883   (vl_api_interface_name_renumber_reply_t * mp)
884 {
885   vat_main_t *vam = &vat_main;
886   i32 retval = ntohl (mp->retval);
887
888   vam->retval = retval;
889   vam->regenerate_interface_table = 1;
890   vam->result_ready = 1;
891 }
892
893 static void vl_api_interface_name_renumber_reply_t_handler_json
894   (vl_api_interface_name_renumber_reply_t * mp)
895 {
896   vat_main_t *vam = &vat_main;
897   vat_json_node_t node;
898
899   vat_json_init_object (&node);
900   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
901
902   vat_json_print (vam->ofp, &node);
903   vat_json_free (&node);
904
905   vam->retval = ntohl (mp->retval);
906   vam->result_ready = 1;
907 }
908
909 /*
910  * Special-case: build the interface table, maintain
911  * the next loopback sw_if_index vbl.
912  */
913 static void vl_api_sw_interface_details_t_handler
914   (vl_api_sw_interface_details_t * mp)
915 {
916   vat_main_t *vam = &vat_main;
917   u8 *s = format (0, "%s%c", mp->interface_name, 0);
918
919   hash_set_mem (vam->sw_if_index_by_interface_name, s,
920                 ntohl (mp->sw_if_index));
921
922   /* In sub interface case, fill the sub interface table entry */
923   if (mp->sw_if_index != mp->sup_sw_if_index)
924     {
925       sw_interface_subif_t *sub = NULL;
926
927       vec_add2 (vam->sw_if_subif_table, sub, 1);
928
929       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
930       strncpy ((char *) sub->interface_name, (char *) s,
931                vec_len (sub->interface_name));
932       sub->sw_if_index = ntohl (mp->sw_if_index);
933       sub->sub_id = ntohl (mp->sub_id);
934
935       sub->sub_dot1ad = mp->sub_dot1ad;
936       sub->sub_number_of_tags = mp->sub_number_of_tags;
937       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
938       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
939       sub->sub_exact_match = mp->sub_exact_match;
940       sub->sub_default = mp->sub_default;
941       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
942       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
943
944       /* vlan tag rewrite */
945       sub->vtr_op = ntohl (mp->vtr_op);
946       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
947       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
948       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
949     }
950 }
951
952 static void vl_api_sw_interface_details_t_handler_json
953   (vl_api_sw_interface_details_t * mp)
954 {
955   vat_main_t *vam = &vat_main;
956   vat_json_node_t *node = NULL;
957
958   if (VAT_JSON_ARRAY != vam->json_tree.type)
959     {
960       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
961       vat_json_init_array (&vam->json_tree);
962     }
963   node = vat_json_array_add (&vam->json_tree);
964
965   vat_json_init_object (node);
966   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
967   vat_json_object_add_uint (node, "sup_sw_if_index",
968                             ntohl (mp->sup_sw_if_index));
969   vat_json_object_add_uint (node, "l2_address_length",
970                             ntohl (mp->l2_address_length));
971   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
972                              sizeof (mp->l2_address));
973   vat_json_object_add_string_copy (node, "interface_name",
974                                    mp->interface_name);
975   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
976   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
977   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
978   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
979   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
980   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
981   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
982   vat_json_object_add_uint (node, "sub_number_of_tags",
983                             mp->sub_number_of_tags);
984   vat_json_object_add_uint (node, "sub_outer_vlan_id",
985                             ntohs (mp->sub_outer_vlan_id));
986   vat_json_object_add_uint (node, "sub_inner_vlan_id",
987                             ntohs (mp->sub_inner_vlan_id));
988   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
989   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
990   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
991                             mp->sub_outer_vlan_id_any);
992   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
993                             mp->sub_inner_vlan_id_any);
994   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
995   vat_json_object_add_uint (node, "vtr_push_dot1q",
996                             ntohl (mp->vtr_push_dot1q));
997   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
998   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
999   if (mp->sub_dot1ah)
1000     {
1001       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1002                                        format (0, "%U",
1003                                                format_ethernet_address,
1004                                                &mp->b_dmac));
1005       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1006                                        format (0, "%U",
1007                                                format_ethernet_address,
1008                                                &mp->b_smac));
1009       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1010       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1011     }
1012 }
1013
1014 #if VPP_API_TEST_BUILTIN == 0
1015 static void vl_api_sw_interface_set_flags_t_handler
1016   (vl_api_sw_interface_set_flags_t * mp)
1017 {
1018   vat_main_t *vam = &vat_main;
1019   if (vam->interface_event_display)
1020     errmsg ("interface flags: sw_if_index %d %s %s",
1021             ntohl (mp->sw_if_index),
1022             mp->admin_up_down ? "admin-up" : "admin-down",
1023             mp->link_up_down ? "link-up" : "link-down");
1024 }
1025 #endif
1026
1027 static void vl_api_sw_interface_set_flags_t_handler_json
1028   (vl_api_sw_interface_set_flags_t * mp)
1029 {
1030   /* JSON output not supported */
1031 }
1032
1033 static void
1034 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1035 {
1036   vat_main_t *vam = &vat_main;
1037   i32 retval = ntohl (mp->retval);
1038
1039   vam->retval = retval;
1040   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1041   vam->result_ready = 1;
1042 }
1043
1044 static void
1045 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1046 {
1047   vat_main_t *vam = &vat_main;
1048   vat_json_node_t node;
1049   api_main_t *am = &api_main;
1050   void *oldheap;
1051   u8 *reply;
1052
1053   vat_json_init_object (&node);
1054   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1055   vat_json_object_add_uint (&node, "reply_in_shmem",
1056                             ntohl (mp->reply_in_shmem));
1057   /* Toss the shared-memory original... */
1058   pthread_mutex_lock (&am->vlib_rp->mutex);
1059   oldheap = svm_push_data_heap (am->vlib_rp);
1060
1061   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1062   vec_free (reply);
1063
1064   svm_pop_heap (oldheap);
1065   pthread_mutex_unlock (&am->vlib_rp->mutex);
1066
1067   vat_json_print (vam->ofp, &node);
1068   vat_json_free (&node);
1069
1070   vam->retval = ntohl (mp->retval);
1071   vam->result_ready = 1;
1072 }
1073
1074 static void
1075 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1076 {
1077   vat_main_t *vam = &vat_main;
1078   i32 retval = ntohl (mp->retval);
1079
1080   vam->retval = retval;
1081   vam->cmd_reply = mp->reply;
1082   vam->result_ready = 1;
1083 }
1084
1085 static void
1086 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1087 {
1088   vat_main_t *vam = &vat_main;
1089   vat_json_node_t node;
1090
1091   vat_json_init_object (&node);
1092   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1093   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1094
1095   vat_json_print (vam->ofp, &node);
1096   vat_json_free (&node);
1097
1098   vam->retval = ntohl (mp->retval);
1099   vam->result_ready = 1;
1100 }
1101
1102 static void vl_api_classify_add_del_table_reply_t_handler
1103   (vl_api_classify_add_del_table_reply_t * mp)
1104 {
1105   vat_main_t *vam = &vat_main;
1106   i32 retval = ntohl (mp->retval);
1107   if (vam->async_mode)
1108     {
1109       vam->async_errors += (retval < 0);
1110     }
1111   else
1112     {
1113       vam->retval = retval;
1114       if (retval == 0 &&
1115           ((mp->new_table_index != 0xFFFFFFFF) ||
1116            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1117            (mp->match_n_vectors != 0xFFFFFFFF)))
1118         /*
1119          * Note: this is just barely thread-safe, depends on
1120          * the main thread spinning waiting for an answer...
1121          */
1122         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1123                 ntohl (mp->new_table_index),
1124                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1125       vam->result_ready = 1;
1126     }
1127 }
1128
1129 static void vl_api_classify_add_del_table_reply_t_handler_json
1130   (vl_api_classify_add_del_table_reply_t * mp)
1131 {
1132   vat_main_t *vam = &vat_main;
1133   vat_json_node_t node;
1134
1135   vat_json_init_object (&node);
1136   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1137   vat_json_object_add_uint (&node, "new_table_index",
1138                             ntohl (mp->new_table_index));
1139   vat_json_object_add_uint (&node, "skip_n_vectors",
1140                             ntohl (mp->skip_n_vectors));
1141   vat_json_object_add_uint (&node, "match_n_vectors",
1142                             ntohl (mp->match_n_vectors));
1143
1144   vat_json_print (vam->ofp, &node);
1145   vat_json_free (&node);
1146
1147   vam->retval = ntohl (mp->retval);
1148   vam->result_ready = 1;
1149 }
1150
1151 static void vl_api_get_node_index_reply_t_handler
1152   (vl_api_get_node_index_reply_t * mp)
1153 {
1154   vat_main_t *vam = &vat_main;
1155   i32 retval = ntohl (mp->retval);
1156   if (vam->async_mode)
1157     {
1158       vam->async_errors += (retval < 0);
1159     }
1160   else
1161     {
1162       vam->retval = retval;
1163       if (retval == 0)
1164         errmsg ("node index %d", ntohl (mp->node_index));
1165       vam->result_ready = 1;
1166     }
1167 }
1168
1169 static void vl_api_get_node_index_reply_t_handler_json
1170   (vl_api_get_node_index_reply_t * mp)
1171 {
1172   vat_main_t *vam = &vat_main;
1173   vat_json_node_t node;
1174
1175   vat_json_init_object (&node);
1176   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1177   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1178
1179   vat_json_print (vam->ofp, &node);
1180   vat_json_free (&node);
1181
1182   vam->retval = ntohl (mp->retval);
1183   vam->result_ready = 1;
1184 }
1185
1186 static void vl_api_get_next_index_reply_t_handler
1187   (vl_api_get_next_index_reply_t * mp)
1188 {
1189   vat_main_t *vam = &vat_main;
1190   i32 retval = ntohl (mp->retval);
1191   if (vam->async_mode)
1192     {
1193       vam->async_errors += (retval < 0);
1194     }
1195   else
1196     {
1197       vam->retval = retval;
1198       if (retval == 0)
1199         errmsg ("next node index %d", ntohl (mp->next_index));
1200       vam->result_ready = 1;
1201     }
1202 }
1203
1204 static void vl_api_get_next_index_reply_t_handler_json
1205   (vl_api_get_next_index_reply_t * mp)
1206 {
1207   vat_main_t *vam = &vat_main;
1208   vat_json_node_t node;
1209
1210   vat_json_init_object (&node);
1211   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1212   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1213
1214   vat_json_print (vam->ofp, &node);
1215   vat_json_free (&node);
1216
1217   vam->retval = ntohl (mp->retval);
1218   vam->result_ready = 1;
1219 }
1220
1221 static void vl_api_add_node_next_reply_t_handler
1222   (vl_api_add_node_next_reply_t * mp)
1223 {
1224   vat_main_t *vam = &vat_main;
1225   i32 retval = ntohl (mp->retval);
1226   if (vam->async_mode)
1227     {
1228       vam->async_errors += (retval < 0);
1229     }
1230   else
1231     {
1232       vam->retval = retval;
1233       if (retval == 0)
1234         errmsg ("next index %d", ntohl (mp->next_index));
1235       vam->result_ready = 1;
1236     }
1237 }
1238
1239 static void vl_api_add_node_next_reply_t_handler_json
1240   (vl_api_add_node_next_reply_t * mp)
1241 {
1242   vat_main_t *vam = &vat_main;
1243   vat_json_node_t node;
1244
1245   vat_json_init_object (&node);
1246   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1247   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1248
1249   vat_json_print (vam->ofp, &node);
1250   vat_json_free (&node);
1251
1252   vam->retval = ntohl (mp->retval);
1253   vam->result_ready = 1;
1254 }
1255
1256 static void vl_api_show_version_reply_t_handler
1257   (vl_api_show_version_reply_t * mp)
1258 {
1259   vat_main_t *vam = &vat_main;
1260   i32 retval = ntohl (mp->retval);
1261
1262   if (retval >= 0)
1263     {
1264       errmsg ("        program: %s", mp->program);
1265       errmsg ("        version: %s", mp->version);
1266       errmsg ("     build date: %s", mp->build_date);
1267       errmsg ("build directory: %s", mp->build_directory);
1268     }
1269   vam->retval = retval;
1270   vam->result_ready = 1;
1271 }
1272
1273 static void vl_api_show_version_reply_t_handler_json
1274   (vl_api_show_version_reply_t * mp)
1275 {
1276   vat_main_t *vam = &vat_main;
1277   vat_json_node_t node;
1278
1279   vat_json_init_object (&node);
1280   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1281   vat_json_object_add_string_copy (&node, "program", mp->program);
1282   vat_json_object_add_string_copy (&node, "version", mp->version);
1283   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1284   vat_json_object_add_string_copy (&node, "build_directory",
1285                                    mp->build_directory);
1286
1287   vat_json_print (vam->ofp, &node);
1288   vat_json_free (&node);
1289
1290   vam->retval = ntohl (mp->retval);
1291   vam->result_ready = 1;
1292 }
1293
1294 static void
1295 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1296 {
1297   u32 sw_if_index = ntohl (mp->sw_if_index);
1298   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1299           mp->mac_ip ? "mac/ip binding" : "address resolution",
1300           ntohl (mp->pid), format_ip4_address, &mp->address,
1301           format_ethernet_address, mp->new_mac, sw_if_index);
1302 }
1303
1304 static void
1305 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1306 {
1307   /* JSON output not supported */
1308 }
1309
1310 static void
1311 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1312 {
1313   u32 sw_if_index = ntohl (mp->sw_if_index);
1314   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1315           mp->mac_ip ? "mac/ip binding" : "address resolution",
1316           ntohl (mp->pid), format_ip6_address, mp->address,
1317           format_ethernet_address, mp->new_mac, sw_if_index);
1318 }
1319
1320 static void
1321 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1322 {
1323   /* JSON output not supported */
1324 }
1325
1326 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1327 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1328
1329 /*
1330  * Special-case: build the bridge domain table, maintain
1331  * the next bd id vbl.
1332  */
1333 static void vl_api_bridge_domain_details_t_handler
1334   (vl_api_bridge_domain_details_t * mp)
1335 {
1336   vat_main_t *vam = &vat_main;
1337   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1338   int i;
1339
1340   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1341          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1342
1343   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1344          ntohl (mp->bd_id), mp->learn, mp->forward,
1345          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1346
1347   if (n_sw_ifs)
1348     {
1349       vl_api_bridge_domain_sw_if_t *sw_ifs;
1350       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1351              "Interface Name");
1352
1353       sw_ifs = mp->sw_if_details;
1354       for (i = 0; i < n_sw_ifs; i++)
1355         {
1356           u8 *sw_if_name = 0;
1357           u32 sw_if_index;
1358           hash_pair_t *p;
1359
1360           sw_if_index = ntohl (sw_ifs->sw_if_index);
1361
1362           /* *INDENT-OFF* */
1363           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1364                              ({
1365                                if ((u32) p->value[0] == sw_if_index)
1366                                  {
1367                                    sw_if_name = (u8 *)(p->key);
1368                                    break;
1369                                  }
1370                              }));
1371           /* *INDENT-ON* */
1372           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1373                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1374                  "sw_if_index not found!");
1375
1376           sw_ifs++;
1377         }
1378     }
1379 }
1380
1381 static void vl_api_bridge_domain_details_t_handler_json
1382   (vl_api_bridge_domain_details_t * mp)
1383 {
1384   vat_main_t *vam = &vat_main;
1385   vat_json_node_t *node, *array = NULL;
1386   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1387
1388   if (VAT_JSON_ARRAY != vam->json_tree.type)
1389     {
1390       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1391       vat_json_init_array (&vam->json_tree);
1392     }
1393   node = vat_json_array_add (&vam->json_tree);
1394
1395   vat_json_init_object (node);
1396   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1397   vat_json_object_add_uint (node, "flood", mp->flood);
1398   vat_json_object_add_uint (node, "forward", mp->forward);
1399   vat_json_object_add_uint (node, "learn", mp->learn);
1400   vat_json_object_add_uint (node, "bvi_sw_if_index",
1401                             ntohl (mp->bvi_sw_if_index));
1402   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1403   array = vat_json_object_add (node, "sw_if");
1404   vat_json_init_array (array);
1405
1406
1407
1408   if (n_sw_ifs)
1409     {
1410       vl_api_bridge_domain_sw_if_t *sw_ifs;
1411       int i;
1412
1413       sw_ifs = mp->sw_if_details;
1414       for (i = 0; i < n_sw_ifs; i++)
1415         {
1416           node = vat_json_array_add (array);
1417           vat_json_init_object (node);
1418           vat_json_object_add_uint (node, "sw_if_index",
1419                                     ntohl (sw_ifs->sw_if_index));
1420           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1421           sw_ifs++;
1422         }
1423     }
1424 }
1425
1426 static void vl_api_control_ping_reply_t_handler
1427   (vl_api_control_ping_reply_t * mp)
1428 {
1429   vat_main_t *vam = &vat_main;
1430   i32 retval = ntohl (mp->retval);
1431   if (vam->async_mode)
1432     {
1433       vam->async_errors += (retval < 0);
1434     }
1435   else
1436     {
1437       vam->retval = retval;
1438       vam->result_ready = 1;
1439     }
1440 }
1441
1442 static void vl_api_control_ping_reply_t_handler_json
1443   (vl_api_control_ping_reply_t * mp)
1444 {
1445   vat_main_t *vam = &vat_main;
1446   i32 retval = ntohl (mp->retval);
1447
1448   if (VAT_JSON_NONE != vam->json_tree.type)
1449     {
1450       vat_json_print (vam->ofp, &vam->json_tree);
1451       vat_json_free (&vam->json_tree);
1452       vam->json_tree.type = VAT_JSON_NONE;
1453     }
1454   else
1455     {
1456       /* just print [] */
1457       vat_json_init_array (&vam->json_tree);
1458       vat_json_print (vam->ofp, &vam->json_tree);
1459       vam->json_tree.type = VAT_JSON_NONE;
1460     }
1461
1462   vam->retval = retval;
1463   vam->result_ready = 1;
1464 }
1465
1466 static void
1467   vl_api_bridge_domain_set_mac_age_reply_t_handler
1468   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1469 {
1470   vat_main_t *vam = &vat_main;
1471   i32 retval = ntohl (mp->retval);
1472   if (vam->async_mode)
1473     {
1474       vam->async_errors += (retval < 0);
1475     }
1476   else
1477     {
1478       vam->retval = retval;
1479       vam->result_ready = 1;
1480     }
1481 }
1482
1483 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1484   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1485 {
1486   vat_main_t *vam = &vat_main;
1487   vat_json_node_t node;
1488
1489   vat_json_init_object (&node);
1490   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1491
1492   vat_json_print (vam->ofp, &node);
1493   vat_json_free (&node);
1494
1495   vam->retval = ntohl (mp->retval);
1496   vam->result_ready = 1;
1497 }
1498
1499 static void
1500 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1501 {
1502   vat_main_t *vam = &vat_main;
1503   i32 retval = ntohl (mp->retval);
1504   if (vam->async_mode)
1505     {
1506       vam->async_errors += (retval < 0);
1507     }
1508   else
1509     {
1510       vam->retval = retval;
1511       vam->result_ready = 1;
1512     }
1513 }
1514
1515 static void vl_api_l2_flags_reply_t_handler_json
1516   (vl_api_l2_flags_reply_t * mp)
1517 {
1518   vat_main_t *vam = &vat_main;
1519   vat_json_node_t node;
1520
1521   vat_json_init_object (&node);
1522   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1523   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1524                             ntohl (mp->resulting_feature_bitmap));
1525
1526   vat_json_print (vam->ofp, &node);
1527   vat_json_free (&node);
1528
1529   vam->retval = ntohl (mp->retval);
1530   vam->result_ready = 1;
1531 }
1532
1533 static void vl_api_bridge_flags_reply_t_handler
1534   (vl_api_bridge_flags_reply_t * mp)
1535 {
1536   vat_main_t *vam = &vat_main;
1537   i32 retval = ntohl (mp->retval);
1538   if (vam->async_mode)
1539     {
1540       vam->async_errors += (retval < 0);
1541     }
1542   else
1543     {
1544       vam->retval = retval;
1545       vam->result_ready = 1;
1546     }
1547 }
1548
1549 static void vl_api_bridge_flags_reply_t_handler_json
1550   (vl_api_bridge_flags_reply_t * mp)
1551 {
1552   vat_main_t *vam = &vat_main;
1553   vat_json_node_t node;
1554
1555   vat_json_init_object (&node);
1556   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1557   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1558                             ntohl (mp->resulting_feature_bitmap));
1559
1560   vat_json_print (vam->ofp, &node);
1561   vat_json_free (&node);
1562
1563   vam->retval = ntohl (mp->retval);
1564   vam->result_ready = 1;
1565 }
1566
1567 static void vl_api_tap_connect_reply_t_handler
1568   (vl_api_tap_connect_reply_t * mp)
1569 {
1570   vat_main_t *vam = &vat_main;
1571   i32 retval = ntohl (mp->retval);
1572   if (vam->async_mode)
1573     {
1574       vam->async_errors += (retval < 0);
1575     }
1576   else
1577     {
1578       vam->retval = retval;
1579       vam->sw_if_index = ntohl (mp->sw_if_index);
1580       vam->result_ready = 1;
1581     }
1582
1583 }
1584
1585 static void vl_api_tap_connect_reply_t_handler_json
1586   (vl_api_tap_connect_reply_t * mp)
1587 {
1588   vat_main_t *vam = &vat_main;
1589   vat_json_node_t node;
1590
1591   vat_json_init_object (&node);
1592   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1593   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1594
1595   vat_json_print (vam->ofp, &node);
1596   vat_json_free (&node);
1597
1598   vam->retval = ntohl (mp->retval);
1599   vam->result_ready = 1;
1600
1601 }
1602
1603 static void
1604 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1605 {
1606   vat_main_t *vam = &vat_main;
1607   i32 retval = ntohl (mp->retval);
1608   if (vam->async_mode)
1609     {
1610       vam->async_errors += (retval < 0);
1611     }
1612   else
1613     {
1614       vam->retval = retval;
1615       vam->sw_if_index = ntohl (mp->sw_if_index);
1616       vam->result_ready = 1;
1617     }
1618 }
1619
1620 static void vl_api_tap_modify_reply_t_handler_json
1621   (vl_api_tap_modify_reply_t * mp)
1622 {
1623   vat_main_t *vam = &vat_main;
1624   vat_json_node_t node;
1625
1626   vat_json_init_object (&node);
1627   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1628   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1629
1630   vat_json_print (vam->ofp, &node);
1631   vat_json_free (&node);
1632
1633   vam->retval = ntohl (mp->retval);
1634   vam->result_ready = 1;
1635 }
1636
1637 static void
1638 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1639 {
1640   vat_main_t *vam = &vat_main;
1641   i32 retval = ntohl (mp->retval);
1642   if (vam->async_mode)
1643     {
1644       vam->async_errors += (retval < 0);
1645     }
1646   else
1647     {
1648       vam->retval = retval;
1649       vam->result_ready = 1;
1650     }
1651 }
1652
1653 static void vl_api_tap_delete_reply_t_handler_json
1654   (vl_api_tap_delete_reply_t * mp)
1655 {
1656   vat_main_t *vam = &vat_main;
1657   vat_json_node_t node;
1658
1659   vat_json_init_object (&node);
1660   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1661
1662   vat_json_print (vam->ofp, &node);
1663   vat_json_free (&node);
1664
1665   vam->retval = ntohl (mp->retval);
1666   vam->result_ready = 1;
1667 }
1668
1669 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1670   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1671 {
1672   vat_main_t *vam = &vat_main;
1673   i32 retval = ntohl (mp->retval);
1674   if (vam->async_mode)
1675     {
1676       vam->async_errors += (retval < 0);
1677     }
1678   else
1679     {
1680       vam->retval = retval;
1681       vam->result_ready = 1;
1682     }
1683 }
1684
1685 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1686   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1687 {
1688   vat_main_t *vam = &vat_main;
1689   vat_json_node_t node;
1690
1691   vat_json_init_object (&node);
1692   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1693   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1694                             ntohl (mp->sw_if_index));
1695
1696   vat_json_print (vam->ofp, &node);
1697   vat_json_free (&node);
1698
1699   vam->retval = ntohl (mp->retval);
1700   vam->result_ready = 1;
1701 }
1702
1703 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1704   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1705 {
1706   vat_main_t *vam = &vat_main;
1707   i32 retval = ntohl (mp->retval);
1708   if (vam->async_mode)
1709     {
1710       vam->async_errors += (retval < 0);
1711     }
1712   else
1713     {
1714       vam->retval = retval;
1715       vam->sw_if_index = ntohl (mp->sw_if_index);
1716       vam->result_ready = 1;
1717     }
1718 }
1719
1720 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1721   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1722 {
1723   vat_main_t *vam = &vat_main;
1724   vat_json_node_t node;
1725
1726   vat_json_init_object (&node);
1727   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1728   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1729
1730   vat_json_print (vam->ofp, &node);
1731   vat_json_free (&node);
1732
1733   vam->retval = ntohl (mp->retval);
1734   vam->result_ready = 1;
1735 }
1736
1737
1738 static void vl_api_one_add_del_locator_set_reply_t_handler
1739   (vl_api_one_add_del_locator_set_reply_t * mp)
1740 {
1741   vat_main_t *vam = &vat_main;
1742   i32 retval = ntohl (mp->retval);
1743   if (vam->async_mode)
1744     {
1745       vam->async_errors += (retval < 0);
1746     }
1747   else
1748     {
1749       vam->retval = retval;
1750       vam->result_ready = 1;
1751     }
1752 }
1753
1754 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1755   (vl_api_one_add_del_locator_set_reply_t * mp)
1756 {
1757   vat_main_t *vam = &vat_main;
1758   vat_json_node_t node;
1759
1760   vat_json_init_object (&node);
1761   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1762   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1763
1764   vat_json_print (vam->ofp, &node);
1765   vat_json_free (&node);
1766
1767   vam->retval = ntohl (mp->retval);
1768   vam->result_ready = 1;
1769 }
1770
1771 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1772   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1773 {
1774   vat_main_t *vam = &vat_main;
1775   i32 retval = ntohl (mp->retval);
1776   if (vam->async_mode)
1777     {
1778       vam->async_errors += (retval < 0);
1779     }
1780   else
1781     {
1782       vam->retval = retval;
1783       vam->sw_if_index = ntohl (mp->sw_if_index);
1784       vam->result_ready = 1;
1785     }
1786 }
1787
1788 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1789   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1790 {
1791   vat_main_t *vam = &vat_main;
1792   vat_json_node_t node;
1793
1794   vat_json_init_object (&node);
1795   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1796   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1797
1798   vat_json_print (vam->ofp, &node);
1799   vat_json_free (&node);
1800
1801   vam->retval = ntohl (mp->retval);
1802   vam->result_ready = 1;
1803 }
1804
1805 static void vl_api_gre_add_del_tunnel_reply_t_handler
1806   (vl_api_gre_add_del_tunnel_reply_t * mp)
1807 {
1808   vat_main_t *vam = &vat_main;
1809   i32 retval = ntohl (mp->retval);
1810   if (vam->async_mode)
1811     {
1812       vam->async_errors += (retval < 0);
1813     }
1814   else
1815     {
1816       vam->retval = retval;
1817       vam->sw_if_index = ntohl (mp->sw_if_index);
1818       vam->result_ready = 1;
1819     }
1820 }
1821
1822 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1823   (vl_api_gre_add_del_tunnel_reply_t * mp)
1824 {
1825   vat_main_t *vam = &vat_main;
1826   vat_json_node_t node;
1827
1828   vat_json_init_object (&node);
1829   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1830   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1831
1832   vat_json_print (vam->ofp, &node);
1833   vat_json_free (&node);
1834
1835   vam->retval = ntohl (mp->retval);
1836   vam->result_ready = 1;
1837 }
1838
1839 static void vl_api_create_vhost_user_if_reply_t_handler
1840   (vl_api_create_vhost_user_if_reply_t * mp)
1841 {
1842   vat_main_t *vam = &vat_main;
1843   i32 retval = ntohl (mp->retval);
1844   if (vam->async_mode)
1845     {
1846       vam->async_errors += (retval < 0);
1847     }
1848   else
1849     {
1850       vam->retval = retval;
1851       vam->sw_if_index = ntohl (mp->sw_if_index);
1852       vam->result_ready = 1;
1853     }
1854 }
1855
1856 static void vl_api_create_vhost_user_if_reply_t_handler_json
1857   (vl_api_create_vhost_user_if_reply_t * mp)
1858 {
1859   vat_main_t *vam = &vat_main;
1860   vat_json_node_t node;
1861
1862   vat_json_init_object (&node);
1863   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1864   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1865
1866   vat_json_print (vam->ofp, &node);
1867   vat_json_free (&node);
1868
1869   vam->retval = ntohl (mp->retval);
1870   vam->result_ready = 1;
1871 }
1872
1873 static void vl_api_ip_address_details_t_handler
1874   (vl_api_ip_address_details_t * mp)
1875 {
1876   vat_main_t *vam = &vat_main;
1877   static ip_address_details_t empty_ip_address_details = { {0} };
1878   ip_address_details_t *address = NULL;
1879   ip_details_t *current_ip_details = NULL;
1880   ip_details_t *details = NULL;
1881
1882   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1883
1884   if (!details || vam->current_sw_if_index >= vec_len (details)
1885       || !details[vam->current_sw_if_index].present)
1886     {
1887       errmsg ("ip address details arrived but not stored");
1888       errmsg ("ip_dump should be called first");
1889       return;
1890     }
1891
1892   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1893
1894 #define addresses (current_ip_details->addr)
1895
1896   vec_validate_init_empty (addresses, vec_len (addresses),
1897                            empty_ip_address_details);
1898
1899   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1900
1901   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1902   address->prefix_length = mp->prefix_length;
1903 #undef addresses
1904 }
1905
1906 static void vl_api_ip_address_details_t_handler_json
1907   (vl_api_ip_address_details_t * mp)
1908 {
1909   vat_main_t *vam = &vat_main;
1910   vat_json_node_t *node = NULL;
1911   struct in6_addr ip6;
1912   struct in_addr ip4;
1913
1914   if (VAT_JSON_ARRAY != vam->json_tree.type)
1915     {
1916       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1917       vat_json_init_array (&vam->json_tree);
1918     }
1919   node = vat_json_array_add (&vam->json_tree);
1920
1921   vat_json_init_object (node);
1922   if (vam->is_ipv6)
1923     {
1924       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1925       vat_json_object_add_ip6 (node, "ip", ip6);
1926     }
1927   else
1928     {
1929       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1930       vat_json_object_add_ip4 (node, "ip", ip4);
1931     }
1932   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1933 }
1934
1935 static void
1936 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1937 {
1938   vat_main_t *vam = &vat_main;
1939   static ip_details_t empty_ip_details = { 0 };
1940   ip_details_t *ip = NULL;
1941   u32 sw_if_index = ~0;
1942
1943   sw_if_index = ntohl (mp->sw_if_index);
1944
1945   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1946                            sw_if_index, empty_ip_details);
1947
1948   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1949                          sw_if_index);
1950
1951   ip->present = 1;
1952 }
1953
1954 static void
1955 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1956 {
1957   vat_main_t *vam = &vat_main;
1958
1959   if (VAT_JSON_ARRAY != vam->json_tree.type)
1960     {
1961       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1962       vat_json_init_array (&vam->json_tree);
1963     }
1964   vat_json_array_add_uint (&vam->json_tree,
1965                            clib_net_to_host_u32 (mp->sw_if_index));
1966 }
1967
1968 static void vl_api_map_domain_details_t_handler_json
1969   (vl_api_map_domain_details_t * mp)
1970 {
1971   vat_json_node_t *node = NULL;
1972   vat_main_t *vam = &vat_main;
1973   struct in6_addr ip6;
1974   struct in_addr ip4;
1975
1976   if (VAT_JSON_ARRAY != vam->json_tree.type)
1977     {
1978       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1979       vat_json_init_array (&vam->json_tree);
1980     }
1981
1982   node = vat_json_array_add (&vam->json_tree);
1983   vat_json_init_object (node);
1984
1985   vat_json_object_add_uint (node, "domain_index",
1986                             clib_net_to_host_u32 (mp->domain_index));
1987   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1988   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1989   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1990   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1991   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1992   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1993   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1994   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1995   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1996   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1997   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1998   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1999   vat_json_object_add_uint (node, "flags", mp->flags);
2000   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
2001   vat_json_object_add_int (node, "is_translation", mp->is_translation);
2002 }
2003
2004 static void vl_api_map_domain_details_t_handler
2005   (vl_api_map_domain_details_t * mp)
2006 {
2007   vat_main_t *vam = &vat_main;
2008
2009   if (mp->is_translation)
2010     {
2011       print (vam->ofp,
2012              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2013              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2014              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2015              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2016              clib_net_to_host_u32 (mp->domain_index));
2017     }
2018   else
2019     {
2020       print (vam->ofp,
2021              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2022              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2023              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2024              format_ip6_address, mp->ip6_src,
2025              clib_net_to_host_u32 (mp->domain_index));
2026     }
2027   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2028          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2029          mp->is_translation ? "map-t" : "");
2030 }
2031
2032 static void vl_api_map_rule_details_t_handler_json
2033   (vl_api_map_rule_details_t * mp)
2034 {
2035   struct in6_addr ip6;
2036   vat_json_node_t *node = NULL;
2037   vat_main_t *vam = &vat_main;
2038
2039   if (VAT_JSON_ARRAY != vam->json_tree.type)
2040     {
2041       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2042       vat_json_init_array (&vam->json_tree);
2043     }
2044
2045   node = vat_json_array_add (&vam->json_tree);
2046   vat_json_init_object (node);
2047
2048   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2049   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2050   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2051 }
2052
2053 static void
2054 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2055 {
2056   vat_main_t *vam = &vat_main;
2057   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2058          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2059 }
2060
2061 static void
2062 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2063 {
2064   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2065           "router_addr %U host_mac %U",
2066           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2067           format_ip4_address, &mp->host_address,
2068           format_ip4_address, &mp->router_address,
2069           format_ethernet_address, mp->host_mac);
2070 }
2071
2072 static void vl_api_dhcp_compl_event_t_handler_json
2073   (vl_api_dhcp_compl_event_t * mp)
2074 {
2075   /* JSON output not supported */
2076 }
2077
2078 static void
2079 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2080                               u32 counter)
2081 {
2082   vat_main_t *vam = &vat_main;
2083   static u64 default_counter = 0;
2084
2085   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2086                            NULL);
2087   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2088                            sw_if_index, default_counter);
2089   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2090 }
2091
2092 static void
2093 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2094                                 interface_counter_t counter)
2095 {
2096   vat_main_t *vam = &vat_main;
2097   static interface_counter_t default_counter = { 0, };
2098
2099   vec_validate_init_empty (vam->combined_interface_counters,
2100                            vnet_counter_type, NULL);
2101   vec_validate_init_empty (vam->combined_interface_counters
2102                            [vnet_counter_type], sw_if_index, default_counter);
2103   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2104 }
2105
2106 static void vl_api_vnet_interface_simple_counters_t_handler
2107   (vl_api_vnet_interface_simple_counters_t * mp)
2108 {
2109   /* not supported */
2110 }
2111
2112 static void vl_api_vnet_interface_combined_counters_t_handler
2113   (vl_api_vnet_interface_combined_counters_t * mp)
2114 {
2115   /* not supported */
2116 }
2117
2118 static void vl_api_vnet_interface_simple_counters_t_handler_json
2119   (vl_api_vnet_interface_simple_counters_t * mp)
2120 {
2121   u64 *v_packets;
2122   u64 packets;
2123   u32 count;
2124   u32 first_sw_if_index;
2125   int i;
2126
2127   count = ntohl (mp->count);
2128   first_sw_if_index = ntohl (mp->first_sw_if_index);
2129
2130   v_packets = (u64 *) & mp->data;
2131   for (i = 0; i < count; i++)
2132     {
2133       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2134       set_simple_interface_counter (mp->vnet_counter_type,
2135                                     first_sw_if_index + i, packets);
2136       v_packets++;
2137     }
2138 }
2139
2140 static void vl_api_vnet_interface_combined_counters_t_handler_json
2141   (vl_api_vnet_interface_combined_counters_t * mp)
2142 {
2143   interface_counter_t counter;
2144   vlib_counter_t *v;
2145   u32 first_sw_if_index;
2146   int i;
2147   u32 count;
2148
2149   count = ntohl (mp->count);
2150   first_sw_if_index = ntohl (mp->first_sw_if_index);
2151
2152   v = (vlib_counter_t *) & mp->data;
2153   for (i = 0; i < count; i++)
2154     {
2155       counter.packets =
2156         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2157       counter.bytes =
2158         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2159       set_combined_interface_counter (mp->vnet_counter_type,
2160                                       first_sw_if_index + i, counter);
2161       v++;
2162     }
2163 }
2164
2165 static u32
2166 ip4_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->ip4_fib_counters_vrf_id_by_index); i++)
2172     {
2173       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2174         {
2175           return i;
2176         }
2177     }
2178   return ~0;
2179 }
2180
2181 static u32
2182 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2183 {
2184   vat_main_t *vam = &vat_main;
2185   u32 i;
2186
2187   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2188     {
2189       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2190         {
2191           return i;
2192         }
2193     }
2194   return ~0;
2195 }
2196
2197 static void vl_api_vnet_ip4_fib_counters_t_handler
2198   (vl_api_vnet_ip4_fib_counters_t * mp)
2199 {
2200   /* not supported */
2201 }
2202
2203 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2204   (vl_api_vnet_ip4_fib_counters_t * mp)
2205 {
2206   vat_main_t *vam = &vat_main;
2207   vl_api_ip4_fib_counter_t *v;
2208   ip4_fib_counter_t *counter;
2209   struct in_addr ip4;
2210   u32 vrf_id;
2211   u32 vrf_index;
2212   u32 count;
2213   int i;
2214
2215   vrf_id = ntohl (mp->vrf_id);
2216   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2217   if (~0 == vrf_index)
2218     {
2219       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2220       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2221       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2222       vec_validate (vam->ip4_fib_counters, vrf_index);
2223       vam->ip4_fib_counters[vrf_index] = NULL;
2224     }
2225
2226   vec_free (vam->ip4_fib_counters[vrf_index]);
2227   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2228   count = ntohl (mp->count);
2229   for (i = 0; i < count; i++)
2230     {
2231       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2232       counter = &vam->ip4_fib_counters[vrf_index][i];
2233       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2234       counter->address = ip4;
2235       counter->address_length = v->address_length;
2236       counter->packets = clib_net_to_host_u64 (v->packets);
2237       counter->bytes = clib_net_to_host_u64 (v->bytes);
2238       v++;
2239     }
2240 }
2241
2242 static void vl_api_vnet_ip4_nbr_counters_t_handler
2243   (vl_api_vnet_ip4_nbr_counters_t * mp)
2244 {
2245   /* not supported */
2246 }
2247
2248 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2249   (vl_api_vnet_ip4_nbr_counters_t * mp)
2250 {
2251   vat_main_t *vam = &vat_main;
2252   vl_api_ip4_nbr_counter_t *v;
2253   ip4_nbr_counter_t *counter;
2254   u32 sw_if_index;
2255   u32 count;
2256   int i;
2257
2258   sw_if_index = ntohl (mp->sw_if_index);
2259   count = ntohl (mp->count);
2260   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2261
2262   if (mp->begin)
2263     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2264
2265   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2266   for (i = 0; i < count; i++)
2267     {
2268       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2269       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2270       counter->address.s_addr = v->address;
2271       counter->packets = clib_net_to_host_u64 (v->packets);
2272       counter->bytes = clib_net_to_host_u64 (v->bytes);
2273       counter->linkt = v->link_type;
2274       v++;
2275     }
2276 }
2277
2278 static void vl_api_vnet_ip6_fib_counters_t_handler
2279   (vl_api_vnet_ip6_fib_counters_t * mp)
2280 {
2281   /* not supported */
2282 }
2283
2284 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2285   (vl_api_vnet_ip6_fib_counters_t * mp)
2286 {
2287   vat_main_t *vam = &vat_main;
2288   vl_api_ip6_fib_counter_t *v;
2289   ip6_fib_counter_t *counter;
2290   struct in6_addr ip6;
2291   u32 vrf_id;
2292   u32 vrf_index;
2293   u32 count;
2294   int i;
2295
2296   vrf_id = ntohl (mp->vrf_id);
2297   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2298   if (~0 == vrf_index)
2299     {
2300       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2301       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2302       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2303       vec_validate (vam->ip6_fib_counters, vrf_index);
2304       vam->ip6_fib_counters[vrf_index] = NULL;
2305     }
2306
2307   vec_free (vam->ip6_fib_counters[vrf_index]);
2308   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2309   count = ntohl (mp->count);
2310   for (i = 0; i < count; i++)
2311     {
2312       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2313       counter = &vam->ip6_fib_counters[vrf_index][i];
2314       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2315       counter->address = ip6;
2316       counter->address_length = v->address_length;
2317       counter->packets = clib_net_to_host_u64 (v->packets);
2318       counter->bytes = clib_net_to_host_u64 (v->bytes);
2319       v++;
2320     }
2321 }
2322
2323 static void vl_api_vnet_ip6_nbr_counters_t_handler
2324   (vl_api_vnet_ip6_nbr_counters_t * mp)
2325 {
2326   /* not supported */
2327 }
2328
2329 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2330   (vl_api_vnet_ip6_nbr_counters_t * mp)
2331 {
2332   vat_main_t *vam = &vat_main;
2333   vl_api_ip6_nbr_counter_t *v;
2334   ip6_nbr_counter_t *counter;
2335   struct in6_addr ip6;
2336   u32 sw_if_index;
2337   u32 count;
2338   int i;
2339
2340   sw_if_index = ntohl (mp->sw_if_index);
2341   count = ntohl (mp->count);
2342   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2343
2344   if (mp->begin)
2345     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2346
2347   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2348   for (i = 0; i < count; i++)
2349     {
2350       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2351       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2352       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2353       counter->address = ip6;
2354       counter->packets = clib_net_to_host_u64 (v->packets);
2355       counter->bytes = clib_net_to_host_u64 (v->bytes);
2356       v++;
2357     }
2358 }
2359
2360 static void vl_api_get_first_msg_id_reply_t_handler
2361   (vl_api_get_first_msg_id_reply_t * mp)
2362 {
2363   vat_main_t *vam = &vat_main;
2364   i32 retval = ntohl (mp->retval);
2365
2366   if (vam->async_mode)
2367     {
2368       vam->async_errors += (retval < 0);
2369     }
2370   else
2371     {
2372       vam->retval = retval;
2373       vam->result_ready = 1;
2374     }
2375   if (retval >= 0)
2376     {
2377       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2378     }
2379 }
2380
2381 static void vl_api_get_first_msg_id_reply_t_handler_json
2382   (vl_api_get_first_msg_id_reply_t * mp)
2383 {
2384   vat_main_t *vam = &vat_main;
2385   vat_json_node_t node;
2386
2387   vat_json_init_object (&node);
2388   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2389   vat_json_object_add_uint (&node, "first_msg_id",
2390                             (uint) ntohs (mp->first_msg_id));
2391
2392   vat_json_print (vam->ofp, &node);
2393   vat_json_free (&node);
2394
2395   vam->retval = ntohl (mp->retval);
2396   vam->result_ready = 1;
2397 }
2398
2399 static void vl_api_get_node_graph_reply_t_handler
2400   (vl_api_get_node_graph_reply_t * mp)
2401 {
2402   vat_main_t *vam = &vat_main;
2403   api_main_t *am = &api_main;
2404   i32 retval = ntohl (mp->retval);
2405   u8 *pvt_copy, *reply;
2406   void *oldheap;
2407   vlib_node_t *node;
2408   int i;
2409
2410   if (vam->async_mode)
2411     {
2412       vam->async_errors += (retval < 0);
2413     }
2414   else
2415     {
2416       vam->retval = retval;
2417       vam->result_ready = 1;
2418     }
2419
2420   /* "Should never happen..." */
2421   if (retval != 0)
2422     return;
2423
2424   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2425   pvt_copy = vec_dup (reply);
2426
2427   /* Toss the shared-memory original... */
2428   pthread_mutex_lock (&am->vlib_rp->mutex);
2429   oldheap = svm_push_data_heap (am->vlib_rp);
2430
2431   vec_free (reply);
2432
2433   svm_pop_heap (oldheap);
2434   pthread_mutex_unlock (&am->vlib_rp->mutex);
2435
2436   if (vam->graph_nodes)
2437     {
2438       hash_free (vam->graph_node_index_by_name);
2439
2440       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2441         {
2442           node = vam->graph_nodes[i];
2443           vec_free (node->name);
2444           vec_free (node->next_nodes);
2445           vec_free (node);
2446         }
2447       vec_free (vam->graph_nodes);
2448     }
2449
2450   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2451   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2452   vec_free (pvt_copy);
2453
2454   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2455     {
2456       node = vam->graph_nodes[i];
2457       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2458     }
2459 }
2460
2461 static void vl_api_get_node_graph_reply_t_handler_json
2462   (vl_api_get_node_graph_reply_t * mp)
2463 {
2464   vat_main_t *vam = &vat_main;
2465   api_main_t *am = &api_main;
2466   void *oldheap;
2467   vat_json_node_t node;
2468   u8 *reply;
2469
2470   /* $$$$ make this real? */
2471   vat_json_init_object (&node);
2472   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2473   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2474
2475   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2476
2477   /* Toss the shared-memory original... */
2478   pthread_mutex_lock (&am->vlib_rp->mutex);
2479   oldheap = svm_push_data_heap (am->vlib_rp);
2480
2481   vec_free (reply);
2482
2483   svm_pop_heap (oldheap);
2484   pthread_mutex_unlock (&am->vlib_rp->mutex);
2485
2486   vat_json_print (vam->ofp, &node);
2487   vat_json_free (&node);
2488
2489   vam->retval = ntohl (mp->retval);
2490   vam->result_ready = 1;
2491 }
2492
2493 static void
2494 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2495 {
2496   vat_main_t *vam = &vat_main;
2497   u8 *s = 0;
2498
2499   if (mp->local)
2500     {
2501       s = format (s, "%=16d%=16d%=16d",
2502                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2503     }
2504   else
2505     {
2506       s = format (s, "%=16U%=16d%=16d",
2507                   mp->is_ipv6 ? format_ip6_address :
2508                   format_ip4_address,
2509                   mp->ip_address, mp->priority, mp->weight);
2510     }
2511
2512   print (vam->ofp, "%v", s);
2513   vec_free (s);
2514 }
2515
2516 static void
2517 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2518 {
2519   vat_main_t *vam = &vat_main;
2520   vat_json_node_t *node = NULL;
2521   struct in6_addr ip6;
2522   struct in_addr ip4;
2523
2524   if (VAT_JSON_ARRAY != vam->json_tree.type)
2525     {
2526       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2527       vat_json_init_array (&vam->json_tree);
2528     }
2529   node = vat_json_array_add (&vam->json_tree);
2530   vat_json_init_object (node);
2531
2532   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2533   vat_json_object_add_uint (node, "priority", mp->priority);
2534   vat_json_object_add_uint (node, "weight", mp->weight);
2535
2536   if (mp->local)
2537     vat_json_object_add_uint (node, "sw_if_index",
2538                               clib_net_to_host_u32 (mp->sw_if_index));
2539   else
2540     {
2541       if (mp->is_ipv6)
2542         {
2543           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2544           vat_json_object_add_ip6 (node, "address", ip6);
2545         }
2546       else
2547         {
2548           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2549           vat_json_object_add_ip4 (node, "address", ip4);
2550         }
2551     }
2552 }
2553
2554 static void
2555 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2556                                           mp)
2557 {
2558   vat_main_t *vam = &vat_main;
2559   u8 *ls_name = 0;
2560
2561   ls_name = format (0, "%s", mp->ls_name);
2562
2563   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2564          ls_name);
2565   vec_free (ls_name);
2566 }
2567
2568 static void
2569   vl_api_one_locator_set_details_t_handler_json
2570   (vl_api_one_locator_set_details_t * mp)
2571 {
2572   vat_main_t *vam = &vat_main;
2573   vat_json_node_t *node = 0;
2574   u8 *ls_name = 0;
2575
2576   ls_name = format (0, "%s", mp->ls_name);
2577   vec_add1 (ls_name, 0);
2578
2579   if (VAT_JSON_ARRAY != vam->json_tree.type)
2580     {
2581       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2582       vat_json_init_array (&vam->json_tree);
2583     }
2584   node = vat_json_array_add (&vam->json_tree);
2585
2586   vat_json_init_object (node);
2587   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2588   vat_json_object_add_uint (node, "ls_index",
2589                             clib_net_to_host_u32 (mp->ls_index));
2590   vec_free (ls_name);
2591 }
2592
2593 static u8 *
2594 format_lisp_flat_eid (u8 * s, va_list * args)
2595 {
2596   u32 type = va_arg (*args, u32);
2597   u8 *eid = va_arg (*args, u8 *);
2598   u32 eid_len = va_arg (*args, u32);
2599
2600   switch (type)
2601     {
2602     case 0:
2603       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2604     case 1:
2605       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2606     case 2:
2607       return format (s, "%U", format_ethernet_address, eid);
2608     }
2609   return 0;
2610 }
2611
2612 static u8 *
2613 format_lisp_eid_vat (u8 * s, va_list * args)
2614 {
2615   u32 type = va_arg (*args, u32);
2616   u8 *eid = va_arg (*args, u8 *);
2617   u32 eid_len = va_arg (*args, u32);
2618   u8 *seid = va_arg (*args, u8 *);
2619   u32 seid_len = va_arg (*args, u32);
2620   u32 is_src_dst = va_arg (*args, u32);
2621
2622   if (is_src_dst)
2623     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2624
2625   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2626
2627   return s;
2628 }
2629
2630 static void
2631 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2632 {
2633   vat_main_t *vam = &vat_main;
2634   u8 *s = 0, *eid = 0;
2635
2636   if (~0 == mp->locator_set_index)
2637     s = format (0, "action: %d", mp->action);
2638   else
2639     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2640
2641   eid = format (0, "%U", format_lisp_eid_vat,
2642                 mp->eid_type,
2643                 mp->eid,
2644                 mp->eid_prefix_len,
2645                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2646   vec_add1 (eid, 0);
2647
2648   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2649          clib_net_to_host_u32 (mp->vni),
2650          eid,
2651          mp->is_local ? "local" : "remote",
2652          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2653          clib_net_to_host_u16 (mp->key_id), mp->key);
2654
2655   vec_free (s);
2656   vec_free (eid);
2657 }
2658
2659 static void
2660 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2661                                              * mp)
2662 {
2663   vat_main_t *vam = &vat_main;
2664   vat_json_node_t *node = 0;
2665   u8 *eid = 0;
2666
2667   if (VAT_JSON_ARRAY != vam->json_tree.type)
2668     {
2669       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2670       vat_json_init_array (&vam->json_tree);
2671     }
2672   node = vat_json_array_add (&vam->json_tree);
2673
2674   vat_json_init_object (node);
2675   if (~0 == mp->locator_set_index)
2676     vat_json_object_add_uint (node, "action", mp->action);
2677   else
2678     vat_json_object_add_uint (node, "locator_set_index",
2679                               clib_net_to_host_u32 (mp->locator_set_index));
2680
2681   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2682   eid = format (0, "%U", format_lisp_eid_vat,
2683                 mp->eid_type,
2684                 mp->eid,
2685                 mp->eid_prefix_len,
2686                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2687   vec_add1 (eid, 0);
2688   vat_json_object_add_string_copy (node, "eid", eid);
2689   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2690   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2691   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2692
2693   if (mp->key_id)
2694     {
2695       vat_json_object_add_uint (node, "key_id",
2696                                 clib_net_to_host_u16 (mp->key_id));
2697       vat_json_object_add_string_copy (node, "key", mp->key);
2698     }
2699   vec_free (eid);
2700 }
2701
2702 static void
2703 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
2704 {
2705   vat_main_t *vam = &vat_main;
2706   u8 *seid = 0, *deid = 0;
2707   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2708
2709   deid = format (0, "%U", format_lisp_eid_vat,
2710                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2711
2712   seid = format (0, "%U", format_lisp_eid_vat,
2713                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2714
2715   vec_add1 (deid, 0);
2716   vec_add1 (seid, 0);
2717
2718   if (mp->is_ip4)
2719     format_ip_address_fcn = format_ip4_address;
2720   else
2721     format_ip_address_fcn = format_ip6_address;
2722
2723
2724   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
2725          clib_net_to_host_u32 (mp->vni),
2726          seid, deid,
2727          format_ip_address_fcn, mp->lloc,
2728          format_ip_address_fcn, mp->rloc,
2729          clib_net_to_host_u32 (mp->pkt_count),
2730          clib_net_to_host_u32 (mp->bytes));
2731
2732   vec_free (deid);
2733   vec_free (seid);
2734 }
2735
2736 static void
2737 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
2738 {
2739   struct in6_addr ip6;
2740   struct in_addr ip4;
2741   vat_main_t *vam = &vat_main;
2742   vat_json_node_t *node = 0;
2743   u8 *deid = 0, *seid = 0;
2744
2745   if (VAT_JSON_ARRAY != vam->json_tree.type)
2746     {
2747       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2748       vat_json_init_array (&vam->json_tree);
2749     }
2750   node = vat_json_array_add (&vam->json_tree);
2751
2752   vat_json_init_object (node);
2753   deid = format (0, "%U", format_lisp_eid_vat,
2754                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2755
2756   seid = format (0, "%U", format_lisp_eid_vat,
2757                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2758
2759   vec_add1 (deid, 0);
2760   vec_add1 (seid, 0);
2761
2762   vat_json_object_add_string_copy (node, "seid", seid);
2763   vat_json_object_add_string_copy (node, "deid", deid);
2764   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2765
2766   if (mp->is_ip4)
2767     {
2768       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
2769       vat_json_object_add_ip4 (node, "lloc", ip4);
2770       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
2771       vat_json_object_add_ip4 (node, "rloc", ip4);
2772     }
2773   else
2774     {
2775       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
2776       vat_json_object_add_ip6 (node, "lloc", ip6);
2777       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
2778       vat_json_object_add_ip6 (node, "rloc", ip6);
2779     }
2780   vat_json_object_add_uint (node, "pkt_count",
2781                             clib_net_to_host_u32 (mp->pkt_count));
2782   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
2783
2784   vec_free (deid);
2785   vec_free (seid);
2786 }
2787
2788 static void
2789   vl_api_one_eid_table_map_details_t_handler
2790   (vl_api_one_eid_table_map_details_t * mp)
2791 {
2792   vat_main_t *vam = &vat_main;
2793
2794   u8 *line = format (0, "%=10d%=10d",
2795                      clib_net_to_host_u32 (mp->vni),
2796                      clib_net_to_host_u32 (mp->dp_table));
2797   print (vam->ofp, "%v", line);
2798   vec_free (line);
2799 }
2800
2801 static void
2802   vl_api_one_eid_table_map_details_t_handler_json
2803   (vl_api_one_eid_table_map_details_t * mp)
2804 {
2805   vat_main_t *vam = &vat_main;
2806   vat_json_node_t *node = NULL;
2807
2808   if (VAT_JSON_ARRAY != vam->json_tree.type)
2809     {
2810       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2811       vat_json_init_array (&vam->json_tree);
2812     }
2813   node = vat_json_array_add (&vam->json_tree);
2814   vat_json_init_object (node);
2815   vat_json_object_add_uint (node, "dp_table",
2816                             clib_net_to_host_u32 (mp->dp_table));
2817   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2818 }
2819
2820 static void
2821   vl_api_one_eid_table_vni_details_t_handler
2822   (vl_api_one_eid_table_vni_details_t * mp)
2823 {
2824   vat_main_t *vam = &vat_main;
2825
2826   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2827   print (vam->ofp, "%v", line);
2828   vec_free (line);
2829 }
2830
2831 static void
2832   vl_api_one_eid_table_vni_details_t_handler_json
2833   (vl_api_one_eid_table_vni_details_t * mp)
2834 {
2835   vat_main_t *vam = &vat_main;
2836   vat_json_node_t *node = NULL;
2837
2838   if (VAT_JSON_ARRAY != vam->json_tree.type)
2839     {
2840       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2841       vat_json_init_array (&vam->json_tree);
2842     }
2843   node = vat_json_array_add (&vam->json_tree);
2844   vat_json_init_object (node);
2845   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2846 }
2847
2848 static void
2849   vl_api_show_one_map_register_state_reply_t_handler
2850   (vl_api_show_one_map_register_state_reply_t * mp)
2851 {
2852   vat_main_t *vam = &vat_main;
2853   int retval = clib_net_to_host_u32 (mp->retval);
2854
2855   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2856
2857   vam->retval = retval;
2858   vam->result_ready = 1;
2859 }
2860
2861 static void
2862   vl_api_show_one_map_register_state_reply_t_handler_json
2863   (vl_api_show_one_map_register_state_reply_t * mp)
2864 {
2865   vat_main_t *vam = &vat_main;
2866   vat_json_node_t _node, *node = &_node;
2867   int retval = clib_net_to_host_u32 (mp->retval);
2868
2869   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2870
2871   vat_json_init_object (node);
2872   vat_json_object_add_string_copy (node, "state", s);
2873
2874   vat_json_print (vam->ofp, node);
2875   vat_json_free (node);
2876
2877   vam->retval = retval;
2878   vam->result_ready = 1;
2879   vec_free (s);
2880 }
2881
2882 static void
2883   vl_api_show_one_rloc_probe_state_reply_t_handler
2884   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2885 {
2886   vat_main_t *vam = &vat_main;
2887   int retval = clib_net_to_host_u32 (mp->retval);
2888
2889   if (retval)
2890     goto end;
2891
2892   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2893 end:
2894   vam->retval = retval;
2895   vam->result_ready = 1;
2896 }
2897
2898 static void
2899   vl_api_show_one_rloc_probe_state_reply_t_handler_json
2900   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2901 {
2902   vat_main_t *vam = &vat_main;
2903   vat_json_node_t _node, *node = &_node;
2904   int retval = clib_net_to_host_u32 (mp->retval);
2905
2906   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2907   vat_json_init_object (node);
2908   vat_json_object_add_string_copy (node, "state", s);
2909
2910   vat_json_print (vam->ofp, node);
2911   vat_json_free (node);
2912
2913   vam->retval = retval;
2914   vam->result_ready = 1;
2915   vec_free (s);
2916 }
2917
2918 static void
2919   vl_api_show_one_stats_enable_disable_reply_t_handler
2920   (vl_api_show_one_stats_enable_disable_reply_t * mp)
2921 {
2922   vat_main_t *vam = &vat_main;
2923   int retval = clib_net_to_host_u32 (mp->retval);
2924
2925   if (retval)
2926     goto end;
2927
2928   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
2929 end:
2930   vam->retval = retval;
2931   vam->result_ready = 1;
2932 }
2933
2934 static void
2935   vl_api_show_one_stats_enable_disable_reply_t_handler_json
2936   (vl_api_show_one_stats_enable_disable_reply_t * mp)
2937 {
2938   vat_main_t *vam = &vat_main;
2939   vat_json_node_t _node, *node = &_node;
2940   int retval = clib_net_to_host_u32 (mp->retval);
2941
2942   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
2943   vat_json_init_object (node);
2944   vat_json_object_add_string_copy (node, "state", s);
2945
2946   vat_json_print (vam->ofp, node);
2947   vat_json_free (node);
2948
2949   vam->retval = retval;
2950   vam->result_ready = 1;
2951   vec_free (s);
2952 }
2953
2954 static void
2955 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
2956 {
2957   e->dp_table = clib_net_to_host_u32 (e->dp_table);
2958   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
2959 }
2960
2961 static void
2962   gpe_fwd_entries_get_reply_t_net_to_host
2963   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2964 {
2965   u32 i;
2966
2967   mp->count = clib_net_to_host_u32 (mp->count);
2968   for (i = 0; i < mp->count; i++)
2969     {
2970       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
2971     }
2972 }
2973
2974 static u8 *
2975 format_gpe_encap_mode (u8 * s, va_list * args)
2976 {
2977   u32 mode = va_arg (*args, u32);
2978
2979   switch (mode)
2980     {
2981     case 0:
2982       return format (s, "lisp");
2983     case 1:
2984       return format (s, "vxlan");
2985     }
2986   return 0;
2987 }
2988
2989 static void
2990   vl_api_gpe_get_encap_mode_reply_t_handler
2991   (vl_api_gpe_get_encap_mode_reply_t * mp)
2992 {
2993   vat_main_t *vam = &vat_main;
2994
2995   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
2996   vam->retval = ntohl (mp->retval);
2997   vam->result_ready = 1;
2998 }
2999
3000 static void
3001   vl_api_gpe_get_encap_mode_reply_t_handler_json
3002   (vl_api_gpe_get_encap_mode_reply_t * mp)
3003 {
3004   vat_main_t *vam = &vat_main;
3005   vat_json_node_t node;
3006
3007   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3008   vec_add1 (encap_mode, 0);
3009
3010   vat_json_init_object (&node);
3011   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3012
3013   vec_free (encap_mode);
3014   vat_json_print (vam->ofp, &node);
3015   vat_json_free (&node);
3016
3017   vam->retval = ntohl (mp->retval);
3018   vam->result_ready = 1;
3019 }
3020
3021 static void
3022   vl_api_gpe_fwd_entry_path_details_t_handler
3023   (vl_api_gpe_fwd_entry_path_details_t * mp)
3024 {
3025   vat_main_t *vam = &vat_main;
3026   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3027
3028   if (mp->lcl_loc.is_ip4)
3029     format_ip_address_fcn = format_ip4_address;
3030   else
3031     format_ip_address_fcn = format_ip6_address;
3032
3033   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3034          format_ip_address_fcn, &mp->lcl_loc,
3035          format_ip_address_fcn, &mp->rmt_loc);
3036 }
3037
3038 static void
3039 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3040 {
3041   struct in6_addr ip6;
3042   struct in_addr ip4;
3043
3044   if (loc->is_ip4)
3045     {
3046       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3047       vat_json_object_add_ip4 (n, "address", ip4);
3048     }
3049   else
3050     {
3051       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3052       vat_json_object_add_ip6 (n, "address", ip6);
3053     }
3054   vat_json_object_add_uint (n, "weight", loc->weight);
3055 }
3056
3057 static void
3058   vl_api_gpe_fwd_entry_path_details_t_handler_json
3059   (vl_api_gpe_fwd_entry_path_details_t * mp)
3060 {
3061   vat_main_t *vam = &vat_main;
3062   vat_json_node_t *node = NULL;
3063   vat_json_node_t *loc_node;
3064
3065   if (VAT_JSON_ARRAY != vam->json_tree.type)
3066     {
3067       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3068       vat_json_init_array (&vam->json_tree);
3069     }
3070   node = vat_json_array_add (&vam->json_tree);
3071   vat_json_init_object (node);
3072
3073   loc_node = vat_json_object_add (node, "local_locator");
3074   vat_json_init_object (loc_node);
3075   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3076
3077   loc_node = vat_json_object_add (node, "remote_locator");
3078   vat_json_init_object (loc_node);
3079   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3080 }
3081
3082 static void
3083   vl_api_gpe_fwd_entries_get_reply_t_handler
3084   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3085 {
3086   vat_main_t *vam = &vat_main;
3087   u32 i;
3088   int retval = clib_net_to_host_u32 (mp->retval);
3089   vl_api_gpe_fwd_entry_t *e;
3090
3091   if (retval)
3092     goto end;
3093
3094   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3095
3096   for (i = 0; i < mp->count; i++)
3097     {
3098       e = &mp->entries[i];
3099       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3100              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3101              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3102     }
3103
3104 end:
3105   vam->retval = retval;
3106   vam->result_ready = 1;
3107 }
3108
3109 static void
3110   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3111   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3112 {
3113   u8 *s = 0;
3114   vat_main_t *vam = &vat_main;
3115   vat_json_node_t *e = 0, root;
3116   u32 i;
3117   int retval = clib_net_to_host_u32 (mp->retval);
3118   vl_api_gpe_fwd_entry_t *fwd;
3119
3120   if (retval)
3121     goto end;
3122
3123   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3124   vat_json_init_array (&root);
3125
3126   for (i = 0; i < mp->count; i++)
3127     {
3128       e = vat_json_array_add (&root);
3129       fwd = &mp->entries[i];
3130
3131       vat_json_init_object (e);
3132       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3133       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3134
3135       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3136                   fwd->leid_prefix_len);
3137       vec_add1 (s, 0);
3138       vat_json_object_add_string_copy (e, "leid", s);
3139       vec_free (s);
3140
3141       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3142                   fwd->reid_prefix_len);
3143       vec_add1 (s, 0);
3144       vat_json_object_add_string_copy (e, "reid", s);
3145       vec_free (s);
3146     }
3147
3148   vat_json_print (vam->ofp, &root);
3149   vat_json_free (&root);
3150
3151 end:
3152   vam->retval = retval;
3153   vam->result_ready = 1;
3154 }
3155
3156 static void
3157   vl_api_one_adjacencies_get_reply_t_handler
3158   (vl_api_one_adjacencies_get_reply_t * mp)
3159 {
3160   vat_main_t *vam = &vat_main;
3161   u32 i, n;
3162   int retval = clib_net_to_host_u32 (mp->retval);
3163   vl_api_one_adjacency_t *a;
3164
3165   if (retval)
3166     goto end;
3167
3168   n = clib_net_to_host_u32 (mp->count);
3169
3170   for (i = 0; i < n; i++)
3171     {
3172       a = &mp->adjacencies[i];
3173       print (vam->ofp, "%U %40U",
3174              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3175              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3176     }
3177
3178 end:
3179   vam->retval = retval;
3180   vam->result_ready = 1;
3181 }
3182
3183 static void
3184   vl_api_one_adjacencies_get_reply_t_handler_json
3185   (vl_api_one_adjacencies_get_reply_t * mp)
3186 {
3187   u8 *s = 0;
3188   vat_main_t *vam = &vat_main;
3189   vat_json_node_t *e = 0, root;
3190   u32 i, n;
3191   int retval = clib_net_to_host_u32 (mp->retval);
3192   vl_api_one_adjacency_t *a;
3193
3194   if (retval)
3195     goto end;
3196
3197   n = clib_net_to_host_u32 (mp->count);
3198   vat_json_init_array (&root);
3199
3200   for (i = 0; i < n; i++)
3201     {
3202       e = vat_json_array_add (&root);
3203       a = &mp->adjacencies[i];
3204
3205       vat_json_init_object (e);
3206       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3207                   a->leid_prefix_len);
3208       vec_add1 (s, 0);
3209       vat_json_object_add_string_copy (e, "leid", s);
3210       vec_free (s);
3211
3212       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3213                   a->reid_prefix_len);
3214       vec_add1 (s, 0);
3215       vat_json_object_add_string_copy (e, "reid", s);
3216       vec_free (s);
3217     }
3218
3219   vat_json_print (vam->ofp, &root);
3220   vat_json_free (&root);
3221
3222 end:
3223   vam->retval = retval;
3224   vam->result_ready = 1;
3225 }
3226
3227 static void
3228 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3229 {
3230   vat_main_t *vam = &vat_main;
3231
3232   print (vam->ofp, "%=20U",
3233          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3234          mp->ip_address);
3235 }
3236
3237 static void
3238   vl_api_one_map_server_details_t_handler_json
3239   (vl_api_one_map_server_details_t * mp)
3240 {
3241   vat_main_t *vam = &vat_main;
3242   vat_json_node_t *node = NULL;
3243   struct in6_addr ip6;
3244   struct in_addr ip4;
3245
3246   if (VAT_JSON_ARRAY != vam->json_tree.type)
3247     {
3248       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3249       vat_json_init_array (&vam->json_tree);
3250     }
3251   node = vat_json_array_add (&vam->json_tree);
3252
3253   vat_json_init_object (node);
3254   if (mp->is_ipv6)
3255     {
3256       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3257       vat_json_object_add_ip6 (node, "map-server", ip6);
3258     }
3259   else
3260     {
3261       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3262       vat_json_object_add_ip4 (node, "map-server", ip4);
3263     }
3264 }
3265
3266 static void
3267 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3268                                            * mp)
3269 {
3270   vat_main_t *vam = &vat_main;
3271
3272   print (vam->ofp, "%=20U",
3273          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3274          mp->ip_address);
3275 }
3276
3277 static void
3278   vl_api_one_map_resolver_details_t_handler_json
3279   (vl_api_one_map_resolver_details_t * mp)
3280 {
3281   vat_main_t *vam = &vat_main;
3282   vat_json_node_t *node = NULL;
3283   struct in6_addr ip6;
3284   struct in_addr ip4;
3285
3286   if (VAT_JSON_ARRAY != vam->json_tree.type)
3287     {
3288       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3289       vat_json_init_array (&vam->json_tree);
3290     }
3291   node = vat_json_array_add (&vam->json_tree);
3292
3293   vat_json_init_object (node);
3294   if (mp->is_ipv6)
3295     {
3296       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3297       vat_json_object_add_ip6 (node, "map resolver", ip6);
3298     }
3299   else
3300     {
3301       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3302       vat_json_object_add_ip4 (node, "map resolver", ip4);
3303     }
3304 }
3305
3306 static void
3307 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
3308 {
3309   vat_main_t *vam = &vat_main;
3310   i32 retval = ntohl (mp->retval);
3311
3312   if (0 <= retval)
3313     {
3314       print (vam->ofp, "feature: %s\ngpe: %s",
3315              mp->feature_status ? "enabled" : "disabled",
3316              mp->gpe_status ? "enabled" : "disabled");
3317     }
3318
3319   vam->retval = retval;
3320   vam->result_ready = 1;
3321 }
3322
3323 static void
3324   vl_api_show_one_status_reply_t_handler_json
3325   (vl_api_show_one_status_reply_t * mp)
3326 {
3327   vat_main_t *vam = &vat_main;
3328   vat_json_node_t node;
3329   u8 *gpe_status = NULL;
3330   u8 *feature_status = NULL;
3331
3332   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
3333   feature_status = format (0, "%s",
3334                            mp->feature_status ? "enabled" : "disabled");
3335   vec_add1 (gpe_status, 0);
3336   vec_add1 (feature_status, 0);
3337
3338   vat_json_init_object (&node);
3339   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
3340   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
3341
3342   vec_free (gpe_status);
3343   vec_free (feature_status);
3344
3345   vat_json_print (vam->ofp, &node);
3346   vat_json_free (&node);
3347
3348   vam->retval = ntohl (mp->retval);
3349   vam->result_ready = 1;
3350 }
3351
3352 static void
3353   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
3354   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3355 {
3356   vat_main_t *vam = &vat_main;
3357   i32 retval = ntohl (mp->retval);
3358
3359   if (retval >= 0)
3360     {
3361       print (vam->ofp, "%=20s", mp->locator_set_name);
3362     }
3363
3364   vam->retval = retval;
3365   vam->result_ready = 1;
3366 }
3367
3368 static void
3369   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
3370   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3371 {
3372   vat_main_t *vam = &vat_main;
3373   vat_json_node_t *node = NULL;
3374
3375   if (VAT_JSON_ARRAY != vam->json_tree.type)
3376     {
3377       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3378       vat_json_init_array (&vam->json_tree);
3379     }
3380   node = vat_json_array_add (&vam->json_tree);
3381
3382   vat_json_init_object (node);
3383   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
3384
3385   vat_json_print (vam->ofp, node);
3386   vat_json_free (node);
3387
3388   vam->retval = ntohl (mp->retval);
3389   vam->result_ready = 1;
3390 }
3391
3392 static u8 *
3393 format_lisp_map_request_mode (u8 * s, va_list * args)
3394 {
3395   u32 mode = va_arg (*args, u32);
3396
3397   switch (mode)
3398     {
3399     case 0:
3400       return format (0, "dst-only");
3401     case 1:
3402       return format (0, "src-dst");
3403     }
3404   return 0;
3405 }
3406
3407 static void
3408   vl_api_show_one_map_request_mode_reply_t_handler
3409   (vl_api_show_one_map_request_mode_reply_t * mp)
3410 {
3411   vat_main_t *vam = &vat_main;
3412   i32 retval = ntohl (mp->retval);
3413
3414   if (0 <= retval)
3415     {
3416       u32 mode = mp->mode;
3417       print (vam->ofp, "map_request_mode: %U",
3418              format_lisp_map_request_mode, mode);
3419     }
3420
3421   vam->retval = retval;
3422   vam->result_ready = 1;
3423 }
3424
3425 static void
3426   vl_api_show_one_map_request_mode_reply_t_handler_json
3427   (vl_api_show_one_map_request_mode_reply_t * mp)
3428 {
3429   vat_main_t *vam = &vat_main;
3430   vat_json_node_t node;
3431   u8 *s = 0;
3432   u32 mode;
3433
3434   mode = mp->mode;
3435   s = format (0, "%U", format_lisp_map_request_mode, mode);
3436   vec_add1 (s, 0);
3437
3438   vat_json_init_object (&node);
3439   vat_json_object_add_string_copy (&node, "map_request_mode", s);
3440   vat_json_print (vam->ofp, &node);
3441   vat_json_free (&node);
3442
3443   vec_free (s);
3444   vam->retval = ntohl (mp->retval);
3445   vam->result_ready = 1;
3446 }
3447
3448 static void
3449   vl_api_show_one_use_petr_reply_t_handler
3450   (vl_api_show_one_use_petr_reply_t * mp)
3451 {
3452   vat_main_t *vam = &vat_main;
3453   i32 retval = ntohl (mp->retval);
3454
3455   if (0 <= retval)
3456     {
3457       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
3458       if (mp->status)
3459         {
3460           print (vam->ofp, "Proxy-ETR address; %U",
3461                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
3462                  mp->address);
3463         }
3464     }
3465
3466   vam->retval = retval;
3467   vam->result_ready = 1;
3468 }
3469
3470 static void
3471   vl_api_show_one_use_petr_reply_t_handler_json
3472   (vl_api_show_one_use_petr_reply_t * mp)
3473 {
3474   vat_main_t *vam = &vat_main;
3475   vat_json_node_t node;
3476   u8 *status = 0;
3477   struct in_addr ip4;
3478   struct in6_addr ip6;
3479
3480   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3481   vec_add1 (status, 0);
3482
3483   vat_json_init_object (&node);
3484   vat_json_object_add_string_copy (&node, "status", status);
3485   if (mp->status)
3486     {
3487       if (mp->is_ip4)
3488         {
3489           clib_memcpy (&ip6, mp->address, sizeof (ip6));
3490           vat_json_object_add_ip6 (&node, "address", ip6);
3491         }
3492       else
3493         {
3494           clib_memcpy (&ip4, mp->address, sizeof (ip4));
3495           vat_json_object_add_ip4 (&node, "address", ip4);
3496         }
3497     }
3498
3499   vec_free (status);
3500
3501   vat_json_print (vam->ofp, &node);
3502   vat_json_free (&node);
3503
3504   vam->retval = ntohl (mp->retval);
3505   vam->result_ready = 1;
3506 }
3507
3508 static void
3509 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
3510 {
3511   vat_main_t *vam = &vat_main;
3512   i32 retval = ntohl (mp->retval);
3513
3514   if (0 <= retval)
3515     {
3516       print (vam->ofp, "%-20s%-16s",
3517              mp->status ? "enabled" : "disabled",
3518              mp->status ? (char *) mp->locator_set_name : "");
3519     }
3520
3521   vam->retval = retval;
3522   vam->result_ready = 1;
3523 }
3524
3525 static void
3526 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
3527 {
3528   vat_main_t *vam = &vat_main;
3529   vat_json_node_t node;
3530   u8 *status = 0;
3531
3532   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3533   vec_add1 (status, 0);
3534
3535   vat_json_init_object (&node);
3536   vat_json_object_add_string_copy (&node, "status", status);
3537   if (mp->status)
3538     {
3539       vat_json_object_add_string_copy (&node, "locator_set",
3540                                        mp->locator_set_name);
3541     }
3542
3543   vec_free (status);
3544
3545   vat_json_print (vam->ofp, &node);
3546   vat_json_free (&node);
3547
3548   vam->retval = ntohl (mp->retval);
3549   vam->result_ready = 1;
3550 }
3551
3552 static u8 *
3553 format_policer_type (u8 * s, va_list * va)
3554 {
3555   u32 i = va_arg (*va, u32);
3556
3557   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
3558     s = format (s, "1r2c");
3559   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
3560     s = format (s, "1r3c");
3561   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
3562     s = format (s, "2r3c-2698");
3563   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
3564     s = format (s, "2r3c-4115");
3565   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
3566     s = format (s, "2r3c-mef5cf1");
3567   else
3568     s = format (s, "ILLEGAL");
3569   return s;
3570 }
3571
3572 static u8 *
3573 format_policer_rate_type (u8 * s, va_list * va)
3574 {
3575   u32 i = va_arg (*va, u32);
3576
3577   if (i == SSE2_QOS_RATE_KBPS)
3578     s = format (s, "kbps");
3579   else if (i == SSE2_QOS_RATE_PPS)
3580     s = format (s, "pps");
3581   else
3582     s = format (s, "ILLEGAL");
3583   return s;
3584 }
3585
3586 static u8 *
3587 format_policer_round_type (u8 * s, va_list * va)
3588 {
3589   u32 i = va_arg (*va, u32);
3590
3591   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3592     s = format (s, "closest");
3593   else if (i == SSE2_QOS_ROUND_TO_UP)
3594     s = format (s, "up");
3595   else if (i == SSE2_QOS_ROUND_TO_DOWN)
3596     s = format (s, "down");
3597   else
3598     s = format (s, "ILLEGAL");
3599   return s;
3600 }
3601
3602 static u8 *
3603 format_policer_action_type (u8 * s, va_list * va)
3604 {
3605   u32 i = va_arg (*va, u32);
3606
3607   if (i == SSE2_QOS_ACTION_DROP)
3608     s = format (s, "drop");
3609   else if (i == SSE2_QOS_ACTION_TRANSMIT)
3610     s = format (s, "transmit");
3611   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3612     s = format (s, "mark-and-transmit");
3613   else
3614     s = format (s, "ILLEGAL");
3615   return s;
3616 }
3617
3618 static u8 *
3619 format_dscp (u8 * s, va_list * va)
3620 {
3621   u32 i = va_arg (*va, u32);
3622   char *t = 0;
3623
3624   switch (i)
3625     {
3626 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3627       foreach_vnet_dscp
3628 #undef _
3629     default:
3630       return format (s, "ILLEGAL");
3631     }
3632   s = format (s, "%s", t);
3633   return s;
3634 }
3635
3636 static void
3637 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3638 {
3639   vat_main_t *vam = &vat_main;
3640   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3641
3642   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3643     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3644   else
3645     conform_dscp_str = format (0, "");
3646
3647   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3648     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3649   else
3650     exceed_dscp_str = format (0, "");
3651
3652   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3653     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3654   else
3655     violate_dscp_str = format (0, "");
3656
3657   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3658          "rate type %U, round type %U, %s rate, %s color-aware, "
3659          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3660          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3661          "conform action %U%s, exceed action %U%s, violate action %U%s",
3662          mp->name,
3663          format_policer_type, mp->type,
3664          ntohl (mp->cir),
3665          ntohl (mp->eir),
3666          clib_net_to_host_u64 (mp->cb),
3667          clib_net_to_host_u64 (mp->eb),
3668          format_policer_rate_type, mp->rate_type,
3669          format_policer_round_type, mp->round_type,
3670          mp->single_rate ? "single" : "dual",
3671          mp->color_aware ? "is" : "not",
3672          ntohl (mp->cir_tokens_per_period),
3673          ntohl (mp->pir_tokens_per_period),
3674          ntohl (mp->scale),
3675          ntohl (mp->current_limit),
3676          ntohl (mp->current_bucket),
3677          ntohl (mp->extended_limit),
3678          ntohl (mp->extended_bucket),
3679          clib_net_to_host_u64 (mp->last_update_time),
3680          format_policer_action_type, mp->conform_action_type,
3681          conform_dscp_str,
3682          format_policer_action_type, mp->exceed_action_type,
3683          exceed_dscp_str,
3684          format_policer_action_type, mp->violate_action_type,
3685          violate_dscp_str);
3686
3687   vec_free (conform_dscp_str);
3688   vec_free (exceed_dscp_str);
3689   vec_free (violate_dscp_str);
3690 }
3691
3692 static void vl_api_policer_details_t_handler_json
3693   (vl_api_policer_details_t * mp)
3694 {
3695   vat_main_t *vam = &vat_main;
3696   vat_json_node_t *node;
3697   u8 *rate_type_str, *round_type_str, *type_str;
3698   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3699
3700   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3701   round_type_str =
3702     format (0, "%U", format_policer_round_type, mp->round_type);
3703   type_str = format (0, "%U", format_policer_type, mp->type);
3704   conform_action_str = format (0, "%U", format_policer_action_type,
3705                                mp->conform_action_type);
3706   exceed_action_str = format (0, "%U", format_policer_action_type,
3707                               mp->exceed_action_type);
3708   violate_action_str = format (0, "%U", format_policer_action_type,
3709                                mp->violate_action_type);
3710
3711   if (VAT_JSON_ARRAY != vam->json_tree.type)
3712     {
3713       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3714       vat_json_init_array (&vam->json_tree);
3715     }
3716   node = vat_json_array_add (&vam->json_tree);
3717
3718   vat_json_init_object (node);
3719   vat_json_object_add_string_copy (node, "name", mp->name);
3720   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3721   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3722   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
3723   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
3724   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3725   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3726   vat_json_object_add_string_copy (node, "type", type_str);
3727   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3728   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3729   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3730   vat_json_object_add_uint (node, "cir_tokens_per_period",
3731                             ntohl (mp->cir_tokens_per_period));
3732   vat_json_object_add_uint (node, "eir_tokens_per_period",
3733                             ntohl (mp->pir_tokens_per_period));
3734   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3735   vat_json_object_add_uint (node, "current_bucket",
3736                             ntohl (mp->current_bucket));
3737   vat_json_object_add_uint (node, "extended_limit",
3738                             ntohl (mp->extended_limit));
3739   vat_json_object_add_uint (node, "extended_bucket",
3740                             ntohl (mp->extended_bucket));
3741   vat_json_object_add_uint (node, "last_update_time",
3742                             ntohl (mp->last_update_time));
3743   vat_json_object_add_string_copy (node, "conform_action",
3744                                    conform_action_str);
3745   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3746     {
3747       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3748       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3749       vec_free (dscp_str);
3750     }
3751   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3752   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3753     {
3754       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3755       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3756       vec_free (dscp_str);
3757     }
3758   vat_json_object_add_string_copy (node, "violate_action",
3759                                    violate_action_str);
3760   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3761     {
3762       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3763       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3764       vec_free (dscp_str);
3765     }
3766
3767   vec_free (rate_type_str);
3768   vec_free (round_type_str);
3769   vec_free (type_str);
3770   vec_free (conform_action_str);
3771   vec_free (exceed_action_str);
3772   vec_free (violate_action_str);
3773 }
3774
3775 static void
3776 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3777                                            mp)
3778 {
3779   vat_main_t *vam = &vat_main;
3780   int i, count = ntohl (mp->count);
3781
3782   if (count > 0)
3783     print (vam->ofp, "classify table ids (%d) : ", count);
3784   for (i = 0; i < count; i++)
3785     {
3786       print (vam->ofp, "%d", ntohl (mp->ids[i]));
3787       print (vam->ofp, (i < count - 1) ? "," : "");
3788     }
3789   vam->retval = ntohl (mp->retval);
3790   vam->result_ready = 1;
3791 }
3792
3793 static void
3794   vl_api_classify_table_ids_reply_t_handler_json
3795   (vl_api_classify_table_ids_reply_t * mp)
3796 {
3797   vat_main_t *vam = &vat_main;
3798   int i, count = ntohl (mp->count);
3799
3800   if (count > 0)
3801     {
3802       vat_json_node_t node;
3803
3804       vat_json_init_object (&node);
3805       for (i = 0; i < count; i++)
3806         {
3807           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3808         }
3809       vat_json_print (vam->ofp, &node);
3810       vat_json_free (&node);
3811     }
3812   vam->retval = ntohl (mp->retval);
3813   vam->result_ready = 1;
3814 }
3815
3816 static void
3817   vl_api_classify_table_by_interface_reply_t_handler
3818   (vl_api_classify_table_by_interface_reply_t * mp)
3819 {
3820   vat_main_t *vam = &vat_main;
3821   u32 table_id;
3822
3823   table_id = ntohl (mp->l2_table_id);
3824   if (table_id != ~0)
3825     print (vam->ofp, "l2 table id : %d", table_id);
3826   else
3827     print (vam->ofp, "l2 table id : No input ACL tables configured");
3828   table_id = ntohl (mp->ip4_table_id);
3829   if (table_id != ~0)
3830     print (vam->ofp, "ip4 table id : %d", table_id);
3831   else
3832     print (vam->ofp, "ip4 table id : No input ACL tables configured");
3833   table_id = ntohl (mp->ip6_table_id);
3834   if (table_id != ~0)
3835     print (vam->ofp, "ip6 table id : %d", table_id);
3836   else
3837     print (vam->ofp, "ip6 table id : No input ACL tables configured");
3838   vam->retval = ntohl (mp->retval);
3839   vam->result_ready = 1;
3840 }
3841
3842 static void
3843   vl_api_classify_table_by_interface_reply_t_handler_json
3844   (vl_api_classify_table_by_interface_reply_t * mp)
3845 {
3846   vat_main_t *vam = &vat_main;
3847   vat_json_node_t node;
3848
3849   vat_json_init_object (&node);
3850
3851   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3852   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3853   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3854
3855   vat_json_print (vam->ofp, &node);
3856   vat_json_free (&node);
3857
3858   vam->retval = ntohl (mp->retval);
3859   vam->result_ready = 1;
3860 }
3861
3862 static void vl_api_policer_add_del_reply_t_handler
3863   (vl_api_policer_add_del_reply_t * mp)
3864 {
3865   vat_main_t *vam = &vat_main;
3866   i32 retval = ntohl (mp->retval);
3867   if (vam->async_mode)
3868     {
3869       vam->async_errors += (retval < 0);
3870     }
3871   else
3872     {
3873       vam->retval = retval;
3874       vam->result_ready = 1;
3875       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3876         /*
3877          * Note: this is just barely thread-safe, depends on
3878          * the main thread spinning waiting for an answer...
3879          */
3880         errmsg ("policer index %d", ntohl (mp->policer_index));
3881     }
3882 }
3883
3884 static void vl_api_policer_add_del_reply_t_handler_json
3885   (vl_api_policer_add_del_reply_t * mp)
3886 {
3887   vat_main_t *vam = &vat_main;
3888   vat_json_node_t node;
3889
3890   vat_json_init_object (&node);
3891   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3892   vat_json_object_add_uint (&node, "policer_index",
3893                             ntohl (mp->policer_index));
3894
3895   vat_json_print (vam->ofp, &node);
3896   vat_json_free (&node);
3897
3898   vam->retval = ntohl (mp->retval);
3899   vam->result_ready = 1;
3900 }
3901
3902 /* Format hex dump. */
3903 u8 *
3904 format_hex_bytes (u8 * s, va_list * va)
3905 {
3906   u8 *bytes = va_arg (*va, u8 *);
3907   int n_bytes = va_arg (*va, int);
3908   uword i;
3909
3910   /* Print short or long form depending on byte count. */
3911   uword short_form = n_bytes <= 32;
3912   uword indent = format_get_indent (s);
3913
3914   if (n_bytes == 0)
3915     return s;
3916
3917   for (i = 0; i < n_bytes; i++)
3918     {
3919       if (!short_form && (i % 32) == 0)
3920         s = format (s, "%08x: ", i);
3921       s = format (s, "%02x", bytes[i]);
3922       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3923         s = format (s, "\n%U", format_white_space, indent);
3924     }
3925
3926   return s;
3927 }
3928
3929 static void
3930 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3931                                             * mp)
3932 {
3933   vat_main_t *vam = &vat_main;
3934   i32 retval = ntohl (mp->retval);
3935   if (retval == 0)
3936     {
3937       print (vam->ofp, "classify table info :");
3938       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3939              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3940              ntohl (mp->miss_next_index));
3941       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3942              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3943              ntohl (mp->match_n_vectors));
3944       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3945              ntohl (mp->mask_length));
3946     }
3947   vam->retval = retval;
3948   vam->result_ready = 1;
3949 }
3950
3951 static void
3952   vl_api_classify_table_info_reply_t_handler_json
3953   (vl_api_classify_table_info_reply_t * mp)
3954 {
3955   vat_main_t *vam = &vat_main;
3956   vat_json_node_t node;
3957
3958   i32 retval = ntohl (mp->retval);
3959   if (retval == 0)
3960     {
3961       vat_json_init_object (&node);
3962
3963       vat_json_object_add_int (&node, "sessions",
3964                                ntohl (mp->active_sessions));
3965       vat_json_object_add_int (&node, "nexttbl",
3966                                ntohl (mp->next_table_index));
3967       vat_json_object_add_int (&node, "nextnode",
3968                                ntohl (mp->miss_next_index));
3969       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3970       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3971       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3972       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3973                       ntohl (mp->mask_length), 0);
3974       vat_json_object_add_string_copy (&node, "mask", s);
3975
3976       vat_json_print (vam->ofp, &node);
3977       vat_json_free (&node);
3978     }
3979   vam->retval = ntohl (mp->retval);
3980   vam->result_ready = 1;
3981 }
3982
3983 static void
3984 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3985                                            mp)
3986 {
3987   vat_main_t *vam = &vat_main;
3988
3989   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3990          ntohl (mp->hit_next_index), ntohl (mp->advance),
3991          ntohl (mp->opaque_index));
3992   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3993          ntohl (mp->match_length));
3994 }
3995
3996 static void
3997   vl_api_classify_session_details_t_handler_json
3998   (vl_api_classify_session_details_t * mp)
3999 {
4000   vat_main_t *vam = &vat_main;
4001   vat_json_node_t *node = NULL;
4002
4003   if (VAT_JSON_ARRAY != vam->json_tree.type)
4004     {
4005       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4006       vat_json_init_array (&vam->json_tree);
4007     }
4008   node = vat_json_array_add (&vam->json_tree);
4009
4010   vat_json_init_object (node);
4011   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4012   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4013   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4014   u8 *s =
4015     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4016             0);
4017   vat_json_object_add_string_copy (node, "match", s);
4018 }
4019
4020 static void vl_api_pg_create_interface_reply_t_handler
4021   (vl_api_pg_create_interface_reply_t * mp)
4022 {
4023   vat_main_t *vam = &vat_main;
4024
4025   vam->retval = ntohl (mp->retval);
4026   vam->result_ready = 1;
4027 }
4028
4029 static void vl_api_pg_create_interface_reply_t_handler_json
4030   (vl_api_pg_create_interface_reply_t * mp)
4031 {
4032   vat_main_t *vam = &vat_main;
4033   vat_json_node_t node;
4034
4035   i32 retval = ntohl (mp->retval);
4036   if (retval == 0)
4037     {
4038       vat_json_init_object (&node);
4039
4040       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4041
4042       vat_json_print (vam->ofp, &node);
4043       vat_json_free (&node);
4044     }
4045   vam->retval = ntohl (mp->retval);
4046   vam->result_ready = 1;
4047 }
4048
4049 static void vl_api_policer_classify_details_t_handler
4050   (vl_api_policer_classify_details_t * mp)
4051 {
4052   vat_main_t *vam = &vat_main;
4053
4054   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4055          ntohl (mp->table_index));
4056 }
4057
4058 static void vl_api_policer_classify_details_t_handler_json
4059   (vl_api_policer_classify_details_t * mp)
4060 {
4061   vat_main_t *vam = &vat_main;
4062   vat_json_node_t *node;
4063
4064   if (VAT_JSON_ARRAY != vam->json_tree.type)
4065     {
4066       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4067       vat_json_init_array (&vam->json_tree);
4068     }
4069   node = vat_json_array_add (&vam->json_tree);
4070
4071   vat_json_init_object (node);
4072   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4073   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4074 }
4075
4076 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
4077   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4078 {
4079   vat_main_t *vam = &vat_main;
4080   i32 retval = ntohl (mp->retval);
4081   if (vam->async_mode)
4082     {
4083       vam->async_errors += (retval < 0);
4084     }
4085   else
4086     {
4087       vam->retval = retval;
4088       vam->sw_if_index = ntohl (mp->sw_if_index);
4089       vam->result_ready = 1;
4090     }
4091 }
4092
4093 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
4094   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4095 {
4096   vat_main_t *vam = &vat_main;
4097   vat_json_node_t node;
4098
4099   vat_json_init_object (&node);
4100   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4101   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
4102
4103   vat_json_print (vam->ofp, &node);
4104   vat_json_free (&node);
4105
4106   vam->retval = ntohl (mp->retval);
4107   vam->result_ready = 1;
4108 }
4109
4110 static void vl_api_flow_classify_details_t_handler
4111   (vl_api_flow_classify_details_t * mp)
4112 {
4113   vat_main_t *vam = &vat_main;
4114
4115   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4116          ntohl (mp->table_index));
4117 }
4118
4119 static void vl_api_flow_classify_details_t_handler_json
4120   (vl_api_flow_classify_details_t * mp)
4121 {
4122   vat_main_t *vam = &vat_main;
4123   vat_json_node_t *node;
4124
4125   if (VAT_JSON_ARRAY != vam->json_tree.type)
4126     {
4127       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4128       vat_json_init_array (&vam->json_tree);
4129     }
4130   node = vat_json_array_add (&vam->json_tree);
4131
4132   vat_json_init_object (node);
4133   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4134   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4135 }
4136
4137 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
4138 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
4139 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
4140 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
4141 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
4142 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
4143 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
4144 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
4145 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
4146 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
4147 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
4148 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
4149 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
4150 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
4151
4152 /*
4153  * Generate boilerplate reply handlers, which
4154  * dig the return value out of the xxx_reply_t API message,
4155  * stick it into vam->retval, and set vam->result_ready
4156  *
4157  * Could also do this by pointing N message decode slots at
4158  * a single function, but that could break in subtle ways.
4159  */
4160
4161 #define foreach_standard_reply_retval_handler           \
4162 _(sw_interface_set_flags_reply)                         \
4163 _(sw_interface_add_del_address_reply)                   \
4164 _(sw_interface_set_table_reply)                         \
4165 _(sw_interface_set_mpls_enable_reply)                   \
4166 _(sw_interface_set_vpath_reply)                         \
4167 _(sw_interface_set_vxlan_bypass_reply)                  \
4168 _(sw_interface_set_l2_bridge_reply)                     \
4169 _(bridge_domain_add_del_reply)                          \
4170 _(sw_interface_set_l2_xconnect_reply)                   \
4171 _(l2fib_add_del_reply)                                  \
4172 _(l2fib_flush_int_reply)                                \
4173 _(l2fib_flush_bd_reply)                                 \
4174 _(ip_add_del_route_reply)                               \
4175 _(ip_mroute_add_del_reply)                              \
4176 _(mpls_route_add_del_reply)                             \
4177 _(mpls_ip_bind_unbind_reply)                            \
4178 _(proxy_arp_add_del_reply)                              \
4179 _(proxy_arp_intfc_enable_disable_reply)                 \
4180 _(sw_interface_set_unnumbered_reply)                    \
4181 _(ip_neighbor_add_del_reply)                            \
4182 _(reset_vrf_reply)                                      \
4183 _(oam_add_del_reply)                                    \
4184 _(reset_fib_reply)                                      \
4185 _(dhcp_proxy_config_reply)                              \
4186 _(dhcp_proxy_set_vss_reply)                             \
4187 _(dhcp_client_config_reply)                             \
4188 _(set_ip_flow_hash_reply)                               \
4189 _(sw_interface_ip6_enable_disable_reply)                \
4190 _(sw_interface_ip6_set_link_local_address_reply)        \
4191 _(ip6nd_proxy_add_del_reply)                            \
4192 _(sw_interface_ip6nd_ra_prefix_reply)                   \
4193 _(sw_interface_ip6nd_ra_config_reply)                   \
4194 _(set_arp_neighbor_limit_reply)                         \
4195 _(l2_patch_add_del_reply)                               \
4196 _(sr_policy_add_reply)                                  \
4197 _(sr_policy_mod_reply)                                  \
4198 _(sr_policy_del_reply)                                  \
4199 _(sr_localsid_add_del_reply)                            \
4200 _(sr_steering_add_del_reply)                            \
4201 _(classify_add_del_session_reply)                       \
4202 _(classify_set_interface_ip_table_reply)                \
4203 _(classify_set_interface_l2_tables_reply)               \
4204 _(l2tpv3_set_tunnel_cookies_reply)                      \
4205 _(l2tpv3_interface_enable_disable_reply)                \
4206 _(l2tpv3_set_lookup_key_reply)                          \
4207 _(l2_fib_clear_table_reply)                             \
4208 _(l2_interface_efp_filter_reply)                        \
4209 _(l2_interface_vlan_tag_rewrite_reply)                  \
4210 _(modify_vhost_user_if_reply)                           \
4211 _(delete_vhost_user_if_reply)                           \
4212 _(want_ip4_arp_events_reply)                            \
4213 _(want_ip6_nd_events_reply)                             \
4214 _(input_acl_set_interface_reply)                        \
4215 _(ipsec_spd_add_del_reply)                              \
4216 _(ipsec_interface_add_del_spd_reply)                    \
4217 _(ipsec_spd_add_del_entry_reply)                        \
4218 _(ipsec_sad_add_del_entry_reply)                        \
4219 _(ipsec_sa_set_key_reply)                               \
4220 _(ipsec_tunnel_if_add_del_reply)                        \
4221 _(ikev2_profile_add_del_reply)                          \
4222 _(ikev2_profile_set_auth_reply)                         \
4223 _(ikev2_profile_set_id_reply)                           \
4224 _(ikev2_profile_set_ts_reply)                           \
4225 _(ikev2_set_local_key_reply)                            \
4226 _(ikev2_set_responder_reply)                            \
4227 _(ikev2_set_ike_transforms_reply)                       \
4228 _(ikev2_set_esp_transforms_reply)                       \
4229 _(ikev2_set_sa_lifetime_reply)                          \
4230 _(ikev2_initiate_sa_init_reply)                         \
4231 _(ikev2_initiate_del_ike_sa_reply)                      \
4232 _(ikev2_initiate_del_child_sa_reply)                    \
4233 _(ikev2_initiate_rekey_child_sa_reply)                  \
4234 _(delete_loopback_reply)                                \
4235 _(bd_ip_mac_add_del_reply)                              \
4236 _(map_del_domain_reply)                                 \
4237 _(map_add_del_rule_reply)                               \
4238 _(want_interface_events_reply)                          \
4239 _(want_stats_reply)                                     \
4240 _(cop_interface_enable_disable_reply)                   \
4241 _(cop_whitelist_enable_disable_reply)                   \
4242 _(sw_interface_clear_stats_reply)                       \
4243 _(ioam_enable_reply)                              \
4244 _(ioam_disable_reply)                              \
4245 _(one_add_del_locator_reply)                            \
4246 _(one_add_del_local_eid_reply)                          \
4247 _(one_add_del_remote_mapping_reply)                     \
4248 _(one_add_del_adjacency_reply)                          \
4249 _(one_add_del_map_resolver_reply)                       \
4250 _(one_add_del_map_server_reply)                         \
4251 _(one_enable_disable_reply)                             \
4252 _(one_rloc_probe_enable_disable_reply)                  \
4253 _(one_map_register_enable_disable_reply)                \
4254 _(one_pitr_set_locator_set_reply)                       \
4255 _(one_map_request_mode_reply)                           \
4256 _(one_add_del_map_request_itr_rlocs_reply)              \
4257 _(one_eid_table_add_del_map_reply)                      \
4258 _(one_use_petr_reply)                                   \
4259 _(one_stats_enable_disable_reply)                       \
4260 _(one_stats_flush_reply)                                \
4261 _(gpe_add_del_fwd_entry_reply)                          \
4262 _(gpe_enable_disable_reply)                             \
4263 _(gpe_set_encap_mode_reply)                             \
4264 _(gpe_add_del_iface_reply)                              \
4265 _(vxlan_gpe_add_del_tunnel_reply)                       \
4266 _(af_packet_delete_reply)                               \
4267 _(policer_classify_set_interface_reply)                 \
4268 _(netmap_create_reply)                                  \
4269 _(netmap_delete_reply)                                  \
4270 _(set_ipfix_exporter_reply)                             \
4271 _(set_ipfix_classify_stream_reply)                      \
4272 _(ipfix_classify_table_add_del_reply)                   \
4273 _(flow_classify_set_interface_reply)                    \
4274 _(sw_interface_span_enable_disable_reply)               \
4275 _(pg_capture_reply)                                     \
4276 _(pg_enable_disable_reply)                              \
4277 _(ip_source_and_port_range_check_add_del_reply)         \
4278 _(ip_source_and_port_range_check_interface_add_del_reply)\
4279 _(delete_subif_reply)                                   \
4280 _(l2_interface_pbb_tag_rewrite_reply)                   \
4281 _(punt_reply)                                           \
4282 _(feature_enable_disable_reply)                         \
4283 _(sw_interface_tag_add_del_reply)                       \
4284 _(sw_interface_set_mtu_reply)
4285
4286 #define _(n)                                    \
4287     static void vl_api_##n##_t_handler          \
4288     (vl_api_##n##_t * mp)                       \
4289     {                                           \
4290         vat_main_t * vam = &vat_main;           \
4291         i32 retval = ntohl(mp->retval);         \
4292         if (vam->async_mode) {                  \
4293             vam->async_errors += (retval < 0);  \
4294         } else {                                \
4295             vam->retval = retval;               \
4296             vam->result_ready = 1;              \
4297         }                                       \
4298     }
4299 foreach_standard_reply_retval_handler;
4300 #undef _
4301
4302 #define _(n)                                    \
4303     static void vl_api_##n##_t_handler_json     \
4304     (vl_api_##n##_t * mp)                       \
4305     {                                           \
4306         vat_main_t * vam = &vat_main;           \
4307         vat_json_node_t node;                   \
4308         vat_json_init_object(&node);            \
4309         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
4310         vat_json_print(vam->ofp, &node);        \
4311         vam->retval = ntohl(mp->retval);        \
4312         vam->result_ready = 1;                  \
4313     }
4314 foreach_standard_reply_retval_handler;
4315 #undef _
4316
4317 /*
4318  * Table of message reply handlers, must include boilerplate handlers
4319  * we just generated
4320  */
4321
4322 #define foreach_vpe_api_reply_msg                                       \
4323 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
4324 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
4325 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
4326 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
4327 _(CONTROL_PING_REPLY, control_ping_reply)                               \
4328 _(CLI_REPLY, cli_reply)                                                 \
4329 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
4330 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
4331   sw_interface_add_del_address_reply)                                   \
4332 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
4333 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
4334 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
4335 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
4336 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
4337   sw_interface_set_l2_xconnect_reply)                                   \
4338 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
4339   sw_interface_set_l2_bridge_reply)                                     \
4340 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
4341 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
4342 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
4343 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
4344 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
4345 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
4346 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
4347 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
4348 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
4349 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
4350 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
4351 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
4352 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
4353 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
4354 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
4355 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
4356 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
4357 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
4358   proxy_arp_intfc_enable_disable_reply)                                 \
4359 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
4360 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
4361   sw_interface_set_unnumbered_reply)                                    \
4362 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
4363 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
4364 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
4365 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
4366 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
4367 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
4368 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
4369 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
4370 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
4371 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
4372 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
4373 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
4374   sw_interface_ip6_enable_disable_reply)                                \
4375 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
4376   sw_interface_ip6_set_link_local_address_reply)                        \
4377 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
4378 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
4379 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
4380   sw_interface_ip6nd_ra_prefix_reply)                                   \
4381 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
4382   sw_interface_ip6nd_ra_config_reply)                                   \
4383 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
4384 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
4385 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
4386 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
4387 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
4388 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
4389 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
4390 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
4391 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
4392 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
4393 classify_set_interface_ip_table_reply)                                  \
4394 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
4395   classify_set_interface_l2_tables_reply)                               \
4396 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
4397 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
4398 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
4399 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
4400 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
4401   l2tpv3_interface_enable_disable_reply)                                \
4402 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
4403 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
4404 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
4405 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
4406 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
4407 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
4408 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
4409 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
4410 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4411 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
4412 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
4413 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
4414 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
4415 _(SHOW_VERSION_REPLY, show_version_reply)                               \
4416 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
4417 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
4418 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
4419 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
4420 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
4421 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
4422 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
4423 _(IP6_ND_EVENT, ip6_nd_event)                                           \
4424 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
4425 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
4426 _(IP_DETAILS, ip_details)                                               \
4427 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
4428 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4429 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
4430 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
4431 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
4432 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
4433 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
4434 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
4435 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
4436 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
4437 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
4438 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
4439 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
4440 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
4441 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
4442 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
4443 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
4444 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
4445 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
4446 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
4447 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
4448 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
4449 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
4450 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
4451 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
4452 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
4453 _(MAP_RULE_DETAILS, map_rule_details)                                   \
4454 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
4455 _(WANT_STATS_REPLY, want_stats_reply)                                   \
4456 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
4457 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4458 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4459 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
4460 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
4461 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
4462 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
4463 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
4464 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
4465 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
4466 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
4467 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
4468 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
4469 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
4470 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
4471 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
4472   one_map_register_enable_disable_reply)                                \
4473 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
4474   one_rloc_probe_enable_disable_reply)                                  \
4475 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
4476 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
4477 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
4478 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
4479 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
4480 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
4481 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
4482 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
4483 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
4484 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
4485 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
4486 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
4487 _(ONE_STATS_DETAILS, one_stats_details)                                 \
4488 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
4489 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
4490 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
4491   show_one_stats_enable_disable_reply)                                  \
4492 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
4493 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
4494 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
4495 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
4496 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
4497 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
4498 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
4499   gpe_fwd_entry_path_details)                                           \
4500 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
4501 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
4502   one_add_del_map_request_itr_rlocs_reply)                              \
4503 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
4504   one_get_map_request_itr_rlocs_reply)                                  \
4505 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
4506 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
4507 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
4508 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
4509 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
4510   show_one_map_register_state_reply)                                    \
4511 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
4512 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
4513 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
4514 _(POLICER_DETAILS, policer_details)                                     \
4515 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4516 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
4517 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
4518 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
4519 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
4520 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
4521 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
4522 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4523 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
4524 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
4525 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
4526 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
4527 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
4528 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
4529 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4530 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
4531 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4532 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
4533 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
4534 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
4535 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
4536 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
4537 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
4538 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
4539 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
4540  ip_source_and_port_range_check_add_del_reply)                          \
4541 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
4542  ip_source_and_port_range_check_interface_add_del_reply)                \
4543 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
4544 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
4545 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
4546 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
4547 _(PUNT_REPLY, punt_reply)                                               \
4548 _(IP_FIB_DETAILS, ip_fib_details)                                       \
4549 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
4550 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
4551 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
4552 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
4553 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
4554 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
4555 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
4556
4557 #define foreach_standalone_reply_msg                                    \
4558 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
4559 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
4560 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
4561 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
4562 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
4563 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
4564 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
4565
4566 typedef struct
4567 {
4568   u8 *name;
4569   u32 value;
4570 } name_sort_t;
4571
4572
4573 #define STR_VTR_OP_CASE(op)     \
4574     case L2_VTR_ ## op:         \
4575         return "" # op;
4576
4577 static const char *
4578 str_vtr_op (u32 vtr_op)
4579 {
4580   switch (vtr_op)
4581     {
4582       STR_VTR_OP_CASE (DISABLED);
4583       STR_VTR_OP_CASE (PUSH_1);
4584       STR_VTR_OP_CASE (PUSH_2);
4585       STR_VTR_OP_CASE (POP_1);
4586       STR_VTR_OP_CASE (POP_2);
4587       STR_VTR_OP_CASE (TRANSLATE_1_1);
4588       STR_VTR_OP_CASE (TRANSLATE_1_2);
4589       STR_VTR_OP_CASE (TRANSLATE_2_1);
4590       STR_VTR_OP_CASE (TRANSLATE_2_2);
4591     }
4592
4593   return "UNKNOWN";
4594 }
4595
4596 static int
4597 dump_sub_interface_table (vat_main_t * vam)
4598 {
4599   const sw_interface_subif_t *sub = NULL;
4600
4601   if (vam->json_output)
4602     {
4603       clib_warning
4604         ("JSON output supported only for VPE API calls and dump_stats_table");
4605       return -99;
4606     }
4607
4608   print (vam->ofp,
4609          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4610          "Interface", "sw_if_index",
4611          "sub id", "dot1ad", "tags", "outer id",
4612          "inner id", "exact", "default", "outer any", "inner any");
4613
4614   vec_foreach (sub, vam->sw_if_subif_table)
4615   {
4616     print (vam->ofp,
4617            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4618            sub->interface_name,
4619            sub->sw_if_index,
4620            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4621            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4622            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4623            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4624     if (sub->vtr_op != L2_VTR_DISABLED)
4625       {
4626         print (vam->ofp,
4627                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4628                "tag1: %d tag2: %d ]",
4629                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4630                sub->vtr_tag1, sub->vtr_tag2);
4631       }
4632   }
4633
4634   return 0;
4635 }
4636
4637 static int
4638 name_sort_cmp (void *a1, void *a2)
4639 {
4640   name_sort_t *n1 = a1;
4641   name_sort_t *n2 = a2;
4642
4643   return strcmp ((char *) n1->name, (char *) n2->name);
4644 }
4645
4646 static int
4647 dump_interface_table (vat_main_t * vam)
4648 {
4649   hash_pair_t *p;
4650   name_sort_t *nses = 0, *ns;
4651
4652   if (vam->json_output)
4653     {
4654       clib_warning
4655         ("JSON output supported only for VPE API calls and dump_stats_table");
4656       return -99;
4657     }
4658
4659   /* *INDENT-OFF* */
4660   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4661   ({
4662     vec_add2 (nses, ns, 1);
4663     ns->name = (u8 *)(p->key);
4664     ns->value = (u32) p->value[0];
4665   }));
4666   /* *INDENT-ON* */
4667
4668   vec_sort_with_function (nses, name_sort_cmp);
4669
4670   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4671   vec_foreach (ns, nses)
4672   {
4673     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4674   }
4675   vec_free (nses);
4676   return 0;
4677 }
4678
4679 static int
4680 dump_ip_table (vat_main_t * vam, int is_ipv6)
4681 {
4682   const ip_details_t *det = NULL;
4683   const ip_address_details_t *address = NULL;
4684   u32 i = ~0;
4685
4686   print (vam->ofp, "%-12s", "sw_if_index");
4687
4688   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4689   {
4690     i++;
4691     if (!det->present)
4692       {
4693         continue;
4694       }
4695     print (vam->ofp, "%-12d", i);
4696     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
4697     if (!det->addr)
4698       {
4699         continue;
4700       }
4701     vec_foreach (address, det->addr)
4702     {
4703       print (vam->ofp,
4704              "            %-30U%-13d",
4705              is_ipv6 ? format_ip6_address : format_ip4_address,
4706              address->ip, address->prefix_length);
4707     }
4708   }
4709
4710   return 0;
4711 }
4712
4713 static int
4714 dump_ipv4_table (vat_main_t * vam)
4715 {
4716   if (vam->json_output)
4717     {
4718       clib_warning
4719         ("JSON output supported only for VPE API calls and dump_stats_table");
4720       return -99;
4721     }
4722
4723   return dump_ip_table (vam, 0);
4724 }
4725
4726 static int
4727 dump_ipv6_table (vat_main_t * vam)
4728 {
4729   if (vam->json_output)
4730     {
4731       clib_warning
4732         ("JSON output supported only for VPE API calls and dump_stats_table");
4733       return -99;
4734     }
4735
4736   return dump_ip_table (vam, 1);
4737 }
4738
4739 static char *
4740 counter_type_to_str (u8 counter_type, u8 is_combined)
4741 {
4742   if (!is_combined)
4743     {
4744       switch (counter_type)
4745         {
4746         case VNET_INTERFACE_COUNTER_DROP:
4747           return "drop";
4748         case VNET_INTERFACE_COUNTER_PUNT:
4749           return "punt";
4750         case VNET_INTERFACE_COUNTER_IP4:
4751           return "ip4";
4752         case VNET_INTERFACE_COUNTER_IP6:
4753           return "ip6";
4754         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4755           return "rx-no-buf";
4756         case VNET_INTERFACE_COUNTER_RX_MISS:
4757           return "rx-miss";
4758         case VNET_INTERFACE_COUNTER_RX_ERROR:
4759           return "rx-error";
4760         case VNET_INTERFACE_COUNTER_TX_ERROR:
4761           return "tx-error";
4762         default:
4763           return "INVALID-COUNTER-TYPE";
4764         }
4765     }
4766   else
4767     {
4768       switch (counter_type)
4769         {
4770         case VNET_INTERFACE_COUNTER_RX:
4771           return "rx";
4772         case VNET_INTERFACE_COUNTER_TX:
4773           return "tx";
4774         default:
4775           return "INVALID-COUNTER-TYPE";
4776         }
4777     }
4778 }
4779
4780 static int
4781 dump_stats_table (vat_main_t * vam)
4782 {
4783   vat_json_node_t node;
4784   vat_json_node_t *msg_array;
4785   vat_json_node_t *msg;
4786   vat_json_node_t *counter_array;
4787   vat_json_node_t *counter;
4788   interface_counter_t c;
4789   u64 packets;
4790   ip4_fib_counter_t *c4;
4791   ip6_fib_counter_t *c6;
4792   ip4_nbr_counter_t *n4;
4793   ip6_nbr_counter_t *n6;
4794   int i, j;
4795
4796   if (!vam->json_output)
4797     {
4798       clib_warning ("dump_stats_table supported only in JSON format");
4799       return -99;
4800     }
4801
4802   vat_json_init_object (&node);
4803
4804   /* interface counters */
4805   msg_array = vat_json_object_add (&node, "interface_counters");
4806   vat_json_init_array (msg_array);
4807   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4808     {
4809       msg = vat_json_array_add (msg_array);
4810       vat_json_init_object (msg);
4811       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4812                                        (u8 *) counter_type_to_str (i, 0));
4813       vat_json_object_add_int (msg, "is_combined", 0);
4814       counter_array = vat_json_object_add (msg, "data");
4815       vat_json_init_array (counter_array);
4816       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4817         {
4818           packets = vam->simple_interface_counters[i][j];
4819           vat_json_array_add_uint (counter_array, packets);
4820         }
4821     }
4822   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4823     {
4824       msg = vat_json_array_add (msg_array);
4825       vat_json_init_object (msg);
4826       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4827                                        (u8 *) counter_type_to_str (i, 1));
4828       vat_json_object_add_int (msg, "is_combined", 1);
4829       counter_array = vat_json_object_add (msg, "data");
4830       vat_json_init_array (counter_array);
4831       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4832         {
4833           c = vam->combined_interface_counters[i][j];
4834           counter = vat_json_array_add (counter_array);
4835           vat_json_init_object (counter);
4836           vat_json_object_add_uint (counter, "packets", c.packets);
4837           vat_json_object_add_uint (counter, "bytes", c.bytes);
4838         }
4839     }
4840
4841   /* ip4 fib counters */
4842   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4843   vat_json_init_array (msg_array);
4844   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4845     {
4846       msg = vat_json_array_add (msg_array);
4847       vat_json_init_object (msg);
4848       vat_json_object_add_uint (msg, "vrf_id",
4849                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4850       counter_array = vat_json_object_add (msg, "c");
4851       vat_json_init_array (counter_array);
4852       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4853         {
4854           counter = vat_json_array_add (counter_array);
4855           vat_json_init_object (counter);
4856           c4 = &vam->ip4_fib_counters[i][j];
4857           vat_json_object_add_ip4 (counter, "address", c4->address);
4858           vat_json_object_add_uint (counter, "address_length",
4859                                     c4->address_length);
4860           vat_json_object_add_uint (counter, "packets", c4->packets);
4861           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4862         }
4863     }
4864
4865   /* ip6 fib counters */
4866   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4867   vat_json_init_array (msg_array);
4868   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4869     {
4870       msg = vat_json_array_add (msg_array);
4871       vat_json_init_object (msg);
4872       vat_json_object_add_uint (msg, "vrf_id",
4873                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4874       counter_array = vat_json_object_add (msg, "c");
4875       vat_json_init_array (counter_array);
4876       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4877         {
4878           counter = vat_json_array_add (counter_array);
4879           vat_json_init_object (counter);
4880           c6 = &vam->ip6_fib_counters[i][j];
4881           vat_json_object_add_ip6 (counter, "address", c6->address);
4882           vat_json_object_add_uint (counter, "address_length",
4883                                     c6->address_length);
4884           vat_json_object_add_uint (counter, "packets", c6->packets);
4885           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4886         }
4887     }
4888
4889   /* ip4 nbr counters */
4890   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
4891   vat_json_init_array (msg_array);
4892   for (i = 0; i < vec_len (vam->ip4_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->ip4_nbr_counters[i]); j++)
4900         {
4901           counter = vat_json_array_add (counter_array);
4902           vat_json_init_object (counter);
4903           n4 = &vam->ip4_nbr_counters[i][j];
4904           vat_json_object_add_ip4 (counter, "address", n4->address);
4905           vat_json_object_add_uint (counter, "link-type", n4->linkt);
4906           vat_json_object_add_uint (counter, "packets", n4->packets);
4907           vat_json_object_add_uint (counter, "bytes", n4->bytes);
4908         }
4909     }
4910
4911   /* ip6 nbr counters */
4912   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
4913   vat_json_init_array (msg_array);
4914   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
4915     {
4916       msg = vat_json_array_add (msg_array);
4917       vat_json_init_object (msg);
4918       vat_json_object_add_uint (msg, "sw_if_index", i);
4919       counter_array = vat_json_object_add (msg, "c");
4920       vat_json_init_array (counter_array);
4921       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
4922         {
4923           counter = vat_json_array_add (counter_array);
4924           vat_json_init_object (counter);
4925           n6 = &vam->ip6_nbr_counters[i][j];
4926           vat_json_object_add_ip6 (counter, "address", n6->address);
4927           vat_json_object_add_uint (counter, "packets", n6->packets);
4928           vat_json_object_add_uint (counter, "bytes", n6->bytes);
4929         }
4930     }
4931
4932   vat_json_print (vam->ofp, &node);
4933   vat_json_free (&node);
4934
4935   return 0;
4936 }
4937
4938 int
4939 exec (vat_main_t * vam)
4940 {
4941   api_main_t *am = &api_main;
4942   vl_api_cli_t *mp;
4943   f64 timeout;
4944   void *oldheap;
4945   u8 *cmd = 0;
4946   unformat_input_t *i = vam->input;
4947
4948   if (vec_len (i->buffer) == 0)
4949     return -1;
4950
4951   if (vam->exec_mode == 0 && unformat (i, "mode"))
4952     {
4953       vam->exec_mode = 1;
4954       return 0;
4955     }
4956   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4957     {
4958       vam->exec_mode = 0;
4959       return 0;
4960     }
4961
4962
4963   M (CLI, mp);
4964
4965   /*
4966    * Copy cmd into shared memory.
4967    * In order for the CLI command to work, it
4968    * must be a vector ending in \n, not a C-string ending
4969    * in \n\0.
4970    */
4971   pthread_mutex_lock (&am->vlib_rp->mutex);
4972   oldheap = svm_push_data_heap (am->vlib_rp);
4973
4974   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4975   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4976
4977   svm_pop_heap (oldheap);
4978   pthread_mutex_unlock (&am->vlib_rp->mutex);
4979
4980   mp->cmd_in_shmem = pointer_to_uword (cmd);
4981   S (mp);
4982   timeout = vat_time_now (vam) + 10.0;
4983
4984   while (vat_time_now (vam) < timeout)
4985     {
4986       if (vam->result_ready == 1)
4987         {
4988           u8 *free_me;
4989           if (vam->shmem_result != NULL)
4990             print (vam->ofp, "%s", vam->shmem_result);
4991           pthread_mutex_lock (&am->vlib_rp->mutex);
4992           oldheap = svm_push_data_heap (am->vlib_rp);
4993
4994           free_me = (u8 *) vam->shmem_result;
4995           vec_free (free_me);
4996
4997           svm_pop_heap (oldheap);
4998           pthread_mutex_unlock (&am->vlib_rp->mutex);
4999           return 0;
5000         }
5001     }
5002   return -99;
5003 }
5004
5005 /*
5006  * Future replacement of exec() that passes CLI buffers directly in
5007  * the API messages instead of an additional shared memory area.
5008  */
5009 static int
5010 exec_inband (vat_main_t * vam)
5011 {
5012   vl_api_cli_inband_t *mp;
5013   unformat_input_t *i = vam->input;
5014   int ret;
5015
5016   if (vec_len (i->buffer) == 0)
5017     return -1;
5018
5019   if (vam->exec_mode == 0 && unformat (i, "mode"))
5020     {
5021       vam->exec_mode = 1;
5022       return 0;
5023     }
5024   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5025     {
5026       vam->exec_mode = 0;
5027       return 0;
5028     }
5029
5030   /*
5031    * In order for the CLI command to work, it
5032    * must be a vector ending in \n, not a C-string ending
5033    * in \n\0.
5034    */
5035   u32 len = vec_len (vam->input->buffer);
5036   M2 (CLI_INBAND, mp, len);
5037   clib_memcpy (mp->cmd, vam->input->buffer, len);
5038   mp->length = htonl (len);
5039
5040   S (mp);
5041   W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
5042   return ret;
5043 }
5044
5045 static int
5046 api_create_loopback (vat_main_t * vam)
5047 {
5048   unformat_input_t *i = vam->input;
5049   vl_api_create_loopback_t *mp;
5050   vl_api_create_loopback_instance_t *mp_lbi;
5051   u8 mac_address[6];
5052   u8 mac_set = 0;
5053   u8 is_specified = 0;
5054   u32 user_instance = 0;
5055   int ret;
5056
5057   memset (mac_address, 0, sizeof (mac_address));
5058
5059   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5060     {
5061       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5062         mac_set = 1;
5063       if (unformat (i, "instance %d", &user_instance))
5064         is_specified = 1;
5065       else
5066         break;
5067     }
5068
5069   if (is_specified)
5070     {
5071       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5072       mp_lbi->is_specified = is_specified;
5073       if (is_specified)
5074         mp_lbi->user_instance = htonl (user_instance);
5075       if (mac_set)
5076         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5077       S (mp_lbi);
5078     }
5079   else
5080     {
5081       /* Construct the API message */
5082       M (CREATE_LOOPBACK, mp);
5083       if (mac_set)
5084         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5085       S (mp);
5086     }
5087
5088   W (ret);
5089   return ret;
5090 }
5091
5092 static int
5093 api_delete_loopback (vat_main_t * vam)
5094 {
5095   unformat_input_t *i = vam->input;
5096   vl_api_delete_loopback_t *mp;
5097   u32 sw_if_index = ~0;
5098   int ret;
5099
5100   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5101     {
5102       if (unformat (i, "sw_if_index %d", &sw_if_index))
5103         ;
5104       else
5105         break;
5106     }
5107
5108   if (sw_if_index == ~0)
5109     {
5110       errmsg ("missing sw_if_index");
5111       return -99;
5112     }
5113
5114   /* Construct the API message */
5115   M (DELETE_LOOPBACK, mp);
5116   mp->sw_if_index = ntohl (sw_if_index);
5117
5118   S (mp);
5119   W (ret);
5120   return ret;
5121 }
5122
5123 static int
5124 api_want_stats (vat_main_t * vam)
5125 {
5126   unformat_input_t *i = vam->input;
5127   vl_api_want_stats_t *mp;
5128   int enable = -1;
5129   int ret;
5130
5131   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5132     {
5133       if (unformat (i, "enable"))
5134         enable = 1;
5135       else if (unformat (i, "disable"))
5136         enable = 0;
5137       else
5138         break;
5139     }
5140
5141   if (enable == -1)
5142     {
5143       errmsg ("missing enable|disable");
5144       return -99;
5145     }
5146
5147   M (WANT_STATS, mp);
5148   mp->enable_disable = enable;
5149
5150   S (mp);
5151   W (ret);
5152   return ret;
5153 }
5154
5155 static int
5156 api_want_interface_events (vat_main_t * vam)
5157 {
5158   unformat_input_t *i = vam->input;
5159   vl_api_want_interface_events_t *mp;
5160   int enable = -1;
5161   int ret;
5162
5163   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5164     {
5165       if (unformat (i, "enable"))
5166         enable = 1;
5167       else if (unformat (i, "disable"))
5168         enable = 0;
5169       else
5170         break;
5171     }
5172
5173   if (enable == -1)
5174     {
5175       errmsg ("missing enable|disable");
5176       return -99;
5177     }
5178
5179   M (WANT_INTERFACE_EVENTS, mp);
5180   mp->enable_disable = enable;
5181
5182   vam->interface_event_display = enable;
5183
5184   S (mp);
5185   W (ret);
5186   return ret;
5187 }
5188
5189
5190 /* Note: non-static, called once to set up the initial intfc table */
5191 int
5192 api_sw_interface_dump (vat_main_t * vam)
5193 {
5194   vl_api_sw_interface_dump_t *mp;
5195   vl_api_control_ping_t *mp_ping;
5196   hash_pair_t *p;
5197   name_sort_t *nses = 0, *ns;
5198   sw_interface_subif_t *sub = NULL;
5199   int ret;
5200
5201   /* Toss the old name table */
5202   /* *INDENT-OFF* */
5203   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5204   ({
5205     vec_add2 (nses, ns, 1);
5206     ns->name = (u8 *)(p->key);
5207     ns->value = (u32) p->value[0];
5208   }));
5209   /* *INDENT-ON* */
5210
5211   hash_free (vam->sw_if_index_by_interface_name);
5212
5213   vec_foreach (ns, nses) vec_free (ns->name);
5214
5215   vec_free (nses);
5216
5217   vec_foreach (sub, vam->sw_if_subif_table)
5218   {
5219     vec_free (sub->interface_name);
5220   }
5221   vec_free (vam->sw_if_subif_table);
5222
5223   /* recreate the interface name hash table */
5224   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5225
5226   /* Get list of ethernets */
5227   M (SW_INTERFACE_DUMP, mp);
5228   mp->name_filter_valid = 1;
5229   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
5230   S (mp);
5231
5232   /* and local / loopback interfaces */
5233   M (SW_INTERFACE_DUMP, mp);
5234   mp->name_filter_valid = 1;
5235   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
5236   S (mp);
5237
5238   /* and packet-generator interfaces */
5239   M (SW_INTERFACE_DUMP, mp);
5240   mp->name_filter_valid = 1;
5241   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
5242   S (mp);
5243
5244   /* and vxlan-gpe tunnel interfaces */
5245   M (SW_INTERFACE_DUMP, mp);
5246   mp->name_filter_valid = 1;
5247   strncpy ((char *) mp->name_filter, "vxlan_gpe",
5248            sizeof (mp->name_filter) - 1);
5249   S (mp);
5250
5251   /* and vxlan tunnel interfaces */
5252   M (SW_INTERFACE_DUMP, mp);
5253   mp->name_filter_valid = 1;
5254   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
5255   S (mp);
5256
5257   /* and host (af_packet) interfaces */
5258   M (SW_INTERFACE_DUMP, mp);
5259   mp->name_filter_valid = 1;
5260   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
5261   S (mp);
5262
5263   /* and l2tpv3 tunnel interfaces */
5264   M (SW_INTERFACE_DUMP, mp);
5265   mp->name_filter_valid = 1;
5266   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
5267            sizeof (mp->name_filter) - 1);
5268   S (mp);
5269
5270   /* and GRE tunnel interfaces */
5271   M (SW_INTERFACE_DUMP, mp);
5272   mp->name_filter_valid = 1;
5273   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
5274   S (mp);
5275
5276   /* and LISP-GPE interfaces */
5277   M (SW_INTERFACE_DUMP, mp);
5278   mp->name_filter_valid = 1;
5279   strncpy ((char *) mp->name_filter, "lisp_gpe",
5280            sizeof (mp->name_filter) - 1);
5281   S (mp);
5282
5283   /* and IPSEC tunnel interfaces */
5284   M (SW_INTERFACE_DUMP, mp);
5285   mp->name_filter_valid = 1;
5286   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
5287   S (mp);
5288
5289   /* Use a control ping for synchronization */
5290   M (CONTROL_PING, mp_ping);
5291   S (mp_ping);
5292
5293   W (ret);
5294   return ret;
5295 }
5296
5297 static int
5298 api_sw_interface_set_flags (vat_main_t * vam)
5299 {
5300   unformat_input_t *i = vam->input;
5301   vl_api_sw_interface_set_flags_t *mp;
5302   u32 sw_if_index;
5303   u8 sw_if_index_set = 0;
5304   u8 admin_up = 0, link_up = 0;
5305   int ret;
5306
5307   /* Parse args required to build the message */
5308   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5309     {
5310       if (unformat (i, "admin-up"))
5311         admin_up = 1;
5312       else if (unformat (i, "admin-down"))
5313         admin_up = 0;
5314       else if (unformat (i, "link-up"))
5315         link_up = 1;
5316       else if (unformat (i, "link-down"))
5317         link_up = 0;
5318       else
5319         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5320         sw_if_index_set = 1;
5321       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5322         sw_if_index_set = 1;
5323       else
5324         break;
5325     }
5326
5327   if (sw_if_index_set == 0)
5328     {
5329       errmsg ("missing interface name or sw_if_index");
5330       return -99;
5331     }
5332
5333   /* Construct the API message */
5334   M (SW_INTERFACE_SET_FLAGS, mp);
5335   mp->sw_if_index = ntohl (sw_if_index);
5336   mp->admin_up_down = admin_up;
5337   mp->link_up_down = link_up;
5338
5339   /* send it... */
5340   S (mp);
5341
5342   /* Wait for a reply, return the good/bad news... */
5343   W (ret);
5344   return ret;
5345 }
5346
5347 static int
5348 api_sw_interface_clear_stats (vat_main_t * vam)
5349 {
5350   unformat_input_t *i = vam->input;
5351   vl_api_sw_interface_clear_stats_t *mp;
5352   u32 sw_if_index;
5353   u8 sw_if_index_set = 0;
5354   int ret;
5355
5356   /* Parse args required to build the message */
5357   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5358     {
5359       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5360         sw_if_index_set = 1;
5361       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5362         sw_if_index_set = 1;
5363       else
5364         break;
5365     }
5366
5367   /* Construct the API message */
5368   M (SW_INTERFACE_CLEAR_STATS, mp);
5369
5370   if (sw_if_index_set == 1)
5371     mp->sw_if_index = ntohl (sw_if_index);
5372   else
5373     mp->sw_if_index = ~0;
5374
5375   /* send it... */
5376   S (mp);
5377
5378   /* Wait for a reply, return the good/bad news... */
5379   W (ret);
5380   return ret;
5381 }
5382
5383 static int
5384 api_sw_interface_add_del_address (vat_main_t * vam)
5385 {
5386   unformat_input_t *i = vam->input;
5387   vl_api_sw_interface_add_del_address_t *mp;
5388   u32 sw_if_index;
5389   u8 sw_if_index_set = 0;
5390   u8 is_add = 1, del_all = 0;
5391   u32 address_length = 0;
5392   u8 v4_address_set = 0;
5393   u8 v6_address_set = 0;
5394   ip4_address_t v4address;
5395   ip6_address_t v6address;
5396   int ret;
5397
5398   /* Parse args required to build the message */
5399   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5400     {
5401       if (unformat (i, "del-all"))
5402         del_all = 1;
5403       else if (unformat (i, "del"))
5404         is_add = 0;
5405       else
5406         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5407         sw_if_index_set = 1;
5408       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5409         sw_if_index_set = 1;
5410       else if (unformat (i, "%U/%d",
5411                          unformat_ip4_address, &v4address, &address_length))
5412         v4_address_set = 1;
5413       else if (unformat (i, "%U/%d",
5414                          unformat_ip6_address, &v6address, &address_length))
5415         v6_address_set = 1;
5416       else
5417         break;
5418     }
5419
5420   if (sw_if_index_set == 0)
5421     {
5422       errmsg ("missing interface name or sw_if_index");
5423       return -99;
5424     }
5425   if (v4_address_set && v6_address_set)
5426     {
5427       errmsg ("both v4 and v6 addresses set");
5428       return -99;
5429     }
5430   if (!v4_address_set && !v6_address_set && !del_all)
5431     {
5432       errmsg ("no addresses set");
5433       return -99;
5434     }
5435
5436   /* Construct the API message */
5437   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
5438
5439   mp->sw_if_index = ntohl (sw_if_index);
5440   mp->is_add = is_add;
5441   mp->del_all = del_all;
5442   if (v6_address_set)
5443     {
5444       mp->is_ipv6 = 1;
5445       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5446     }
5447   else
5448     {
5449       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5450     }
5451   mp->address_length = address_length;
5452
5453   /* send it... */
5454   S (mp);
5455
5456   /* Wait for a reply, return good/bad news  */
5457   W (ret);
5458   return ret;
5459 }
5460
5461 static int
5462 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5463 {
5464   unformat_input_t *i = vam->input;
5465   vl_api_sw_interface_set_mpls_enable_t *mp;
5466   u32 sw_if_index;
5467   u8 sw_if_index_set = 0;
5468   u8 enable = 1;
5469   int ret;
5470
5471   /* Parse args required to build the message */
5472   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5473     {
5474       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5475         sw_if_index_set = 1;
5476       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5477         sw_if_index_set = 1;
5478       else if (unformat (i, "disable"))
5479         enable = 0;
5480       else if (unformat (i, "dis"))
5481         enable = 0;
5482       else
5483         break;
5484     }
5485
5486   if (sw_if_index_set == 0)
5487     {
5488       errmsg ("missing interface name or sw_if_index");
5489       return -99;
5490     }
5491
5492   /* Construct the API message */
5493   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
5494
5495   mp->sw_if_index = ntohl (sw_if_index);
5496   mp->enable = enable;
5497
5498   /* send it... */
5499   S (mp);
5500
5501   /* Wait for a reply... */
5502   W (ret);
5503   return ret;
5504 }
5505
5506 static int
5507 api_sw_interface_set_table (vat_main_t * vam)
5508 {
5509   unformat_input_t *i = vam->input;
5510   vl_api_sw_interface_set_table_t *mp;
5511   u32 sw_if_index, vrf_id = 0;
5512   u8 sw_if_index_set = 0;
5513   u8 is_ipv6 = 0;
5514   int ret;
5515
5516   /* Parse args required to build the message */
5517   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5518     {
5519       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5520         sw_if_index_set = 1;
5521       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5522         sw_if_index_set = 1;
5523       else if (unformat (i, "vrf %d", &vrf_id))
5524         ;
5525       else if (unformat (i, "ipv6"))
5526         is_ipv6 = 1;
5527       else
5528         break;
5529     }
5530
5531   if (sw_if_index_set == 0)
5532     {
5533       errmsg ("missing interface name or sw_if_index");
5534       return -99;
5535     }
5536
5537   /* Construct the API message */
5538   M (SW_INTERFACE_SET_TABLE, mp);
5539
5540   mp->sw_if_index = ntohl (sw_if_index);
5541   mp->is_ipv6 = is_ipv6;
5542   mp->vrf_id = ntohl (vrf_id);
5543
5544   /* send it... */
5545   S (mp);
5546
5547   /* Wait for a reply... */
5548   W (ret);
5549   return ret;
5550 }
5551
5552 static void vl_api_sw_interface_get_table_reply_t_handler
5553   (vl_api_sw_interface_get_table_reply_t * mp)
5554 {
5555   vat_main_t *vam = &vat_main;
5556
5557   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5558
5559   vam->retval = ntohl (mp->retval);
5560   vam->result_ready = 1;
5561
5562 }
5563
5564 static void vl_api_sw_interface_get_table_reply_t_handler_json
5565   (vl_api_sw_interface_get_table_reply_t * mp)
5566 {
5567   vat_main_t *vam = &vat_main;
5568   vat_json_node_t node;
5569
5570   vat_json_init_object (&node);
5571   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5572   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5573
5574   vat_json_print (vam->ofp, &node);
5575   vat_json_free (&node);
5576
5577   vam->retval = ntohl (mp->retval);
5578   vam->result_ready = 1;
5579 }
5580
5581 static int
5582 api_sw_interface_get_table (vat_main_t * vam)
5583 {
5584   unformat_input_t *i = vam->input;
5585   vl_api_sw_interface_get_table_t *mp;
5586   u32 sw_if_index;
5587   u8 sw_if_index_set = 0;
5588   u8 is_ipv6 = 0;
5589   int ret;
5590
5591   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5592     {
5593       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5594         sw_if_index_set = 1;
5595       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5596         sw_if_index_set = 1;
5597       else if (unformat (i, "ipv6"))
5598         is_ipv6 = 1;
5599       else
5600         break;
5601     }
5602
5603   if (sw_if_index_set == 0)
5604     {
5605       errmsg ("missing interface name or sw_if_index");
5606       return -99;
5607     }
5608
5609   M (SW_INTERFACE_GET_TABLE, mp);
5610   mp->sw_if_index = htonl (sw_if_index);
5611   mp->is_ipv6 = is_ipv6;
5612
5613   S (mp);
5614   W (ret);
5615   return ret;
5616 }
5617
5618 static int
5619 api_sw_interface_set_vpath (vat_main_t * vam)
5620 {
5621   unformat_input_t *i = vam->input;
5622   vl_api_sw_interface_set_vpath_t *mp;
5623   u32 sw_if_index = 0;
5624   u8 sw_if_index_set = 0;
5625   u8 is_enable = 0;
5626   int ret;
5627
5628   /* Parse args required to build the message */
5629   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5630     {
5631       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5632         sw_if_index_set = 1;
5633       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5634         sw_if_index_set = 1;
5635       else if (unformat (i, "enable"))
5636         is_enable = 1;
5637       else if (unformat (i, "disable"))
5638         is_enable = 0;
5639       else
5640         break;
5641     }
5642
5643   if (sw_if_index_set == 0)
5644     {
5645       errmsg ("missing interface name or sw_if_index");
5646       return -99;
5647     }
5648
5649   /* Construct the API message */
5650   M (SW_INTERFACE_SET_VPATH, mp);
5651
5652   mp->sw_if_index = ntohl (sw_if_index);
5653   mp->enable = is_enable;
5654
5655   /* send it... */
5656   S (mp);
5657
5658   /* Wait for a reply... */
5659   W (ret);
5660   return ret;
5661 }
5662
5663 static int
5664 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5665 {
5666   unformat_input_t *i = vam->input;
5667   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5668   u32 sw_if_index = 0;
5669   u8 sw_if_index_set = 0;
5670   u8 is_enable = 1;
5671   u8 is_ipv6 = 0;
5672   int ret;
5673
5674   /* Parse args required to build the message */
5675   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5676     {
5677       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5678         sw_if_index_set = 1;
5679       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5680         sw_if_index_set = 1;
5681       else if (unformat (i, "enable"))
5682         is_enable = 1;
5683       else if (unformat (i, "disable"))
5684         is_enable = 0;
5685       else if (unformat (i, "ip4"))
5686         is_ipv6 = 0;
5687       else if (unformat (i, "ip6"))
5688         is_ipv6 = 1;
5689       else
5690         break;
5691     }
5692
5693   if (sw_if_index_set == 0)
5694     {
5695       errmsg ("missing interface name or sw_if_index");
5696       return -99;
5697     }
5698
5699   /* Construct the API message */
5700   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
5701
5702   mp->sw_if_index = ntohl (sw_if_index);
5703   mp->enable = is_enable;
5704   mp->is_ipv6 = is_ipv6;
5705
5706   /* send it... */
5707   S (mp);
5708
5709   /* Wait for a reply... */
5710   W (ret);
5711   return ret;
5712 }
5713
5714 static int
5715 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5716 {
5717   unformat_input_t *i = vam->input;
5718   vl_api_sw_interface_set_l2_xconnect_t *mp;
5719   u32 rx_sw_if_index;
5720   u8 rx_sw_if_index_set = 0;
5721   u32 tx_sw_if_index;
5722   u8 tx_sw_if_index_set = 0;
5723   u8 enable = 1;
5724   int ret;
5725
5726   /* Parse args required to build the message */
5727   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5728     {
5729       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5730         rx_sw_if_index_set = 1;
5731       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5732         tx_sw_if_index_set = 1;
5733       else if (unformat (i, "rx"))
5734         {
5735           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5736             {
5737               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5738                             &rx_sw_if_index))
5739                 rx_sw_if_index_set = 1;
5740             }
5741           else
5742             break;
5743         }
5744       else if (unformat (i, "tx"))
5745         {
5746           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5747             {
5748               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5749                             &tx_sw_if_index))
5750                 tx_sw_if_index_set = 1;
5751             }
5752           else
5753             break;
5754         }
5755       else if (unformat (i, "enable"))
5756         enable = 1;
5757       else if (unformat (i, "disable"))
5758         enable = 0;
5759       else
5760         break;
5761     }
5762
5763   if (rx_sw_if_index_set == 0)
5764     {
5765       errmsg ("missing rx interface name or rx_sw_if_index");
5766       return -99;
5767     }
5768
5769   if (enable && (tx_sw_if_index_set == 0))
5770     {
5771       errmsg ("missing tx interface name or tx_sw_if_index");
5772       return -99;
5773     }
5774
5775   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
5776
5777   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5778   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5779   mp->enable = enable;
5780
5781   S (mp);
5782   W (ret);
5783   return ret;
5784 }
5785
5786 static int
5787 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5788 {
5789   unformat_input_t *i = vam->input;
5790   vl_api_sw_interface_set_l2_bridge_t *mp;
5791   u32 rx_sw_if_index;
5792   u8 rx_sw_if_index_set = 0;
5793   u32 bd_id;
5794   u8 bd_id_set = 0;
5795   u8 bvi = 0;
5796   u32 shg = 0;
5797   u8 enable = 1;
5798   int ret;
5799
5800   /* Parse args required to build the message */
5801   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5802     {
5803       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5804         rx_sw_if_index_set = 1;
5805       else if (unformat (i, "bd_id %d", &bd_id))
5806         bd_id_set = 1;
5807       else
5808         if (unformat
5809             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5810         rx_sw_if_index_set = 1;
5811       else if (unformat (i, "shg %d", &shg))
5812         ;
5813       else if (unformat (i, "bvi"))
5814         bvi = 1;
5815       else if (unformat (i, "enable"))
5816         enable = 1;
5817       else if (unformat (i, "disable"))
5818         enable = 0;
5819       else
5820         break;
5821     }
5822
5823   if (rx_sw_if_index_set == 0)
5824     {
5825       errmsg ("missing rx interface name or sw_if_index");
5826       return -99;
5827     }
5828
5829   if (enable && (bd_id_set == 0))
5830     {
5831       errmsg ("missing bridge domain");
5832       return -99;
5833     }
5834
5835   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
5836
5837   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5838   mp->bd_id = ntohl (bd_id);
5839   mp->shg = (u8) shg;
5840   mp->bvi = bvi;
5841   mp->enable = enable;
5842
5843   S (mp);
5844   W (ret);
5845   return ret;
5846 }
5847
5848 static int
5849 api_bridge_domain_dump (vat_main_t * vam)
5850 {
5851   unformat_input_t *i = vam->input;
5852   vl_api_bridge_domain_dump_t *mp;
5853   vl_api_control_ping_t *mp_ping;
5854   u32 bd_id = ~0;
5855   int ret;
5856
5857   /* Parse args required to build the message */
5858   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5859     {
5860       if (unformat (i, "bd_id %d", &bd_id))
5861         ;
5862       else
5863         break;
5864     }
5865
5866   M (BRIDGE_DOMAIN_DUMP, mp);
5867   mp->bd_id = ntohl (bd_id);
5868   S (mp);
5869
5870   /* Use a control ping for synchronization */
5871   M (CONTROL_PING, mp_ping);
5872   S (mp_ping);
5873
5874   W (ret);
5875   return ret;
5876 }
5877
5878 static int
5879 api_bridge_domain_add_del (vat_main_t * vam)
5880 {
5881   unformat_input_t *i = vam->input;
5882   vl_api_bridge_domain_add_del_t *mp;
5883   u32 bd_id = ~0;
5884   u8 is_add = 1;
5885   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5886   u32 mac_age = 0;
5887   int ret;
5888
5889   /* Parse args required to build the message */
5890   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5891     {
5892       if (unformat (i, "bd_id %d", &bd_id))
5893         ;
5894       else if (unformat (i, "flood %d", &flood))
5895         ;
5896       else if (unformat (i, "uu-flood %d", &uu_flood))
5897         ;
5898       else if (unformat (i, "forward %d", &forward))
5899         ;
5900       else if (unformat (i, "learn %d", &learn))
5901         ;
5902       else if (unformat (i, "arp-term %d", &arp_term))
5903         ;
5904       else if (unformat (i, "mac-age %d", &mac_age))
5905         ;
5906       else if (unformat (i, "del"))
5907         {
5908           is_add = 0;
5909           flood = uu_flood = forward = learn = 0;
5910         }
5911       else
5912         break;
5913     }
5914
5915   if (bd_id == ~0)
5916     {
5917       errmsg ("missing bridge domain");
5918       return -99;
5919     }
5920
5921   if (mac_age > 255)
5922     {
5923       errmsg ("mac age must be less than 256 ");
5924       return -99;
5925     }
5926
5927   M (BRIDGE_DOMAIN_ADD_DEL, mp);
5928
5929   mp->bd_id = ntohl (bd_id);
5930   mp->flood = flood;
5931   mp->uu_flood = uu_flood;
5932   mp->forward = forward;
5933   mp->learn = learn;
5934   mp->arp_term = arp_term;
5935   mp->is_add = is_add;
5936   mp->mac_age = (u8) mac_age;
5937
5938   S (mp);
5939   W (ret);
5940   return ret;
5941 }
5942
5943 static int
5944 api_l2fib_flush_bd (vat_main_t * vam)
5945 {
5946   unformat_input_t *i = vam->input;
5947   vl_api_l2fib_flush_bd_t *mp;
5948   u32 bd_id = ~0;
5949   int ret;
5950
5951   /* Parse args required to build the message */
5952   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5953     {
5954       if (unformat (i, "bd_id %d", &bd_id));
5955       else
5956         break;
5957     }
5958
5959   if (bd_id == ~0)
5960     {
5961       errmsg ("missing bridge domain");
5962       return -99;
5963     }
5964
5965   M (L2FIB_FLUSH_BD, mp);
5966
5967   mp->bd_id = htonl (bd_id);
5968
5969   S (mp);
5970   W (ret);
5971   return ret;
5972 }
5973
5974 static int
5975 api_l2fib_flush_int (vat_main_t * vam)
5976 {
5977   unformat_input_t *i = vam->input;
5978   vl_api_l2fib_flush_int_t *mp;
5979   u32 sw_if_index = ~0;
5980   int ret;
5981
5982   /* Parse args required to build the message */
5983   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5984     {
5985       if (unformat (i, "sw_if_index %d", &sw_if_index));
5986       else
5987         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
5988       else
5989         break;
5990     }
5991
5992   if (sw_if_index == ~0)
5993     {
5994       errmsg ("missing interface name or sw_if_index");
5995       return -99;
5996     }
5997
5998   M (L2FIB_FLUSH_INT, mp);
5999
6000   mp->sw_if_index = ntohl (sw_if_index);
6001
6002   S (mp);
6003   W (ret);
6004   return ret;
6005 }
6006
6007 static int
6008 api_l2fib_add_del (vat_main_t * vam)
6009 {
6010   unformat_input_t *i = vam->input;
6011   vl_api_l2fib_add_del_t *mp;
6012   f64 timeout;
6013   u64 mac = 0;
6014   u8 mac_set = 0;
6015   u32 bd_id;
6016   u8 bd_id_set = 0;
6017   u32 sw_if_index = ~0;
6018   u8 sw_if_index_set = 0;
6019   u8 is_add = 1;
6020   u8 static_mac = 0;
6021   u8 filter_mac = 0;
6022   u8 bvi_mac = 0;
6023   int count = 1;
6024   f64 before = 0;
6025   int j;
6026
6027   /* Parse args required to build the message */
6028   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6029     {
6030       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
6031         mac_set = 1;
6032       else if (unformat (i, "bd_id %d", &bd_id))
6033         bd_id_set = 1;
6034       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6035         sw_if_index_set = 1;
6036       else if (unformat (i, "sw_if"))
6037         {
6038           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6039             {
6040               if (unformat
6041                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6042                 sw_if_index_set = 1;
6043             }
6044           else
6045             break;
6046         }
6047       else if (unformat (i, "static"))
6048         static_mac = 1;
6049       else if (unformat (i, "filter"))
6050         {
6051           filter_mac = 1;
6052           static_mac = 1;
6053         }
6054       else if (unformat (i, "bvi"))
6055         {
6056           bvi_mac = 1;
6057           static_mac = 1;
6058         }
6059       else if (unformat (i, "del"))
6060         is_add = 0;
6061       else if (unformat (i, "count %d", &count))
6062         ;
6063       else
6064         break;
6065     }
6066
6067   if (mac_set == 0)
6068     {
6069       errmsg ("missing mac address");
6070       return -99;
6071     }
6072
6073   if (bd_id_set == 0)
6074     {
6075       errmsg ("missing bridge domain");
6076       return -99;
6077     }
6078
6079   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6080     {
6081       errmsg ("missing interface name or sw_if_index");
6082       return -99;
6083     }
6084
6085   if (count > 1)
6086     {
6087       /* Turn on async mode */
6088       vam->async_mode = 1;
6089       vam->async_errors = 0;
6090       before = vat_time_now (vam);
6091     }
6092
6093   for (j = 0; j < count; j++)
6094     {
6095       M (L2FIB_ADD_DEL, mp);
6096
6097       mp->mac = mac;
6098       mp->bd_id = ntohl (bd_id);
6099       mp->is_add = is_add;
6100
6101       if (is_add)
6102         {
6103           mp->sw_if_index = ntohl (sw_if_index);
6104           mp->static_mac = static_mac;
6105           mp->filter_mac = filter_mac;
6106           mp->bvi_mac = bvi_mac;
6107         }
6108       increment_mac_address (&mac);
6109       /* send it... */
6110       S (mp);
6111     }
6112
6113   if (count > 1)
6114     {
6115       vl_api_control_ping_t *mp_ping;
6116       f64 after;
6117
6118       /* Shut off async mode */
6119       vam->async_mode = 0;
6120
6121       M (CONTROL_PING, mp_ping);
6122       S (mp_ping);
6123
6124       timeout = vat_time_now (vam) + 1.0;
6125       while (vat_time_now (vam) < timeout)
6126         if (vam->result_ready == 1)
6127           goto out;
6128       vam->retval = -99;
6129
6130     out:
6131       if (vam->retval == -99)
6132         errmsg ("timeout");
6133
6134       if (vam->async_errors > 0)
6135         {
6136           errmsg ("%d asynchronous errors", vam->async_errors);
6137           vam->retval = -98;
6138         }
6139       vam->async_errors = 0;
6140       after = vat_time_now (vam);
6141
6142       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6143              count, after - before, count / (after - before));
6144     }
6145   else
6146     {
6147       int ret;
6148
6149       /* Wait for a reply... */
6150       W (ret);
6151       return ret;
6152     }
6153   /* Return the good/bad news */
6154   return (vam->retval);
6155 }
6156
6157 static int
6158 api_bridge_domain_set_mac_age (vat_main_t * vam)
6159 {
6160   unformat_input_t *i = vam->input;
6161   vl_api_bridge_domain_set_mac_age_t *mp;
6162   u32 bd_id = ~0;
6163   u32 mac_age = 0;
6164   int ret;
6165
6166   /* Parse args required to build the message */
6167   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6168     {
6169       if (unformat (i, "bd_id %d", &bd_id));
6170       else if (unformat (i, "mac-age %d", &mac_age));
6171       else
6172         break;
6173     }
6174
6175   if (bd_id == ~0)
6176     {
6177       errmsg ("missing bridge domain");
6178       return -99;
6179     }
6180
6181   if (mac_age > 255)
6182     {
6183       errmsg ("mac age must be less than 256 ");
6184       return -99;
6185     }
6186
6187   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6188
6189   mp->bd_id = htonl (bd_id);
6190   mp->mac_age = (u8) mac_age;
6191
6192   S (mp);
6193   W (ret);
6194   return ret;
6195 }
6196
6197 static int
6198 api_l2_flags (vat_main_t * vam)
6199 {
6200   unformat_input_t *i = vam->input;
6201   vl_api_l2_flags_t *mp;
6202   u32 sw_if_index;
6203   u32 feature_bitmap = 0;
6204   u8 sw_if_index_set = 0;
6205   int ret;
6206
6207   /* Parse args required to build the message */
6208   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6209     {
6210       if (unformat (i, "sw_if_index %d", &sw_if_index))
6211         sw_if_index_set = 1;
6212       else if (unformat (i, "sw_if"))
6213         {
6214           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6215             {
6216               if (unformat
6217                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6218                 sw_if_index_set = 1;
6219             }
6220           else
6221             break;
6222         }
6223       else if (unformat (i, "learn"))
6224         feature_bitmap |= L2INPUT_FEAT_LEARN;
6225       else if (unformat (i, "forward"))
6226         feature_bitmap |= L2INPUT_FEAT_FWD;
6227       else if (unformat (i, "flood"))
6228         feature_bitmap |= L2INPUT_FEAT_FLOOD;
6229       else if (unformat (i, "uu-flood"))
6230         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
6231       else
6232         break;
6233     }
6234
6235   if (sw_if_index_set == 0)
6236     {
6237       errmsg ("missing interface name or sw_if_index");
6238       return -99;
6239     }
6240
6241   M (L2_FLAGS, mp);
6242
6243   mp->sw_if_index = ntohl (sw_if_index);
6244   mp->feature_bitmap = ntohl (feature_bitmap);
6245
6246   S (mp);
6247   W (ret);
6248   return ret;
6249 }
6250
6251 static int
6252 api_bridge_flags (vat_main_t * vam)
6253 {
6254   unformat_input_t *i = vam->input;
6255   vl_api_bridge_flags_t *mp;
6256   u32 bd_id;
6257   u8 bd_id_set = 0;
6258   u8 is_set = 1;
6259   u32 flags = 0;
6260   int ret;
6261
6262   /* Parse args required to build the message */
6263   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6264     {
6265       if (unformat (i, "bd_id %d", &bd_id))
6266         bd_id_set = 1;
6267       else if (unformat (i, "learn"))
6268         flags |= L2_LEARN;
6269       else if (unformat (i, "forward"))
6270         flags |= L2_FWD;
6271       else if (unformat (i, "flood"))
6272         flags |= L2_FLOOD;
6273       else if (unformat (i, "uu-flood"))
6274         flags |= L2_UU_FLOOD;
6275       else if (unformat (i, "arp-term"))
6276         flags |= L2_ARP_TERM;
6277       else if (unformat (i, "off"))
6278         is_set = 0;
6279       else if (unformat (i, "disable"))
6280         is_set = 0;
6281       else
6282         break;
6283     }
6284
6285   if (bd_id_set == 0)
6286     {
6287       errmsg ("missing bridge domain");
6288       return -99;
6289     }
6290
6291   M (BRIDGE_FLAGS, mp);
6292
6293   mp->bd_id = ntohl (bd_id);
6294   mp->feature_bitmap = ntohl (flags);
6295   mp->is_set = is_set;
6296
6297   S (mp);
6298   W (ret);
6299   return ret;
6300 }
6301
6302 static int
6303 api_bd_ip_mac_add_del (vat_main_t * vam)
6304 {
6305   unformat_input_t *i = vam->input;
6306   vl_api_bd_ip_mac_add_del_t *mp;
6307   u32 bd_id;
6308   u8 is_ipv6 = 0;
6309   u8 is_add = 1;
6310   u8 bd_id_set = 0;
6311   u8 ip_set = 0;
6312   u8 mac_set = 0;
6313   ip4_address_t v4addr;
6314   ip6_address_t v6addr;
6315   u8 macaddr[6];
6316   int ret;
6317
6318
6319   /* Parse args required to build the message */
6320   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6321     {
6322       if (unformat (i, "bd_id %d", &bd_id))
6323         {
6324           bd_id_set++;
6325         }
6326       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
6327         {
6328           ip_set++;
6329         }
6330       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
6331         {
6332           ip_set++;
6333           is_ipv6++;
6334         }
6335       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
6336         {
6337           mac_set++;
6338         }
6339       else if (unformat (i, "del"))
6340         is_add = 0;
6341       else
6342         break;
6343     }
6344
6345   if (bd_id_set == 0)
6346     {
6347       errmsg ("missing bridge domain");
6348       return -99;
6349     }
6350   else if (ip_set == 0)
6351     {
6352       errmsg ("missing IP address");
6353       return -99;
6354     }
6355   else if (mac_set == 0)
6356     {
6357       errmsg ("missing MAC address");
6358       return -99;
6359     }
6360
6361   M (BD_IP_MAC_ADD_DEL, mp);
6362
6363   mp->bd_id = ntohl (bd_id);
6364   mp->is_ipv6 = is_ipv6;
6365   mp->is_add = is_add;
6366   if (is_ipv6)
6367     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
6368   else
6369     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
6370   clib_memcpy (mp->mac_address, macaddr, 6);
6371   S (mp);
6372   W (ret);
6373   return ret;
6374 }
6375
6376 static int
6377 api_tap_connect (vat_main_t * vam)
6378 {
6379   unformat_input_t *i = vam->input;
6380   vl_api_tap_connect_t *mp;
6381   u8 mac_address[6];
6382   u8 random_mac = 1;
6383   u8 name_set = 0;
6384   u8 *tap_name;
6385   u8 *tag = 0;
6386   ip4_address_t ip4_address;
6387   u32 ip4_mask_width;
6388   int ip4_address_set = 0;
6389   ip6_address_t ip6_address;
6390   u32 ip6_mask_width;
6391   int ip6_address_set = 0;
6392   int ret;
6393
6394   memset (mac_address, 0, sizeof (mac_address));
6395
6396   /* Parse args required to build the message */
6397   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6398     {
6399       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6400         {
6401           random_mac = 0;
6402         }
6403       else if (unformat (i, "random-mac"))
6404         random_mac = 1;
6405       else if (unformat (i, "tapname %s", &tap_name))
6406         name_set = 1;
6407       else if (unformat (i, "tag %s", &tag))
6408         ;
6409       else if (unformat (i, "address %U/%d",
6410                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
6411         ip4_address_set = 1;
6412       else if (unformat (i, "address %U/%d",
6413                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
6414         ip6_address_set = 1;
6415       else
6416         break;
6417     }
6418
6419   if (name_set == 0)
6420     {
6421       errmsg ("missing tap name");
6422       return -99;
6423     }
6424   if (vec_len (tap_name) > 63)
6425     {
6426       errmsg ("tap name too long");
6427       return -99;
6428     }
6429   vec_add1 (tap_name, 0);
6430
6431   if (vec_len (tag) > 63)
6432     {
6433       errmsg ("tag too long");
6434       return -99;
6435     }
6436
6437   /* Construct the API message */
6438   M (TAP_CONNECT, mp);
6439
6440   mp->use_random_mac = random_mac;
6441   clib_memcpy (mp->mac_address, mac_address, 6);
6442   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6443   if (tag)
6444     clib_memcpy (mp->tag, tag, vec_len (tag));
6445
6446   if (ip4_address_set)
6447     {
6448       mp->ip4_address_set = 1;
6449       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6450       mp->ip4_mask_width = ip4_mask_width;
6451     }
6452   if (ip6_address_set)
6453     {
6454       mp->ip6_address_set = 1;
6455       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6456       mp->ip6_mask_width = ip6_mask_width;
6457     }
6458
6459   vec_free (tap_name);
6460   vec_free (tag);
6461
6462   /* send it... */
6463   S (mp);
6464
6465   /* Wait for a reply... */
6466   W (ret);
6467   return ret;
6468 }
6469
6470 static int
6471 api_tap_modify (vat_main_t * vam)
6472 {
6473   unformat_input_t *i = vam->input;
6474   vl_api_tap_modify_t *mp;
6475   u8 mac_address[6];
6476   u8 random_mac = 1;
6477   u8 name_set = 0;
6478   u8 *tap_name;
6479   u32 sw_if_index = ~0;
6480   u8 sw_if_index_set = 0;
6481   int ret;
6482
6483   memset (mac_address, 0, sizeof (mac_address));
6484
6485   /* Parse args required to build the message */
6486   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6487     {
6488       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6489         sw_if_index_set = 1;
6490       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6491         sw_if_index_set = 1;
6492       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6493         {
6494           random_mac = 0;
6495         }
6496       else if (unformat (i, "random-mac"))
6497         random_mac = 1;
6498       else if (unformat (i, "tapname %s", &tap_name))
6499         name_set = 1;
6500       else
6501         break;
6502     }
6503
6504   if (sw_if_index_set == 0)
6505     {
6506       errmsg ("missing vpp interface name");
6507       return -99;
6508     }
6509   if (name_set == 0)
6510     {
6511       errmsg ("missing tap name");
6512       return -99;
6513     }
6514   if (vec_len (tap_name) > 63)
6515     {
6516       errmsg ("tap name too long");
6517     }
6518   vec_add1 (tap_name, 0);
6519
6520   /* Construct the API message */
6521   M (TAP_MODIFY, mp);
6522
6523   mp->use_random_mac = random_mac;
6524   mp->sw_if_index = ntohl (sw_if_index);
6525   clib_memcpy (mp->mac_address, mac_address, 6);
6526   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6527   vec_free (tap_name);
6528
6529   /* send it... */
6530   S (mp);
6531
6532   /* Wait for a reply... */
6533   W (ret);
6534   return ret;
6535 }
6536
6537 static int
6538 api_tap_delete (vat_main_t * vam)
6539 {
6540   unformat_input_t *i = vam->input;
6541   vl_api_tap_delete_t *mp;
6542   u32 sw_if_index = ~0;
6543   u8 sw_if_index_set = 0;
6544   int ret;
6545
6546   /* Parse args required to build the message */
6547   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6548     {
6549       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6550         sw_if_index_set = 1;
6551       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6552         sw_if_index_set = 1;
6553       else
6554         break;
6555     }
6556
6557   if (sw_if_index_set == 0)
6558     {
6559       errmsg ("missing vpp interface name");
6560       return -99;
6561     }
6562
6563   /* Construct the API message */
6564   M (TAP_DELETE, mp);
6565
6566   mp->sw_if_index = ntohl (sw_if_index);
6567
6568   /* send it... */
6569   S (mp);
6570
6571   /* Wait for a reply... */
6572   W (ret);
6573   return ret;
6574 }
6575
6576 static int
6577 api_ip_add_del_route (vat_main_t * vam)
6578 {
6579   unformat_input_t *i = vam->input;
6580   vl_api_ip_add_del_route_t *mp;
6581   u32 sw_if_index = ~0, vrf_id = 0;
6582   u8 is_ipv6 = 0;
6583   u8 is_local = 0, is_drop = 0;
6584   u8 is_unreach = 0, is_prohibit = 0;
6585   u8 create_vrf_if_needed = 0;
6586   u8 is_add = 1;
6587   u32 next_hop_weight = 1;
6588   u8 not_last = 0;
6589   u8 is_multipath = 0;
6590   u8 address_set = 0;
6591   u8 address_length_set = 0;
6592   u32 next_hop_table_id = 0;
6593   u32 resolve_attempts = 0;
6594   u32 dst_address_length = 0;
6595   u8 next_hop_set = 0;
6596   ip4_address_t v4_dst_address, v4_next_hop_address;
6597   ip6_address_t v6_dst_address, v6_next_hop_address;
6598   int count = 1;
6599   int j;
6600   f64 before = 0;
6601   u32 random_add_del = 0;
6602   u32 *random_vector = 0;
6603   uword *random_hash;
6604   u32 random_seed = 0xdeaddabe;
6605   u32 classify_table_index = ~0;
6606   u8 is_classify = 0;
6607   u8 resolve_host = 0, resolve_attached = 0;
6608   mpls_label_t *next_hop_out_label_stack = NULL;
6609   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6610   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6611
6612   /* Parse args required to build the message */
6613   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6614     {
6615       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6616         ;
6617       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6618         ;
6619       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6620         {
6621           address_set = 1;
6622           is_ipv6 = 0;
6623         }
6624       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6625         {
6626           address_set = 1;
6627           is_ipv6 = 1;
6628         }
6629       else if (unformat (i, "/%d", &dst_address_length))
6630         {
6631           address_length_set = 1;
6632         }
6633
6634       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6635                                          &v4_next_hop_address))
6636         {
6637           next_hop_set = 1;
6638         }
6639       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6640                                          &v6_next_hop_address))
6641         {
6642           next_hop_set = 1;
6643         }
6644       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6645         ;
6646       else if (unformat (i, "weight %d", &next_hop_weight))
6647         ;
6648       else if (unformat (i, "drop"))
6649         {
6650           is_drop = 1;
6651         }
6652       else if (unformat (i, "null-send-unreach"))
6653         {
6654           is_unreach = 1;
6655         }
6656       else if (unformat (i, "null-send-prohibit"))
6657         {
6658           is_prohibit = 1;
6659         }
6660       else if (unformat (i, "local"))
6661         {
6662           is_local = 1;
6663         }
6664       else if (unformat (i, "classify %d", &classify_table_index))
6665         {
6666           is_classify = 1;
6667         }
6668       else if (unformat (i, "del"))
6669         is_add = 0;
6670       else if (unformat (i, "add"))
6671         is_add = 1;
6672       else if (unformat (i, "not-last"))
6673         not_last = 1;
6674       else if (unformat (i, "resolve-via-host"))
6675         resolve_host = 1;
6676       else if (unformat (i, "resolve-via-attached"))
6677         resolve_attached = 1;
6678       else if (unformat (i, "multipath"))
6679         is_multipath = 1;
6680       else if (unformat (i, "vrf %d", &vrf_id))
6681         ;
6682       else if (unformat (i, "create-vrf"))
6683         create_vrf_if_needed = 1;
6684       else if (unformat (i, "count %d", &count))
6685         ;
6686       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6687         ;
6688       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6689         ;
6690       else if (unformat (i, "out-label %d", &next_hop_out_label))
6691         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6692       else if (unformat (i, "via-label %d", &next_hop_via_label))
6693         ;
6694       else if (unformat (i, "random"))
6695         random_add_del = 1;
6696       else if (unformat (i, "seed %d", &random_seed))
6697         ;
6698       else
6699         {
6700           clib_warning ("parse error '%U'", format_unformat_error, i);
6701           return -99;
6702         }
6703     }
6704
6705   if (!next_hop_set && !is_drop && !is_local &&
6706       !is_classify && !is_unreach && !is_prohibit &&
6707       MPLS_LABEL_INVALID == next_hop_via_label)
6708     {
6709       errmsg
6710         ("next hop / local / drop / unreach / prohibit / classify not set");
6711       return -99;
6712     }
6713
6714   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6715     {
6716       errmsg ("next hop and next-hop via label set");
6717       return -99;
6718     }
6719   if (address_set == 0)
6720     {
6721       errmsg ("missing addresses");
6722       return -99;
6723     }
6724
6725   if (address_length_set == 0)
6726     {
6727       errmsg ("missing address length");
6728       return -99;
6729     }
6730
6731   /* Generate a pile of unique, random routes */
6732   if (random_add_del)
6733     {
6734       u32 this_random_address;
6735       random_hash = hash_create (count, sizeof (uword));
6736
6737       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6738       for (j = 0; j <= count; j++)
6739         {
6740           do
6741             {
6742               this_random_address = random_u32 (&random_seed);
6743               this_random_address =
6744                 clib_host_to_net_u32 (this_random_address);
6745             }
6746           while (hash_get (random_hash, this_random_address));
6747           vec_add1 (random_vector, this_random_address);
6748           hash_set (random_hash, this_random_address, 1);
6749         }
6750       hash_free (random_hash);
6751       v4_dst_address.as_u32 = random_vector[0];
6752     }
6753
6754   if (count > 1)
6755     {
6756       /* Turn on async mode */
6757       vam->async_mode = 1;
6758       vam->async_errors = 0;
6759       before = vat_time_now (vam);
6760     }
6761
6762   for (j = 0; j < count; j++)
6763     {
6764       /* Construct the API message */
6765       M2 (IP_ADD_DEL_ROUTE, mp,
6766           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6767
6768       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6769       mp->table_id = ntohl (vrf_id);
6770       mp->create_vrf_if_needed = create_vrf_if_needed;
6771
6772       mp->is_add = is_add;
6773       mp->is_drop = is_drop;
6774       mp->is_unreach = is_unreach;
6775       mp->is_prohibit = is_prohibit;
6776       mp->is_ipv6 = is_ipv6;
6777       mp->is_local = is_local;
6778       mp->is_classify = is_classify;
6779       mp->is_multipath = is_multipath;
6780       mp->is_resolve_host = resolve_host;
6781       mp->is_resolve_attached = resolve_attached;
6782       mp->not_last = not_last;
6783       mp->next_hop_weight = next_hop_weight;
6784       mp->dst_address_length = dst_address_length;
6785       mp->next_hop_table_id = ntohl (next_hop_table_id);
6786       mp->classify_table_index = ntohl (classify_table_index);
6787       mp->next_hop_via_label = ntohl (next_hop_via_label);
6788       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6789       if (0 != mp->next_hop_n_out_labels)
6790         {
6791           memcpy (mp->next_hop_out_label_stack,
6792                   next_hop_out_label_stack,
6793                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6794           vec_free (next_hop_out_label_stack);
6795         }
6796
6797       if (is_ipv6)
6798         {
6799           clib_memcpy (mp->dst_address, &v6_dst_address,
6800                        sizeof (v6_dst_address));
6801           if (next_hop_set)
6802             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6803                          sizeof (v6_next_hop_address));
6804           increment_v6_address (&v6_dst_address);
6805         }
6806       else
6807         {
6808           clib_memcpy (mp->dst_address, &v4_dst_address,
6809                        sizeof (v4_dst_address));
6810           if (next_hop_set)
6811             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6812                          sizeof (v4_next_hop_address));
6813           if (random_add_del)
6814             v4_dst_address.as_u32 = random_vector[j + 1];
6815           else
6816             increment_v4_address (&v4_dst_address);
6817         }
6818       /* send it... */
6819       S (mp);
6820       /* If we receive SIGTERM, stop now... */
6821       if (vam->do_exit)
6822         break;
6823     }
6824
6825   /* When testing multiple add/del ops, use a control-ping to sync */
6826   if (count > 1)
6827     {
6828       vl_api_control_ping_t *mp_ping;
6829       f64 after;
6830       f64 timeout;
6831
6832       /* Shut off async mode */
6833       vam->async_mode = 0;
6834
6835       M (CONTROL_PING, mp_ping);
6836       S (mp_ping);
6837
6838       timeout = vat_time_now (vam) + 1.0;
6839       while (vat_time_now (vam) < timeout)
6840         if (vam->result_ready == 1)
6841           goto out;
6842       vam->retval = -99;
6843
6844     out:
6845       if (vam->retval == -99)
6846         errmsg ("timeout");
6847
6848       if (vam->async_errors > 0)
6849         {
6850           errmsg ("%d asynchronous errors", vam->async_errors);
6851           vam->retval = -98;
6852         }
6853       vam->async_errors = 0;
6854       after = vat_time_now (vam);
6855
6856       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6857       if (j > 0)
6858         count = j;
6859
6860       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6861              count, after - before, count / (after - before));
6862     }
6863   else
6864     {
6865       int ret;
6866
6867       /* Wait for a reply... */
6868       W (ret);
6869       return ret;
6870     }
6871
6872   /* Return the good/bad news */
6873   return (vam->retval);
6874 }
6875
6876 static int
6877 api_ip_mroute_add_del (vat_main_t * vam)
6878 {
6879   unformat_input_t *i = vam->input;
6880   vl_api_ip_mroute_add_del_t *mp;
6881   u32 sw_if_index = ~0, vrf_id = 0;
6882   u8 is_ipv6 = 0;
6883   u8 is_local = 0;
6884   u8 create_vrf_if_needed = 0;
6885   u8 is_add = 1;
6886   u8 address_set = 0;
6887   u32 grp_address_length = 0;
6888   ip4_address_t v4_grp_address, v4_src_address;
6889   ip6_address_t v6_grp_address, v6_src_address;
6890   mfib_itf_flags_t iflags = 0;
6891   mfib_entry_flags_t eflags = 0;
6892   int ret;
6893
6894   /* Parse args required to build the message */
6895   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6896     {
6897       if (unformat (i, "sw_if_index %d", &sw_if_index))
6898         ;
6899       else if (unformat (i, "%U %U",
6900                          unformat_ip4_address, &v4_src_address,
6901                          unformat_ip4_address, &v4_grp_address))
6902         {
6903           grp_address_length = 64;
6904           address_set = 1;
6905           is_ipv6 = 0;
6906         }
6907       else if (unformat (i, "%U %U",
6908                          unformat_ip6_address, &v6_src_address,
6909                          unformat_ip6_address, &v6_grp_address))
6910         {
6911           grp_address_length = 256;
6912           address_set = 1;
6913           is_ipv6 = 1;
6914         }
6915       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
6916         {
6917           memset (&v4_src_address, 0, sizeof (v4_src_address));
6918           grp_address_length = 32;
6919           address_set = 1;
6920           is_ipv6 = 0;
6921         }
6922       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
6923         {
6924           memset (&v6_src_address, 0, sizeof (v6_src_address));
6925           grp_address_length = 128;
6926           address_set = 1;
6927           is_ipv6 = 1;
6928         }
6929       else if (unformat (i, "/%d", &grp_address_length))
6930         ;
6931       else if (unformat (i, "local"))
6932         {
6933           is_local = 1;
6934         }
6935       else if (unformat (i, "del"))
6936         is_add = 0;
6937       else if (unformat (i, "add"))
6938         is_add = 1;
6939       else if (unformat (i, "vrf %d", &vrf_id))
6940         ;
6941       else if (unformat (i, "create-vrf"))
6942         create_vrf_if_needed = 1;
6943       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
6944         ;
6945       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6946         ;
6947       else
6948         {
6949           clib_warning ("parse error '%U'", format_unformat_error, i);
6950           return -99;
6951         }
6952     }
6953
6954   if (address_set == 0)
6955     {
6956       errmsg ("missing addresses\n");
6957       return -99;
6958     }
6959
6960   /* Construct the API message */
6961   M (IP_MROUTE_ADD_DEL, mp);
6962
6963   mp->next_hop_sw_if_index = ntohl (sw_if_index);
6964   mp->table_id = ntohl (vrf_id);
6965   mp->create_vrf_if_needed = create_vrf_if_needed;
6966
6967   mp->is_add = is_add;
6968   mp->is_ipv6 = is_ipv6;
6969   mp->is_local = is_local;
6970   mp->itf_flags = ntohl (iflags);
6971   mp->entry_flags = ntohl (eflags);
6972   mp->grp_address_length = grp_address_length;
6973   mp->grp_address_length = ntohs (mp->grp_address_length);
6974
6975   if (is_ipv6)
6976     {
6977       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
6978       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
6979     }
6980   else
6981     {
6982       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
6983       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
6984
6985     }
6986
6987   /* send it... */
6988   S (mp);
6989   /* Wait for a reply... */
6990   W (ret);
6991   return ret;
6992 }
6993
6994 static int
6995 api_mpls_route_add_del (vat_main_t * vam)
6996 {
6997   unformat_input_t *i = vam->input;
6998   vl_api_mpls_route_add_del_t *mp;
6999   u32 sw_if_index = ~0, table_id = 0;
7000   u8 create_table_if_needed = 0;
7001   u8 is_add = 1;
7002   u32 next_hop_weight = 1;
7003   u8 is_multipath = 0;
7004   u32 next_hop_table_id = 0;
7005   u8 next_hop_set = 0;
7006   ip4_address_t v4_next_hop_address = {
7007     .as_u32 = 0,
7008   };
7009   ip6_address_t v6_next_hop_address = { {0} };
7010   int count = 1;
7011   int j;
7012   f64 before = 0;
7013   u32 classify_table_index = ~0;
7014   u8 is_classify = 0;
7015   u8 resolve_host = 0, resolve_attached = 0;
7016   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7017   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7018   mpls_label_t *next_hop_out_label_stack = NULL;
7019   mpls_label_t local_label = MPLS_LABEL_INVALID;
7020   u8 is_eos = 0;
7021   u8 next_hop_proto_is_ip4 = 1;
7022
7023   /* Parse args required to build the message */
7024   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7025     {
7026       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7027         ;
7028       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7029         ;
7030       else if (unformat (i, "%d", &local_label))
7031         ;
7032       else if (unformat (i, "eos"))
7033         is_eos = 1;
7034       else if (unformat (i, "non-eos"))
7035         is_eos = 0;
7036       else if (unformat (i, "via %U", unformat_ip4_address,
7037                          &v4_next_hop_address))
7038         {
7039           next_hop_set = 1;
7040           next_hop_proto_is_ip4 = 1;
7041         }
7042       else if (unformat (i, "via %U", unformat_ip6_address,
7043                          &v6_next_hop_address))
7044         {
7045           next_hop_set = 1;
7046           next_hop_proto_is_ip4 = 0;
7047         }
7048       else if (unformat (i, "weight %d", &next_hop_weight))
7049         ;
7050       else if (unformat (i, "create-table"))
7051         create_table_if_needed = 1;
7052       else if (unformat (i, "classify %d", &classify_table_index))
7053         {
7054           is_classify = 1;
7055         }
7056       else if (unformat (i, "del"))
7057         is_add = 0;
7058       else if (unformat (i, "add"))
7059         is_add = 1;
7060       else if (unformat (i, "resolve-via-host"))
7061         resolve_host = 1;
7062       else if (unformat (i, "resolve-via-attached"))
7063         resolve_attached = 1;
7064       else if (unformat (i, "multipath"))
7065         is_multipath = 1;
7066       else if (unformat (i, "count %d", &count))
7067         ;
7068       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
7069         {
7070           next_hop_set = 1;
7071           next_hop_proto_is_ip4 = 1;
7072         }
7073       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
7074         {
7075           next_hop_set = 1;
7076           next_hop_proto_is_ip4 = 0;
7077         }
7078       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7079         ;
7080       else if (unformat (i, "via-label %d", &next_hop_via_label))
7081         ;
7082       else if (unformat (i, "out-label %d", &next_hop_out_label))
7083         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7084       else
7085         {
7086           clib_warning ("parse error '%U'", format_unformat_error, i);
7087           return -99;
7088         }
7089     }
7090
7091   if (!next_hop_set && !is_classify)
7092     {
7093       errmsg ("next hop / classify not set");
7094       return -99;
7095     }
7096
7097   if (MPLS_LABEL_INVALID == local_label)
7098     {
7099       errmsg ("missing label");
7100       return -99;
7101     }
7102
7103   if (count > 1)
7104     {
7105       /* Turn on async mode */
7106       vam->async_mode = 1;
7107       vam->async_errors = 0;
7108       before = vat_time_now (vam);
7109     }
7110
7111   for (j = 0; j < count; j++)
7112     {
7113       /* Construct the API message */
7114       M2 (MPLS_ROUTE_ADD_DEL, mp,
7115           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7116
7117       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
7118       mp->mr_table_id = ntohl (table_id);
7119       mp->mr_create_table_if_needed = create_table_if_needed;
7120
7121       mp->mr_is_add = is_add;
7122       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7123       mp->mr_is_classify = is_classify;
7124       mp->mr_is_multipath = is_multipath;
7125       mp->mr_is_resolve_host = resolve_host;
7126       mp->mr_is_resolve_attached = resolve_attached;
7127       mp->mr_next_hop_weight = next_hop_weight;
7128       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
7129       mp->mr_classify_table_index = ntohl (classify_table_index);
7130       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
7131       mp->mr_label = ntohl (local_label);
7132       mp->mr_eos = is_eos;
7133
7134       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7135       if (0 != mp->mr_next_hop_n_out_labels)
7136         {
7137           memcpy (mp->mr_next_hop_out_label_stack,
7138                   next_hop_out_label_stack,
7139                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7140           vec_free (next_hop_out_label_stack);
7141         }
7142
7143       if (next_hop_set)
7144         {
7145           if (next_hop_proto_is_ip4)
7146             {
7147               clib_memcpy (mp->mr_next_hop,
7148                            &v4_next_hop_address,
7149                            sizeof (v4_next_hop_address));
7150             }
7151           else
7152             {
7153               clib_memcpy (mp->mr_next_hop,
7154                            &v6_next_hop_address,
7155                            sizeof (v6_next_hop_address));
7156             }
7157         }
7158       local_label++;
7159
7160       /* send it... */
7161       S (mp);
7162       /* If we receive SIGTERM, stop now... */
7163       if (vam->do_exit)
7164         break;
7165     }
7166
7167   /* When testing multiple add/del ops, use a control-ping to sync */
7168   if (count > 1)
7169     {
7170       vl_api_control_ping_t *mp_ping;
7171       f64 after;
7172       f64 timeout;
7173
7174       /* Shut off async mode */
7175       vam->async_mode = 0;
7176
7177       M (CONTROL_PING, mp_ping);
7178       S (mp_ping);
7179
7180       timeout = vat_time_now (vam) + 1.0;
7181       while (vat_time_now (vam) < timeout)
7182         if (vam->result_ready == 1)
7183           goto out;
7184       vam->retval = -99;
7185
7186     out:
7187       if (vam->retval == -99)
7188         errmsg ("timeout");
7189
7190       if (vam->async_errors > 0)
7191         {
7192           errmsg ("%d asynchronous errors", vam->async_errors);
7193           vam->retval = -98;
7194         }
7195       vam->async_errors = 0;
7196       after = vat_time_now (vam);
7197
7198       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7199       if (j > 0)
7200         count = j;
7201
7202       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7203              count, after - before, count / (after - before));
7204     }
7205   else
7206     {
7207       int ret;
7208
7209       /* Wait for a reply... */
7210       W (ret);
7211       return ret;
7212     }
7213
7214   /* Return the good/bad news */
7215   return (vam->retval);
7216 }
7217
7218 static int
7219 api_mpls_ip_bind_unbind (vat_main_t * vam)
7220 {
7221   unformat_input_t *i = vam->input;
7222   vl_api_mpls_ip_bind_unbind_t *mp;
7223   u32 ip_table_id = 0;
7224   u8 create_table_if_needed = 0;
7225   u8 is_bind = 1;
7226   u8 is_ip4 = 1;
7227   ip4_address_t v4_address;
7228   ip6_address_t v6_address;
7229   u32 address_length;
7230   u8 address_set = 0;
7231   mpls_label_t local_label = MPLS_LABEL_INVALID;
7232   int ret;
7233
7234   /* Parse args required to build the message */
7235   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7236     {
7237       if (unformat (i, "%U/%d", unformat_ip4_address,
7238                     &v4_address, &address_length))
7239         {
7240           is_ip4 = 1;
7241           address_set = 1;
7242         }
7243       else if (unformat (i, "%U/%d", unformat_ip6_address,
7244                          &v6_address, &address_length))
7245         {
7246           is_ip4 = 0;
7247           address_set = 1;
7248         }
7249       else if (unformat (i, "%d", &local_label))
7250         ;
7251       else if (unformat (i, "create-table"))
7252         create_table_if_needed = 1;
7253       else if (unformat (i, "table-id %d", &ip_table_id))
7254         ;
7255       else if (unformat (i, "unbind"))
7256         is_bind = 0;
7257       else if (unformat (i, "bind"))
7258         is_bind = 1;
7259       else
7260         {
7261           clib_warning ("parse error '%U'", format_unformat_error, i);
7262           return -99;
7263         }
7264     }
7265
7266   if (!address_set)
7267     {
7268       errmsg ("IP addres not set");
7269       return -99;
7270     }
7271
7272   if (MPLS_LABEL_INVALID == local_label)
7273     {
7274       errmsg ("missing label");
7275       return -99;
7276     }
7277
7278   /* Construct the API message */
7279   M (MPLS_IP_BIND_UNBIND, mp);
7280
7281   mp->mb_create_table_if_needed = create_table_if_needed;
7282   mp->mb_is_bind = is_bind;
7283   mp->mb_is_ip4 = is_ip4;
7284   mp->mb_ip_table_id = ntohl (ip_table_id);
7285   mp->mb_mpls_table_id = 0;
7286   mp->mb_label = ntohl (local_label);
7287   mp->mb_address_length = address_length;
7288
7289   if (is_ip4)
7290     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
7291   else
7292     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
7293
7294   /* send it... */
7295   S (mp);
7296
7297   /* Wait for a reply... */
7298   W (ret);
7299   return ret;
7300 }
7301
7302 static int
7303 api_proxy_arp_add_del (vat_main_t * vam)
7304 {
7305   unformat_input_t *i = vam->input;
7306   vl_api_proxy_arp_add_del_t *mp;
7307   u32 vrf_id = 0;
7308   u8 is_add = 1;
7309   ip4_address_t lo, hi;
7310   u8 range_set = 0;
7311   int ret;
7312
7313   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7314     {
7315       if (unformat (i, "vrf %d", &vrf_id))
7316         ;
7317       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
7318                          unformat_ip4_address, &hi))
7319         range_set = 1;
7320       else if (unformat (i, "del"))
7321         is_add = 0;
7322       else
7323         {
7324           clib_warning ("parse error '%U'", format_unformat_error, i);
7325           return -99;
7326         }
7327     }
7328
7329   if (range_set == 0)
7330     {
7331       errmsg ("address range not set");
7332       return -99;
7333     }
7334
7335   M (PROXY_ARP_ADD_DEL, mp);
7336
7337   mp->vrf_id = ntohl (vrf_id);
7338   mp->is_add = is_add;
7339   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
7340   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
7341
7342   S (mp);
7343   W (ret);
7344   return ret;
7345 }
7346
7347 static int
7348 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
7349 {
7350   unformat_input_t *i = vam->input;
7351   vl_api_proxy_arp_intfc_enable_disable_t *mp;
7352   u32 sw_if_index;
7353   u8 enable = 1;
7354   u8 sw_if_index_set = 0;
7355   int ret;
7356
7357   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7358     {
7359       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7360         sw_if_index_set = 1;
7361       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7362         sw_if_index_set = 1;
7363       else if (unformat (i, "enable"))
7364         enable = 1;
7365       else if (unformat (i, "disable"))
7366         enable = 0;
7367       else
7368         {
7369           clib_warning ("parse error '%U'", format_unformat_error, i);
7370           return -99;
7371         }
7372     }
7373
7374   if (sw_if_index_set == 0)
7375     {
7376       errmsg ("missing interface name or sw_if_index");
7377       return -99;
7378     }
7379
7380   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
7381
7382   mp->sw_if_index = ntohl (sw_if_index);
7383   mp->enable_disable = enable;
7384
7385   S (mp);
7386   W (ret);
7387   return ret;
7388 }
7389
7390 static int
7391 api_mpls_tunnel_add_del (vat_main_t * vam)
7392 {
7393   unformat_input_t *i = vam->input;
7394   vl_api_mpls_tunnel_add_del_t *mp;
7395
7396   u8 is_add = 1;
7397   u8 l2_only = 0;
7398   u32 sw_if_index = ~0;
7399   u32 next_hop_sw_if_index = ~0;
7400   u32 next_hop_proto_is_ip4 = 1;
7401
7402   u32 next_hop_table_id = 0;
7403   ip4_address_t v4_next_hop_address = {
7404     .as_u32 = 0,
7405   };
7406   ip6_address_t v6_next_hop_address = { {0} };
7407   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
7408   int ret;
7409
7410   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7411     {
7412       if (unformat (i, "add"))
7413         is_add = 1;
7414       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7415         is_add = 0;
7416       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7417         ;
7418       else if (unformat (i, "via %U",
7419                          unformat_ip4_address, &v4_next_hop_address))
7420         {
7421           next_hop_proto_is_ip4 = 1;
7422         }
7423       else if (unformat (i, "via %U",
7424                          unformat_ip6_address, &v6_next_hop_address))
7425         {
7426           next_hop_proto_is_ip4 = 0;
7427         }
7428       else if (unformat (i, "l2-only"))
7429         l2_only = 1;
7430       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7431         ;
7432       else if (unformat (i, "out-label %d", &next_hop_out_label))
7433         vec_add1 (labels, ntohl (next_hop_out_label));
7434       else
7435         {
7436           clib_warning ("parse error '%U'", format_unformat_error, i);
7437           return -99;
7438         }
7439     }
7440
7441   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
7442
7443   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
7444   mp->mt_sw_if_index = ntohl (sw_if_index);
7445   mp->mt_is_add = is_add;
7446   mp->mt_l2_only = l2_only;
7447   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
7448   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7449
7450   mp->mt_next_hop_n_out_labels = vec_len (labels);
7451
7452   if (0 != mp->mt_next_hop_n_out_labels)
7453     {
7454       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7455                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7456       vec_free (labels);
7457     }
7458
7459   if (next_hop_proto_is_ip4)
7460     {
7461       clib_memcpy (mp->mt_next_hop,
7462                    &v4_next_hop_address, sizeof (v4_next_hop_address));
7463     }
7464   else
7465     {
7466       clib_memcpy (mp->mt_next_hop,
7467                    &v6_next_hop_address, sizeof (v6_next_hop_address));
7468     }
7469
7470   S (mp);
7471   W (ret);
7472   return ret;
7473 }
7474
7475 static int
7476 api_sw_interface_set_unnumbered (vat_main_t * vam)
7477 {
7478   unformat_input_t *i = vam->input;
7479   vl_api_sw_interface_set_unnumbered_t *mp;
7480   u32 sw_if_index;
7481   u32 unnum_sw_index = ~0;
7482   u8 is_add = 1;
7483   u8 sw_if_index_set = 0;
7484   int ret;
7485
7486   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7487     {
7488       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7489         sw_if_index_set = 1;
7490       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7491         sw_if_index_set = 1;
7492       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7493         ;
7494       else if (unformat (i, "del"))
7495         is_add = 0;
7496       else
7497         {
7498           clib_warning ("parse error '%U'", format_unformat_error, i);
7499           return -99;
7500         }
7501     }
7502
7503   if (sw_if_index_set == 0)
7504     {
7505       errmsg ("missing interface name or sw_if_index");
7506       return -99;
7507     }
7508
7509   M (SW_INTERFACE_SET_UNNUMBERED, mp);
7510
7511   mp->sw_if_index = ntohl (sw_if_index);
7512   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7513   mp->is_add = is_add;
7514
7515   S (mp);
7516   W (ret);
7517   return ret;
7518 }
7519
7520 static int
7521 api_ip_neighbor_add_del (vat_main_t * vam)
7522 {
7523   unformat_input_t *i = vam->input;
7524   vl_api_ip_neighbor_add_del_t *mp;
7525   u32 sw_if_index;
7526   u8 sw_if_index_set = 0;
7527   u8 is_add = 1;
7528   u8 is_static = 0;
7529   u8 is_no_fib_entry = 0;
7530   u8 mac_address[6];
7531   u8 mac_set = 0;
7532   u8 v4_address_set = 0;
7533   u8 v6_address_set = 0;
7534   ip4_address_t v4address;
7535   ip6_address_t v6address;
7536   int ret;
7537
7538   memset (mac_address, 0, sizeof (mac_address));
7539
7540   /* Parse args required to build the message */
7541   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7542     {
7543       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7544         {
7545           mac_set = 1;
7546         }
7547       else if (unformat (i, "del"))
7548         is_add = 0;
7549       else
7550         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7551         sw_if_index_set = 1;
7552       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7553         sw_if_index_set = 1;
7554       else if (unformat (i, "is_static"))
7555         is_static = 1;
7556       else if (unformat (i, "no-fib-entry"))
7557         is_no_fib_entry = 1;
7558       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
7559         v4_address_set = 1;
7560       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
7561         v6_address_set = 1;
7562       else
7563         {
7564           clib_warning ("parse error '%U'", format_unformat_error, i);
7565           return -99;
7566         }
7567     }
7568
7569   if (sw_if_index_set == 0)
7570     {
7571       errmsg ("missing interface name or sw_if_index");
7572       return -99;
7573     }
7574   if (v4_address_set && v6_address_set)
7575     {
7576       errmsg ("both v4 and v6 addresses set");
7577       return -99;
7578     }
7579   if (!v4_address_set && !v6_address_set)
7580     {
7581       errmsg ("no address set");
7582       return -99;
7583     }
7584
7585   /* Construct the API message */
7586   M (IP_NEIGHBOR_ADD_DEL, mp);
7587
7588   mp->sw_if_index = ntohl (sw_if_index);
7589   mp->is_add = is_add;
7590   mp->is_static = is_static;
7591   mp->is_no_adj_fib = is_no_fib_entry;
7592   if (mac_set)
7593     clib_memcpy (mp->mac_address, mac_address, 6);
7594   if (v6_address_set)
7595     {
7596       mp->is_ipv6 = 1;
7597       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
7598     }
7599   else
7600     {
7601       /* mp->is_ipv6 = 0; via memset in M macro above */
7602       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
7603     }
7604
7605   /* send it... */
7606   S (mp);
7607
7608   /* Wait for a reply, return good/bad news  */
7609   W (ret);
7610   return ret;
7611 }
7612
7613 static int
7614 api_reset_vrf (vat_main_t * vam)
7615 {
7616   unformat_input_t *i = vam->input;
7617   vl_api_reset_vrf_t *mp;
7618   u32 vrf_id = 0;
7619   u8 is_ipv6 = 0;
7620   u8 vrf_id_set = 0;
7621   int ret;
7622
7623   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7624     {
7625       if (unformat (i, "vrf %d", &vrf_id))
7626         vrf_id_set = 1;
7627       else if (unformat (i, "ipv6"))
7628         is_ipv6 = 1;
7629       else
7630         {
7631           clib_warning ("parse error '%U'", format_unformat_error, i);
7632           return -99;
7633         }
7634     }
7635
7636   if (vrf_id_set == 0)
7637     {
7638       errmsg ("missing vrf id");
7639       return -99;
7640     }
7641
7642   M (RESET_VRF, mp);
7643
7644   mp->vrf_id = ntohl (vrf_id);
7645   mp->is_ipv6 = is_ipv6;
7646
7647   S (mp);
7648   W (ret);
7649   return ret;
7650 }
7651
7652 static int
7653 api_create_vlan_subif (vat_main_t * vam)
7654 {
7655   unformat_input_t *i = vam->input;
7656   vl_api_create_vlan_subif_t *mp;
7657   u32 sw_if_index;
7658   u8 sw_if_index_set = 0;
7659   u32 vlan_id;
7660   u8 vlan_id_set = 0;
7661   int ret;
7662
7663   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7664     {
7665       if (unformat (i, "sw_if_index %d", &sw_if_index))
7666         sw_if_index_set = 1;
7667       else
7668         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7669         sw_if_index_set = 1;
7670       else if (unformat (i, "vlan %d", &vlan_id))
7671         vlan_id_set = 1;
7672       else
7673         {
7674           clib_warning ("parse error '%U'", format_unformat_error, i);
7675           return -99;
7676         }
7677     }
7678
7679   if (sw_if_index_set == 0)
7680     {
7681       errmsg ("missing interface name or sw_if_index");
7682       return -99;
7683     }
7684
7685   if (vlan_id_set == 0)
7686     {
7687       errmsg ("missing vlan_id");
7688       return -99;
7689     }
7690   M (CREATE_VLAN_SUBIF, mp);
7691
7692   mp->sw_if_index = ntohl (sw_if_index);
7693   mp->vlan_id = ntohl (vlan_id);
7694
7695   S (mp);
7696   W (ret);
7697   return ret;
7698 }
7699
7700 #define foreach_create_subif_bit                \
7701 _(no_tags)                                      \
7702 _(one_tag)                                      \
7703 _(two_tags)                                     \
7704 _(dot1ad)                                       \
7705 _(exact_match)                                  \
7706 _(default_sub)                                  \
7707 _(outer_vlan_id_any)                            \
7708 _(inner_vlan_id_any)
7709
7710 static int
7711 api_create_subif (vat_main_t * vam)
7712 {
7713   unformat_input_t *i = vam->input;
7714   vl_api_create_subif_t *mp;
7715   u32 sw_if_index;
7716   u8 sw_if_index_set = 0;
7717   u32 sub_id;
7718   u8 sub_id_set = 0;
7719   u32 no_tags = 0;
7720   u32 one_tag = 0;
7721   u32 two_tags = 0;
7722   u32 dot1ad = 0;
7723   u32 exact_match = 0;
7724   u32 default_sub = 0;
7725   u32 outer_vlan_id_any = 0;
7726   u32 inner_vlan_id_any = 0;
7727   u32 tmp;
7728   u16 outer_vlan_id = 0;
7729   u16 inner_vlan_id = 0;
7730   int ret;
7731
7732   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7733     {
7734       if (unformat (i, "sw_if_index %d", &sw_if_index))
7735         sw_if_index_set = 1;
7736       else
7737         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7738         sw_if_index_set = 1;
7739       else if (unformat (i, "sub_id %d", &sub_id))
7740         sub_id_set = 1;
7741       else if (unformat (i, "outer_vlan_id %d", &tmp))
7742         outer_vlan_id = tmp;
7743       else if (unformat (i, "inner_vlan_id %d", &tmp))
7744         inner_vlan_id = tmp;
7745
7746 #define _(a) else if (unformat (i, #a)) a = 1 ;
7747       foreach_create_subif_bit
7748 #undef _
7749         else
7750         {
7751           clib_warning ("parse error '%U'", format_unformat_error, i);
7752           return -99;
7753         }
7754     }
7755
7756   if (sw_if_index_set == 0)
7757     {
7758       errmsg ("missing interface name or sw_if_index");
7759       return -99;
7760     }
7761
7762   if (sub_id_set == 0)
7763     {
7764       errmsg ("missing sub_id");
7765       return -99;
7766     }
7767   M (CREATE_SUBIF, mp);
7768
7769   mp->sw_if_index = ntohl (sw_if_index);
7770   mp->sub_id = ntohl (sub_id);
7771
7772 #define _(a) mp->a = a;
7773   foreach_create_subif_bit;
7774 #undef _
7775
7776   mp->outer_vlan_id = ntohs (outer_vlan_id);
7777   mp->inner_vlan_id = ntohs (inner_vlan_id);
7778
7779   S (mp);
7780   W (ret);
7781   return ret;
7782 }
7783
7784 static int
7785 api_oam_add_del (vat_main_t * vam)
7786 {
7787   unformat_input_t *i = vam->input;
7788   vl_api_oam_add_del_t *mp;
7789   u32 vrf_id = 0;
7790   u8 is_add = 1;
7791   ip4_address_t src, dst;
7792   u8 src_set = 0;
7793   u8 dst_set = 0;
7794   int ret;
7795
7796   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7797     {
7798       if (unformat (i, "vrf %d", &vrf_id))
7799         ;
7800       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7801         src_set = 1;
7802       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7803         dst_set = 1;
7804       else if (unformat (i, "del"))
7805         is_add = 0;
7806       else
7807         {
7808           clib_warning ("parse error '%U'", format_unformat_error, i);
7809           return -99;
7810         }
7811     }
7812
7813   if (src_set == 0)
7814     {
7815       errmsg ("missing src addr");
7816       return -99;
7817     }
7818
7819   if (dst_set == 0)
7820     {
7821       errmsg ("missing dst addr");
7822       return -99;
7823     }
7824
7825   M (OAM_ADD_DEL, mp);
7826
7827   mp->vrf_id = ntohl (vrf_id);
7828   mp->is_add = is_add;
7829   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7830   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7831
7832   S (mp);
7833   W (ret);
7834   return ret;
7835 }
7836
7837 static int
7838 api_reset_fib (vat_main_t * vam)
7839 {
7840   unformat_input_t *i = vam->input;
7841   vl_api_reset_fib_t *mp;
7842   u32 vrf_id = 0;
7843   u8 is_ipv6 = 0;
7844   u8 vrf_id_set = 0;
7845
7846   int ret;
7847   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7848     {
7849       if (unformat (i, "vrf %d", &vrf_id))
7850         vrf_id_set = 1;
7851       else if (unformat (i, "ipv6"))
7852         is_ipv6 = 1;
7853       else
7854         {
7855           clib_warning ("parse error '%U'", format_unformat_error, i);
7856           return -99;
7857         }
7858     }
7859
7860   if (vrf_id_set == 0)
7861     {
7862       errmsg ("missing vrf id");
7863       return -99;
7864     }
7865
7866   M (RESET_FIB, mp);
7867
7868   mp->vrf_id = ntohl (vrf_id);
7869   mp->is_ipv6 = is_ipv6;
7870
7871   S (mp);
7872   W (ret);
7873   return ret;
7874 }
7875
7876 static int
7877 api_dhcp_proxy_config (vat_main_t * vam)
7878 {
7879   unformat_input_t *i = vam->input;
7880   vl_api_dhcp_proxy_config_t *mp;
7881   u32 rx_vrf_id = 0;
7882   u32 server_vrf_id = 0;
7883   u8 is_add = 1;
7884   u8 v4_address_set = 0;
7885   u8 v6_address_set = 0;
7886   ip4_address_t v4address;
7887   ip6_address_t v6address;
7888   u8 v4_src_address_set = 0;
7889   u8 v6_src_address_set = 0;
7890   ip4_address_t v4srcaddress;
7891   ip6_address_t v6srcaddress;
7892   int ret;
7893
7894   /* Parse args required to build the message */
7895   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7896     {
7897       if (unformat (i, "del"))
7898         is_add = 0;
7899       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7900         ;
7901       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7902         ;
7903       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7904         v4_address_set = 1;
7905       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7906         v6_address_set = 1;
7907       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7908         v4_src_address_set = 1;
7909       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7910         v6_src_address_set = 1;
7911       else
7912         break;
7913     }
7914
7915   if (v4_address_set && v6_address_set)
7916     {
7917       errmsg ("both v4 and v6 server addresses set");
7918       return -99;
7919     }
7920   if (!v4_address_set && !v6_address_set)
7921     {
7922       errmsg ("no server addresses set");
7923       return -99;
7924     }
7925
7926   if (v4_src_address_set && v6_src_address_set)
7927     {
7928       errmsg ("both v4 and v6  src addresses set");
7929       return -99;
7930     }
7931   if (!v4_src_address_set && !v6_src_address_set)
7932     {
7933       errmsg ("no src addresses set");
7934       return -99;
7935     }
7936
7937   if (!(v4_src_address_set && v4_address_set) &&
7938       !(v6_src_address_set && v6_address_set))
7939     {
7940       errmsg ("no matching server and src addresses set");
7941       return -99;
7942     }
7943
7944   /* Construct the API message */
7945   M (DHCP_PROXY_CONFIG, mp);
7946
7947   mp->is_add = is_add;
7948   mp->rx_vrf_id = ntohl (rx_vrf_id);
7949   mp->server_vrf_id = ntohl (server_vrf_id);
7950   if (v6_address_set)
7951     {
7952       mp->is_ipv6 = 1;
7953       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7954       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7955     }
7956   else
7957     {
7958       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7959       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7960     }
7961
7962   /* send it... */
7963   S (mp);
7964
7965   /* Wait for a reply, return good/bad news  */
7966   W (ret);
7967   return ret;
7968 }
7969
7970 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
7971 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
7972
7973 static void
7974 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
7975 {
7976   vat_main_t *vam = &vat_main;
7977   u32 i, count = mp->count;
7978   vl_api_dhcp_server_t *s;
7979
7980   if (mp->is_ipv6)
7981     print (vam->ofp,
7982            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7983            ntohl (mp->rx_vrf_id),
7984            format_ip6_address, mp->dhcp_src_address,
7985            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7986   else
7987     print (vam->ofp,
7988            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7989            ntohl (mp->rx_vrf_id),
7990            format_ip4_address, mp->dhcp_src_address,
7991            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7992
7993   for (i = 0; i < count; i++)
7994     {
7995       s = &mp->servers[i];
7996
7997       if (mp->is_ipv6)
7998         print (vam->ofp,
7999                " Server Table-ID %d, Server Address %U",
8000                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
8001       else
8002         print (vam->ofp,
8003                " Server Table-ID %d, Server Address %U",
8004                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
8005     }
8006 }
8007
8008 static void vl_api_dhcp_proxy_details_t_handler_json
8009   (vl_api_dhcp_proxy_details_t * mp)
8010 {
8011   vat_main_t *vam = &vat_main;
8012   vat_json_node_t *node = NULL;
8013   u32 i, count = mp->count;
8014   struct in_addr ip4;
8015   struct in6_addr ip6;
8016   vl_api_dhcp_server_t *s;
8017
8018   if (VAT_JSON_ARRAY != vam->json_tree.type)
8019     {
8020       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8021       vat_json_init_array (&vam->json_tree);
8022     }
8023   node = vat_json_array_add (&vam->json_tree);
8024
8025   vat_json_init_object (node);
8026   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
8027   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
8028   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
8029
8030   if (mp->is_ipv6)
8031     {
8032       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
8033       vat_json_object_add_ip6 (node, "src_address", ip6);
8034     }
8035   else
8036     {
8037       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
8038       vat_json_object_add_ip4 (node, "src_address", ip4);
8039     }
8040
8041   for (i = 0; i < count; i++)
8042     {
8043       s = &mp->servers[i];
8044
8045       vat_json_object_add_uint (node, "server-table-id",
8046                                 ntohl (s->server_vrf_id));
8047
8048       if (mp->is_ipv6)
8049         {
8050           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
8051           vat_json_object_add_ip4 (node, "src_address", ip4);
8052         }
8053       else
8054         {
8055           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
8056           vat_json_object_add_ip6 (node, "server_address", ip6);
8057         }
8058     }
8059 }
8060
8061 static int
8062 api_dhcp_proxy_dump (vat_main_t * vam)
8063 {
8064   unformat_input_t *i = vam->input;
8065   vl_api_control_ping_t *mp_ping;
8066   vl_api_dhcp_proxy_dump_t *mp;
8067   u8 is_ipv6 = 0;
8068   int ret;
8069
8070   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8071     {
8072       if (unformat (i, "ipv6"))
8073         is_ipv6 = 1;
8074       else
8075         {
8076           clib_warning ("parse error '%U'", format_unformat_error, i);
8077           return -99;
8078         }
8079     }
8080
8081   M (DHCP_PROXY_DUMP, mp);
8082
8083   mp->is_ip6 = is_ipv6;
8084   S (mp);
8085
8086   /* Use a control ping for synchronization */
8087   M (CONTROL_PING, mp_ping);
8088   S (mp_ping);
8089
8090   W (ret);
8091   return ret;
8092 }
8093
8094 static int
8095 api_dhcp_proxy_set_vss (vat_main_t * vam)
8096 {
8097   unformat_input_t *i = vam->input;
8098   vl_api_dhcp_proxy_set_vss_t *mp;
8099   u8 is_ipv6 = 0;
8100   u8 is_add = 1;
8101   u32 tbl_id;
8102   u8 tbl_id_set = 0;
8103   u32 oui;
8104   u8 oui_set = 0;
8105   u32 fib_id;
8106   u8 fib_id_set = 0;
8107   int ret;
8108
8109   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8110     {
8111       if (unformat (i, "tbl_id %d", &tbl_id))
8112         tbl_id_set = 1;
8113       if (unformat (i, "fib_id %d", &fib_id))
8114         fib_id_set = 1;
8115       if (unformat (i, "oui %d", &oui))
8116         oui_set = 1;
8117       else if (unformat (i, "ipv6"))
8118         is_ipv6 = 1;
8119       else if (unformat (i, "del"))
8120         is_add = 0;
8121       else
8122         {
8123           clib_warning ("parse error '%U'", format_unformat_error, i);
8124           return -99;
8125         }
8126     }
8127
8128   if (tbl_id_set == 0)
8129     {
8130       errmsg ("missing tbl id");
8131       return -99;
8132     }
8133
8134   if (fib_id_set == 0)
8135     {
8136       errmsg ("missing fib id");
8137       return -99;
8138     }
8139   if (oui_set == 0)
8140     {
8141       errmsg ("missing oui");
8142       return -99;
8143     }
8144
8145   M (DHCP_PROXY_SET_VSS, mp);
8146   mp->tbl_id = ntohl (tbl_id);
8147   mp->fib_id = ntohl (fib_id);
8148   mp->oui = ntohl (oui);
8149   mp->is_ipv6 = is_ipv6;
8150   mp->is_add = is_add;
8151
8152   S (mp);
8153   W (ret);
8154   return ret;
8155 }
8156
8157 static int
8158 api_dhcp_client_config (vat_main_t * vam)
8159 {
8160   unformat_input_t *i = vam->input;
8161   vl_api_dhcp_client_config_t *mp;
8162   u32 sw_if_index;
8163   u8 sw_if_index_set = 0;
8164   u8 is_add = 1;
8165   u8 *hostname = 0;
8166   u8 disable_event = 0;
8167   int ret;
8168
8169   /* Parse args required to build the message */
8170   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8171     {
8172       if (unformat (i, "del"))
8173         is_add = 0;
8174       else
8175         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8176         sw_if_index_set = 1;
8177       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8178         sw_if_index_set = 1;
8179       else if (unformat (i, "hostname %s", &hostname))
8180         ;
8181       else if (unformat (i, "disable_event"))
8182         disable_event = 1;
8183       else
8184         break;
8185     }
8186
8187   if (sw_if_index_set == 0)
8188     {
8189       errmsg ("missing interface name or sw_if_index");
8190       return -99;
8191     }
8192
8193   if (vec_len (hostname) > 63)
8194     {
8195       errmsg ("hostname too long");
8196     }
8197   vec_add1 (hostname, 0);
8198
8199   /* Construct the API message */
8200   M (DHCP_CLIENT_CONFIG, mp);
8201
8202   mp->sw_if_index = htonl (sw_if_index);
8203   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
8204   vec_free (hostname);
8205   mp->is_add = is_add;
8206   mp->want_dhcp_event = disable_event ? 0 : 1;
8207   mp->pid = htonl (getpid ());
8208
8209   /* send it... */
8210   S (mp);
8211
8212   /* Wait for a reply, return good/bad news  */
8213   W (ret);
8214   return ret;
8215 }
8216
8217 static int
8218 api_set_ip_flow_hash (vat_main_t * vam)
8219 {
8220   unformat_input_t *i = vam->input;
8221   vl_api_set_ip_flow_hash_t *mp;
8222   u32 vrf_id = 0;
8223   u8 is_ipv6 = 0;
8224   u8 vrf_id_set = 0;
8225   u8 src = 0;
8226   u8 dst = 0;
8227   u8 sport = 0;
8228   u8 dport = 0;
8229   u8 proto = 0;
8230   u8 reverse = 0;
8231   int ret;
8232
8233   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8234     {
8235       if (unformat (i, "vrf %d", &vrf_id))
8236         vrf_id_set = 1;
8237       else if (unformat (i, "ipv6"))
8238         is_ipv6 = 1;
8239       else if (unformat (i, "src"))
8240         src = 1;
8241       else if (unformat (i, "dst"))
8242         dst = 1;
8243       else if (unformat (i, "sport"))
8244         sport = 1;
8245       else if (unformat (i, "dport"))
8246         dport = 1;
8247       else if (unformat (i, "proto"))
8248         proto = 1;
8249       else if (unformat (i, "reverse"))
8250         reverse = 1;
8251
8252       else
8253         {
8254           clib_warning ("parse error '%U'", format_unformat_error, i);
8255           return -99;
8256         }
8257     }
8258
8259   if (vrf_id_set == 0)
8260     {
8261       errmsg ("missing vrf id");
8262       return -99;
8263     }
8264
8265   M (SET_IP_FLOW_HASH, mp);
8266   mp->src = src;
8267   mp->dst = dst;
8268   mp->sport = sport;
8269   mp->dport = dport;
8270   mp->proto = proto;
8271   mp->reverse = reverse;
8272   mp->vrf_id = ntohl (vrf_id);
8273   mp->is_ipv6 = is_ipv6;
8274
8275   S (mp);
8276   W (ret);
8277   return ret;
8278 }
8279
8280 static int
8281 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
8282 {
8283   unformat_input_t *i = vam->input;
8284   vl_api_sw_interface_ip6_enable_disable_t *mp;
8285   u32 sw_if_index;
8286   u8 sw_if_index_set = 0;
8287   u8 enable = 0;
8288   int ret;
8289
8290   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8291     {
8292       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8293         sw_if_index_set = 1;
8294       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8295         sw_if_index_set = 1;
8296       else if (unformat (i, "enable"))
8297         enable = 1;
8298       else if (unformat (i, "disable"))
8299         enable = 0;
8300       else
8301         {
8302           clib_warning ("parse error '%U'", format_unformat_error, i);
8303           return -99;
8304         }
8305     }
8306
8307   if (sw_if_index_set == 0)
8308     {
8309       errmsg ("missing interface name or sw_if_index");
8310       return -99;
8311     }
8312
8313   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
8314
8315   mp->sw_if_index = ntohl (sw_if_index);
8316   mp->enable = enable;
8317
8318   S (mp);
8319   W (ret);
8320   return ret;
8321 }
8322
8323 static int
8324 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
8325 {
8326   unformat_input_t *i = vam->input;
8327   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
8328   u32 sw_if_index;
8329   u8 sw_if_index_set = 0;
8330   u8 v6_address_set = 0;
8331   ip6_address_t v6address;
8332   int ret;
8333
8334   /* Parse args required to build the message */
8335   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8336     {
8337       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8338         sw_if_index_set = 1;
8339       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8340         sw_if_index_set = 1;
8341       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8342         v6_address_set = 1;
8343       else
8344         break;
8345     }
8346
8347   if (sw_if_index_set == 0)
8348     {
8349       errmsg ("missing interface name or sw_if_index");
8350       return -99;
8351     }
8352   if (!v6_address_set)
8353     {
8354       errmsg ("no address set");
8355       return -99;
8356     }
8357
8358   /* Construct the API message */
8359   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
8360
8361   mp->sw_if_index = ntohl (sw_if_index);
8362   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8363
8364   /* send it... */
8365   S (mp);
8366
8367   /* Wait for a reply, return good/bad news  */
8368   W (ret);
8369   return ret;
8370 }
8371
8372 static int
8373 api_ip6nd_proxy_add_del (vat_main_t * vam)
8374 {
8375   unformat_input_t *i = vam->input;
8376   vl_api_ip6nd_proxy_add_del_t *mp;
8377   u32 sw_if_index = ~0;
8378   u8 v6_address_set = 0;
8379   ip6_address_t v6address;
8380   u8 is_del = 0;
8381   int ret;
8382
8383   /* Parse args required to build the message */
8384   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8385     {
8386       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8387         ;
8388       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8389         ;
8390       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8391         v6_address_set = 1;
8392       if (unformat (i, "del"))
8393         is_del = 1;
8394       else
8395         {
8396           clib_warning ("parse error '%U'", format_unformat_error, i);
8397           return -99;
8398         }
8399     }
8400
8401   if (sw_if_index == ~0)
8402     {
8403       errmsg ("missing interface name or sw_if_index");
8404       return -99;
8405     }
8406   if (!v6_address_set)
8407     {
8408       errmsg ("no address set");
8409       return -99;
8410     }
8411
8412   /* Construct the API message */
8413   M (IP6ND_PROXY_ADD_DEL, mp);
8414
8415   mp->is_del = is_del;
8416   mp->sw_if_index = ntohl (sw_if_index);
8417   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8418
8419   /* send it... */
8420   S (mp);
8421
8422   /* Wait for a reply, return good/bad news  */
8423   W (ret);
8424   return ret;
8425 }
8426
8427 static int
8428 api_ip6nd_proxy_dump (vat_main_t * vam)
8429 {
8430   vl_api_ip6nd_proxy_dump_t *mp;
8431   vl_api_control_ping_t *mp_ping;
8432   int ret;
8433
8434   M (IP6ND_PROXY_DUMP, mp);
8435
8436   S (mp);
8437
8438   /* Use a control ping for synchronization */
8439   M (CONTROL_PING, mp_ping);
8440   S (mp_ping);
8441
8442   W (ret);
8443   return ret;
8444 }
8445
8446 static void vl_api_ip6nd_proxy_details_t_handler
8447   (vl_api_ip6nd_proxy_details_t * mp)
8448 {
8449   vat_main_t *vam = &vat_main;
8450
8451   print (vam->ofp, "host %U sw_if_index %d",
8452          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
8453 }
8454
8455 static void vl_api_ip6nd_proxy_details_t_handler_json
8456   (vl_api_ip6nd_proxy_details_t * mp)
8457 {
8458   vat_main_t *vam = &vat_main;
8459   struct in6_addr ip6;
8460   vat_json_node_t *node = NULL;
8461
8462   if (VAT_JSON_ARRAY != vam->json_tree.type)
8463     {
8464       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8465       vat_json_init_array (&vam->json_tree);
8466     }
8467   node = vat_json_array_add (&vam->json_tree);
8468
8469   vat_json_init_object (node);
8470   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
8471
8472   clib_memcpy (&ip6, mp->address, sizeof (ip6));
8473   vat_json_object_add_ip6 (node, "host", ip6);
8474 }
8475
8476 static int
8477 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
8478 {
8479   unformat_input_t *i = vam->input;
8480   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
8481   u32 sw_if_index;
8482   u8 sw_if_index_set = 0;
8483   u32 address_length = 0;
8484   u8 v6_address_set = 0;
8485   ip6_address_t v6address;
8486   u8 use_default = 0;
8487   u8 no_advertise = 0;
8488   u8 off_link = 0;
8489   u8 no_autoconfig = 0;
8490   u8 no_onlink = 0;
8491   u8 is_no = 0;
8492   u32 val_lifetime = 0;
8493   u32 pref_lifetime = 0;
8494   int ret;
8495
8496   /* Parse args required to build the message */
8497   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8498     {
8499       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8500         sw_if_index_set = 1;
8501       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8502         sw_if_index_set = 1;
8503       else if (unformat (i, "%U/%d",
8504                          unformat_ip6_address, &v6address, &address_length))
8505         v6_address_set = 1;
8506       else if (unformat (i, "val_life %d", &val_lifetime))
8507         ;
8508       else if (unformat (i, "pref_life %d", &pref_lifetime))
8509         ;
8510       else if (unformat (i, "def"))
8511         use_default = 1;
8512       else if (unformat (i, "noadv"))
8513         no_advertise = 1;
8514       else if (unformat (i, "offl"))
8515         off_link = 1;
8516       else if (unformat (i, "noauto"))
8517         no_autoconfig = 1;
8518       else if (unformat (i, "nolink"))
8519         no_onlink = 1;
8520       else if (unformat (i, "isno"))
8521         is_no = 1;
8522       else
8523         {
8524           clib_warning ("parse error '%U'", format_unformat_error, i);
8525           return -99;
8526         }
8527     }
8528
8529   if (sw_if_index_set == 0)
8530     {
8531       errmsg ("missing interface name or sw_if_index");
8532       return -99;
8533     }
8534   if (!v6_address_set)
8535     {
8536       errmsg ("no address set");
8537       return -99;
8538     }
8539
8540   /* Construct the API message */
8541   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
8542
8543   mp->sw_if_index = ntohl (sw_if_index);
8544   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8545   mp->address_length = address_length;
8546   mp->use_default = use_default;
8547   mp->no_advertise = no_advertise;
8548   mp->off_link = off_link;
8549   mp->no_autoconfig = no_autoconfig;
8550   mp->no_onlink = no_onlink;
8551   mp->is_no = is_no;
8552   mp->val_lifetime = ntohl (val_lifetime);
8553   mp->pref_lifetime = ntohl (pref_lifetime);
8554
8555   /* send it... */
8556   S (mp);
8557
8558   /* Wait for a reply, return good/bad news  */
8559   W (ret);
8560   return ret;
8561 }
8562
8563 static int
8564 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
8565 {
8566   unformat_input_t *i = vam->input;
8567   vl_api_sw_interface_ip6nd_ra_config_t *mp;
8568   u32 sw_if_index;
8569   u8 sw_if_index_set = 0;
8570   u8 suppress = 0;
8571   u8 managed = 0;
8572   u8 other = 0;
8573   u8 ll_option = 0;
8574   u8 send_unicast = 0;
8575   u8 cease = 0;
8576   u8 is_no = 0;
8577   u8 default_router = 0;
8578   u32 max_interval = 0;
8579   u32 min_interval = 0;
8580   u32 lifetime = 0;
8581   u32 initial_count = 0;
8582   u32 initial_interval = 0;
8583   int ret;
8584
8585
8586   /* Parse args required to build the message */
8587   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8588     {
8589       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8590         sw_if_index_set = 1;
8591       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8592         sw_if_index_set = 1;
8593       else if (unformat (i, "maxint %d", &max_interval))
8594         ;
8595       else if (unformat (i, "minint %d", &min_interval))
8596         ;
8597       else if (unformat (i, "life %d", &lifetime))
8598         ;
8599       else if (unformat (i, "count %d", &initial_count))
8600         ;
8601       else if (unformat (i, "interval %d", &initial_interval))
8602         ;
8603       else if (unformat (i, "suppress") || unformat (i, "surpress"))
8604         suppress = 1;
8605       else if (unformat (i, "managed"))
8606         managed = 1;
8607       else if (unformat (i, "other"))
8608         other = 1;
8609       else if (unformat (i, "ll"))
8610         ll_option = 1;
8611       else if (unformat (i, "send"))
8612         send_unicast = 1;
8613       else if (unformat (i, "cease"))
8614         cease = 1;
8615       else if (unformat (i, "isno"))
8616         is_no = 1;
8617       else if (unformat (i, "def"))
8618         default_router = 1;
8619       else
8620         {
8621           clib_warning ("parse error '%U'", format_unformat_error, i);
8622           return -99;
8623         }
8624     }
8625
8626   if (sw_if_index_set == 0)
8627     {
8628       errmsg ("missing interface name or sw_if_index");
8629       return -99;
8630     }
8631
8632   /* Construct the API message */
8633   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
8634
8635   mp->sw_if_index = ntohl (sw_if_index);
8636   mp->max_interval = ntohl (max_interval);
8637   mp->min_interval = ntohl (min_interval);
8638   mp->lifetime = ntohl (lifetime);
8639   mp->initial_count = ntohl (initial_count);
8640   mp->initial_interval = ntohl (initial_interval);
8641   mp->suppress = suppress;
8642   mp->managed = managed;
8643   mp->other = other;
8644   mp->ll_option = ll_option;
8645   mp->send_unicast = send_unicast;
8646   mp->cease = cease;
8647   mp->is_no = is_no;
8648   mp->default_router = default_router;
8649
8650   /* send it... */
8651   S (mp);
8652
8653   /* Wait for a reply, return good/bad news  */
8654   W (ret);
8655   return ret;
8656 }
8657
8658 static int
8659 api_set_arp_neighbor_limit (vat_main_t * vam)
8660 {
8661   unformat_input_t *i = vam->input;
8662   vl_api_set_arp_neighbor_limit_t *mp;
8663   u32 arp_nbr_limit;
8664   u8 limit_set = 0;
8665   u8 is_ipv6 = 0;
8666   int ret;
8667
8668   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8669     {
8670       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
8671         limit_set = 1;
8672       else if (unformat (i, "ipv6"))
8673         is_ipv6 = 1;
8674       else
8675         {
8676           clib_warning ("parse error '%U'", format_unformat_error, i);
8677           return -99;
8678         }
8679     }
8680
8681   if (limit_set == 0)
8682     {
8683       errmsg ("missing limit value");
8684       return -99;
8685     }
8686
8687   M (SET_ARP_NEIGHBOR_LIMIT, mp);
8688
8689   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
8690   mp->is_ipv6 = is_ipv6;
8691
8692   S (mp);
8693   W (ret);
8694   return ret;
8695 }
8696
8697 static int
8698 api_l2_patch_add_del (vat_main_t * vam)
8699 {
8700   unformat_input_t *i = vam->input;
8701   vl_api_l2_patch_add_del_t *mp;
8702   u32 rx_sw_if_index;
8703   u8 rx_sw_if_index_set = 0;
8704   u32 tx_sw_if_index;
8705   u8 tx_sw_if_index_set = 0;
8706   u8 is_add = 1;
8707   int ret;
8708
8709   /* Parse args required to build the message */
8710   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8711     {
8712       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
8713         rx_sw_if_index_set = 1;
8714       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
8715         tx_sw_if_index_set = 1;
8716       else if (unformat (i, "rx"))
8717         {
8718           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8719             {
8720               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8721                             &rx_sw_if_index))
8722                 rx_sw_if_index_set = 1;
8723             }
8724           else
8725             break;
8726         }
8727       else if (unformat (i, "tx"))
8728         {
8729           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8730             {
8731               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8732                             &tx_sw_if_index))
8733                 tx_sw_if_index_set = 1;
8734             }
8735           else
8736             break;
8737         }
8738       else if (unformat (i, "del"))
8739         is_add = 0;
8740       else
8741         break;
8742     }
8743
8744   if (rx_sw_if_index_set == 0)
8745     {
8746       errmsg ("missing rx interface name or rx_sw_if_index");
8747       return -99;
8748     }
8749
8750   if (tx_sw_if_index_set == 0)
8751     {
8752       errmsg ("missing tx interface name or tx_sw_if_index");
8753       return -99;
8754     }
8755
8756   M (L2_PATCH_ADD_DEL, mp);
8757
8758   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
8759   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
8760   mp->is_add = is_add;
8761
8762   S (mp);
8763   W (ret);
8764   return ret;
8765 }
8766
8767 u8 is_del;
8768 u8 localsid_addr[16];
8769 u8 end_psp;
8770 u8 behavior;
8771 u32 sw_if_index;
8772 u32 vlan_index;
8773 u32 fib_table;
8774 u8 nh_addr[16];
8775
8776 static int
8777 api_sr_localsid_add_del (vat_main_t * vam)
8778 {
8779   unformat_input_t *i = vam->input;
8780   vl_api_sr_localsid_add_del_t *mp;
8781
8782   u8 is_del;
8783   ip6_address_t localsid;
8784   u8 end_psp = 0;
8785   u8 behavior = ~0;
8786   u32 sw_if_index;
8787   u32 fib_table = ~(u32) 0;
8788   ip6_address_t next_hop;
8789
8790   bool nexthop_set = 0;
8791
8792   int ret;
8793
8794   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8795     {
8796       if (unformat (i, "del"))
8797         is_del = 1;
8798       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
8799       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
8800         nexthop_set = 1;
8801       else if (unformat (i, "behavior %u", &behavior));
8802       else if (unformat (i, "sw_if_index %u", &sw_if_index));
8803       else if (unformat (i, "fib-table %u", &fib_table));
8804       else if (unformat (i, "end.psp %u", &behavior));
8805       else
8806         break;
8807     }
8808
8809   M (SR_LOCALSID_ADD_DEL, mp);
8810
8811   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
8812   if (nexthop_set)
8813     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
8814   mp->behavior = behavior;
8815   mp->sw_if_index = ntohl (sw_if_index);
8816   mp->fib_table = ntohl (fib_table);
8817   mp->end_psp = end_psp;
8818   mp->is_del = is_del;
8819
8820   S (mp);
8821   W (ret);
8822   return ret;
8823 }
8824
8825 static int
8826 api_ioam_enable (vat_main_t * vam)
8827 {
8828   unformat_input_t *input = vam->input;
8829   vl_api_ioam_enable_t *mp;
8830   u32 id = 0;
8831   int has_trace_option = 0;
8832   int has_pot_option = 0;
8833   int has_seqno_option = 0;
8834   int has_analyse_option = 0;
8835   int ret;
8836
8837   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8838     {
8839       if (unformat (input, "trace"))
8840         has_trace_option = 1;
8841       else if (unformat (input, "pot"))
8842         has_pot_option = 1;
8843       else if (unformat (input, "seqno"))
8844         has_seqno_option = 1;
8845       else if (unformat (input, "analyse"))
8846         has_analyse_option = 1;
8847       else
8848         break;
8849     }
8850   M (IOAM_ENABLE, mp);
8851   mp->id = htons (id);
8852   mp->seqno = has_seqno_option;
8853   mp->analyse = has_analyse_option;
8854   mp->pot_enable = has_pot_option;
8855   mp->trace_enable = has_trace_option;
8856
8857   S (mp);
8858   W (ret);
8859   return ret;
8860 }
8861
8862
8863 static int
8864 api_ioam_disable (vat_main_t * vam)
8865 {
8866   vl_api_ioam_disable_t *mp;
8867   int ret;
8868
8869   M (IOAM_DISABLE, mp);
8870   S (mp);
8871   W (ret);
8872   return ret;
8873 }
8874
8875 #define foreach_tcp_proto_field                 \
8876 _(src_port)                                     \
8877 _(dst_port)
8878
8879 #define foreach_udp_proto_field                 \
8880 _(src_port)                                     \
8881 _(dst_port)
8882
8883 #define foreach_ip4_proto_field                 \
8884 _(src_address)                                  \
8885 _(dst_address)                                  \
8886 _(tos)                                          \
8887 _(length)                                       \
8888 _(fragment_id)                                  \
8889 _(ttl)                                          \
8890 _(protocol)                                     \
8891 _(checksum)
8892
8893 typedef struct
8894 {
8895   u16 src_port, dst_port;
8896 } tcpudp_header_t;
8897
8898 #if VPP_API_TEST_BUILTIN == 0
8899 uword
8900 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8901 {
8902   u8 **maskp = va_arg (*args, u8 **);
8903   u8 *mask = 0;
8904   u8 found_something = 0;
8905   tcp_header_t *tcp;
8906
8907 #define _(a) u8 a=0;
8908   foreach_tcp_proto_field;
8909 #undef _
8910
8911   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8912     {
8913       if (0);
8914 #define _(a) else if (unformat (input, #a)) a=1;
8915       foreach_tcp_proto_field
8916 #undef _
8917         else
8918         break;
8919     }
8920
8921 #define _(a) found_something += a;
8922   foreach_tcp_proto_field;
8923 #undef _
8924
8925   if (found_something == 0)
8926     return 0;
8927
8928   vec_validate (mask, sizeof (*tcp) - 1);
8929
8930   tcp = (tcp_header_t *) mask;
8931
8932 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8933   foreach_tcp_proto_field;
8934 #undef _
8935
8936   *maskp = mask;
8937   return 1;
8938 }
8939
8940 uword
8941 unformat_udp_mask (unformat_input_t * input, va_list * args)
8942 {
8943   u8 **maskp = va_arg (*args, u8 **);
8944   u8 *mask = 0;
8945   u8 found_something = 0;
8946   udp_header_t *udp;
8947
8948 #define _(a) u8 a=0;
8949   foreach_udp_proto_field;
8950 #undef _
8951
8952   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8953     {
8954       if (0);
8955 #define _(a) else if (unformat (input, #a)) a=1;
8956       foreach_udp_proto_field
8957 #undef _
8958         else
8959         break;
8960     }
8961
8962 #define _(a) found_something += a;
8963   foreach_udp_proto_field;
8964 #undef _
8965
8966   if (found_something == 0)
8967     return 0;
8968
8969   vec_validate (mask, sizeof (*udp) - 1);
8970
8971   udp = (udp_header_t *) mask;
8972
8973 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8974   foreach_udp_proto_field;
8975 #undef _
8976
8977   *maskp = mask;
8978   return 1;
8979 }
8980
8981 uword
8982 unformat_l4_mask (unformat_input_t * input, va_list * args)
8983 {
8984   u8 **maskp = va_arg (*args, u8 **);
8985   u16 src_port = 0, dst_port = 0;
8986   tcpudp_header_t *tcpudp;
8987
8988   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8989     {
8990       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8991         return 1;
8992       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8993         return 1;
8994       else if (unformat (input, "src_port"))
8995         src_port = 0xFFFF;
8996       else if (unformat (input, "dst_port"))
8997         dst_port = 0xFFFF;
8998       else
8999         return 0;
9000     }
9001
9002   if (!src_port && !dst_port)
9003     return 0;
9004
9005   u8 *mask = 0;
9006   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9007
9008   tcpudp = (tcpudp_header_t *) mask;
9009   tcpudp->src_port = src_port;
9010   tcpudp->dst_port = dst_port;
9011
9012   *maskp = mask;
9013
9014   return 1;
9015 }
9016
9017 uword
9018 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9019 {
9020   u8 **maskp = va_arg (*args, u8 **);
9021   u8 *mask = 0;
9022   u8 found_something = 0;
9023   ip4_header_t *ip;
9024
9025 #define _(a) u8 a=0;
9026   foreach_ip4_proto_field;
9027 #undef _
9028   u8 version = 0;
9029   u8 hdr_length = 0;
9030
9031
9032   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9033     {
9034       if (unformat (input, "version"))
9035         version = 1;
9036       else if (unformat (input, "hdr_length"))
9037         hdr_length = 1;
9038       else if (unformat (input, "src"))
9039         src_address = 1;
9040       else if (unformat (input, "dst"))
9041         dst_address = 1;
9042       else if (unformat (input, "proto"))
9043         protocol = 1;
9044
9045 #define _(a) else if (unformat (input, #a)) a=1;
9046       foreach_ip4_proto_field
9047 #undef _
9048         else
9049         break;
9050     }
9051
9052 #define _(a) found_something += a;
9053   foreach_ip4_proto_field;
9054 #undef _
9055
9056   if (found_something == 0)
9057     return 0;
9058
9059   vec_validate (mask, sizeof (*ip) - 1);
9060
9061   ip = (ip4_header_t *) mask;
9062
9063 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9064   foreach_ip4_proto_field;
9065 #undef _
9066
9067   ip->ip_version_and_header_length = 0;
9068
9069   if (version)
9070     ip->ip_version_and_header_length |= 0xF0;
9071
9072   if (hdr_length)
9073     ip->ip_version_and_header_length |= 0x0F;
9074
9075   *maskp = mask;
9076   return 1;
9077 }
9078
9079 #define foreach_ip6_proto_field                 \
9080 _(src_address)                                  \
9081 _(dst_address)                                  \
9082 _(payload_length)                               \
9083 _(hop_limit)                                    \
9084 _(protocol)
9085
9086 uword
9087 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9088 {
9089   u8 **maskp = va_arg (*args, u8 **);
9090   u8 *mask = 0;
9091   u8 found_something = 0;
9092   ip6_header_t *ip;
9093   u32 ip_version_traffic_class_and_flow_label;
9094
9095 #define _(a) u8 a=0;
9096   foreach_ip6_proto_field;
9097 #undef _
9098   u8 version = 0;
9099   u8 traffic_class = 0;
9100   u8 flow_label = 0;
9101
9102   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9103     {
9104       if (unformat (input, "version"))
9105         version = 1;
9106       else if (unformat (input, "traffic-class"))
9107         traffic_class = 1;
9108       else if (unformat (input, "flow-label"))
9109         flow_label = 1;
9110       else if (unformat (input, "src"))
9111         src_address = 1;
9112       else if (unformat (input, "dst"))
9113         dst_address = 1;
9114       else if (unformat (input, "proto"))
9115         protocol = 1;
9116
9117 #define _(a) else if (unformat (input, #a)) a=1;
9118       foreach_ip6_proto_field
9119 #undef _
9120         else
9121         break;
9122     }
9123
9124 #define _(a) found_something += a;
9125   foreach_ip6_proto_field;
9126 #undef _
9127
9128   if (found_something == 0)
9129     return 0;
9130
9131   vec_validate (mask, sizeof (*ip) - 1);
9132
9133   ip = (ip6_header_t *) mask;
9134
9135 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9136   foreach_ip6_proto_field;
9137 #undef _
9138
9139   ip_version_traffic_class_and_flow_label = 0;
9140
9141   if (version)
9142     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9143
9144   if (traffic_class)
9145     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9146
9147   if (flow_label)
9148     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9149
9150   ip->ip_version_traffic_class_and_flow_label =
9151     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9152
9153   *maskp = mask;
9154   return 1;
9155 }
9156
9157 uword
9158 unformat_l3_mask (unformat_input_t * input, va_list * args)
9159 {
9160   u8 **maskp = va_arg (*args, u8 **);
9161
9162   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9163     {
9164       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9165         return 1;
9166       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9167         return 1;
9168       else
9169         break;
9170     }
9171   return 0;
9172 }
9173
9174 uword
9175 unformat_l2_mask (unformat_input_t * input, va_list * args)
9176 {
9177   u8 **maskp = va_arg (*args, u8 **);
9178   u8 *mask = 0;
9179   u8 src = 0;
9180   u8 dst = 0;
9181   u8 proto = 0;
9182   u8 tag1 = 0;
9183   u8 tag2 = 0;
9184   u8 ignore_tag1 = 0;
9185   u8 ignore_tag2 = 0;
9186   u8 cos1 = 0;
9187   u8 cos2 = 0;
9188   u8 dot1q = 0;
9189   u8 dot1ad = 0;
9190   int len = 14;
9191
9192   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9193     {
9194       if (unformat (input, "src"))
9195         src = 1;
9196       else if (unformat (input, "dst"))
9197         dst = 1;
9198       else if (unformat (input, "proto"))
9199         proto = 1;
9200       else if (unformat (input, "tag1"))
9201         tag1 = 1;
9202       else if (unformat (input, "tag2"))
9203         tag2 = 1;
9204       else if (unformat (input, "ignore-tag1"))
9205         ignore_tag1 = 1;
9206       else if (unformat (input, "ignore-tag2"))
9207         ignore_tag2 = 1;
9208       else if (unformat (input, "cos1"))
9209         cos1 = 1;
9210       else if (unformat (input, "cos2"))
9211         cos2 = 1;
9212       else if (unformat (input, "dot1q"))
9213         dot1q = 1;
9214       else if (unformat (input, "dot1ad"))
9215         dot1ad = 1;
9216       else
9217         break;
9218     }
9219   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9220        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9221     return 0;
9222
9223   if (tag1 || ignore_tag1 || cos1 || dot1q)
9224     len = 18;
9225   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9226     len = 22;
9227
9228   vec_validate (mask, len - 1);
9229
9230   if (dst)
9231     memset (mask, 0xff, 6);
9232
9233   if (src)
9234     memset (mask + 6, 0xff, 6);
9235
9236   if (tag2 || dot1ad)
9237     {
9238       /* inner vlan tag */
9239       if (tag2)
9240         {
9241           mask[19] = 0xff;
9242           mask[18] = 0x0f;
9243         }
9244       if (cos2)
9245         mask[18] |= 0xe0;
9246       if (proto)
9247         mask[21] = mask[20] = 0xff;
9248       if (tag1)
9249         {
9250           mask[15] = 0xff;
9251           mask[14] = 0x0f;
9252         }
9253       if (cos1)
9254         mask[14] |= 0xe0;
9255       *maskp = mask;
9256       return 1;
9257     }
9258   if (tag1 | dot1q)
9259     {
9260       if (tag1)
9261         {
9262           mask[15] = 0xff;
9263           mask[14] = 0x0f;
9264         }
9265       if (cos1)
9266         mask[14] |= 0xe0;
9267       if (proto)
9268         mask[16] = mask[17] = 0xff;
9269
9270       *maskp = mask;
9271       return 1;
9272     }
9273   if (cos2)
9274     mask[18] |= 0xe0;
9275   if (cos1)
9276     mask[14] |= 0xe0;
9277   if (proto)
9278     mask[12] = mask[13] = 0xff;
9279
9280   *maskp = mask;
9281   return 1;
9282 }
9283
9284 uword
9285 unformat_classify_mask (unformat_input_t * input, va_list * args)
9286 {
9287   u8 **maskp = va_arg (*args, u8 **);
9288   u32 *skipp = va_arg (*args, u32 *);
9289   u32 *matchp = va_arg (*args, u32 *);
9290   u32 match;
9291   u8 *mask = 0;
9292   u8 *l2 = 0;
9293   u8 *l3 = 0;
9294   u8 *l4 = 0;
9295   int i;
9296
9297   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9298     {
9299       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9300         ;
9301       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9302         ;
9303       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9304         ;
9305       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9306         ;
9307       else
9308         break;
9309     }
9310
9311   if (l4 && !l3)
9312     {
9313       vec_free (mask);
9314       vec_free (l2);
9315       vec_free (l4);
9316       return 0;
9317     }
9318
9319   if (mask || l2 || l3 || l4)
9320     {
9321       if (l2 || l3 || l4)
9322         {
9323           /* "With a free Ethernet header in every package" */
9324           if (l2 == 0)
9325             vec_validate (l2, 13);
9326           mask = l2;
9327           if (vec_len (l3))
9328             {
9329               vec_append (mask, l3);
9330               vec_free (l3);
9331             }
9332           if (vec_len (l4))
9333             {
9334               vec_append (mask, l4);
9335               vec_free (l4);
9336             }
9337         }
9338
9339       /* Scan forward looking for the first significant mask octet */
9340       for (i = 0; i < vec_len (mask); i++)
9341         if (mask[i])
9342           break;
9343
9344       /* compute (skip, match) params */
9345       *skipp = i / sizeof (u32x4);
9346       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9347
9348       /* Pad mask to an even multiple of the vector size */
9349       while (vec_len (mask) % sizeof (u32x4))
9350         vec_add1 (mask, 0);
9351
9352       match = vec_len (mask) / sizeof (u32x4);
9353
9354       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9355         {
9356           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9357           if (*tmp || *(tmp + 1))
9358             break;
9359           match--;
9360         }
9361       if (match == 0)
9362         clib_warning ("BUG: match 0");
9363
9364       _vec_len (mask) = match * sizeof (u32x4);
9365
9366       *matchp = match;
9367       *maskp = mask;
9368
9369       return 1;
9370     }
9371
9372   return 0;
9373 }
9374 #endif /* VPP_API_TEST_BUILTIN */
9375
9376 #define foreach_l2_next                         \
9377 _(drop, DROP)                                   \
9378 _(ethernet, ETHERNET_INPUT)                     \
9379 _(ip4, IP4_INPUT)                               \
9380 _(ip6, IP6_INPUT)
9381
9382 uword
9383 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9384 {
9385   u32 *miss_next_indexp = va_arg (*args, u32 *);
9386   u32 next_index = 0;
9387   u32 tmp;
9388
9389 #define _(n,N) \
9390   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9391   foreach_l2_next;
9392 #undef _
9393
9394   if (unformat (input, "%d", &tmp))
9395     {
9396       next_index = tmp;
9397       goto out;
9398     }
9399
9400   return 0;
9401
9402 out:
9403   *miss_next_indexp = next_index;
9404   return 1;
9405 }
9406
9407 #define foreach_ip_next                         \
9408 _(drop, DROP)                                   \
9409 _(local, LOCAL)                                 \
9410 _(rewrite, REWRITE)
9411
9412 uword
9413 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9414 {
9415   u32 *miss_next_indexp = va_arg (*args, u32 *);
9416   u32 next_index = 0;
9417   u32 tmp;
9418
9419 #define _(n,N) \
9420   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9421   foreach_ip_next;
9422 #undef _
9423
9424   if (unformat (input, "%d", &tmp))
9425     {
9426       next_index = tmp;
9427       goto out;
9428     }
9429
9430   return 0;
9431
9432 out:
9433   *miss_next_indexp = next_index;
9434   return 1;
9435 }
9436
9437 #define foreach_acl_next                        \
9438 _(deny, DENY)
9439
9440 uword
9441 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9442 {
9443   u32 *miss_next_indexp = va_arg (*args, u32 *);
9444   u32 next_index = 0;
9445   u32 tmp;
9446
9447 #define _(n,N) \
9448   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9449   foreach_acl_next;
9450 #undef _
9451
9452   if (unformat (input, "permit"))
9453     {
9454       next_index = ~0;
9455       goto out;
9456     }
9457   else if (unformat (input, "%d", &tmp))
9458     {
9459       next_index = tmp;
9460       goto out;
9461     }
9462
9463   return 0;
9464
9465 out:
9466   *miss_next_indexp = next_index;
9467   return 1;
9468 }
9469
9470 uword
9471 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9472 {
9473   u32 *r = va_arg (*args, u32 *);
9474
9475   if (unformat (input, "conform-color"))
9476     *r = POLICE_CONFORM;
9477   else if (unformat (input, "exceed-color"))
9478     *r = POLICE_EXCEED;
9479   else
9480     return 0;
9481
9482   return 1;
9483 }
9484
9485 static int
9486 api_classify_add_del_table (vat_main_t * vam)
9487 {
9488   unformat_input_t *i = vam->input;
9489   vl_api_classify_add_del_table_t *mp;
9490
9491   u32 nbuckets = 2;
9492   u32 skip = ~0;
9493   u32 match = ~0;
9494   int is_add = 1;
9495   int del_chain = 0;
9496   u32 table_index = ~0;
9497   u32 next_table_index = ~0;
9498   u32 miss_next_index = ~0;
9499   u32 memory_size = 32 << 20;
9500   u8 *mask = 0;
9501   u32 current_data_flag = 0;
9502   int current_data_offset = 0;
9503   int ret;
9504
9505   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9506     {
9507       if (unformat (i, "del"))
9508         is_add = 0;
9509       else if (unformat (i, "del-chain"))
9510         {
9511           is_add = 0;
9512           del_chain = 1;
9513         }
9514       else if (unformat (i, "buckets %d", &nbuckets))
9515         ;
9516       else if (unformat (i, "memory_size %d", &memory_size))
9517         ;
9518       else if (unformat (i, "skip %d", &skip))
9519         ;
9520       else if (unformat (i, "match %d", &match))
9521         ;
9522       else if (unformat (i, "table %d", &table_index))
9523         ;
9524       else if (unformat (i, "mask %U", unformat_classify_mask,
9525                          &mask, &skip, &match))
9526         ;
9527       else if (unformat (i, "next-table %d", &next_table_index))
9528         ;
9529       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
9530                          &miss_next_index))
9531         ;
9532       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
9533                          &miss_next_index))
9534         ;
9535       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
9536                          &miss_next_index))
9537         ;
9538       else if (unformat (i, "current-data-flag %d", &current_data_flag))
9539         ;
9540       else if (unformat (i, "current-data-offset %d", &current_data_offset))
9541         ;
9542       else
9543         break;
9544     }
9545
9546   if (is_add && mask == 0)
9547     {
9548       errmsg ("Mask required");
9549       return -99;
9550     }
9551
9552   if (is_add && skip == ~0)
9553     {
9554       errmsg ("skip count required");
9555       return -99;
9556     }
9557
9558   if (is_add && match == ~0)
9559     {
9560       errmsg ("match count required");
9561       return -99;
9562     }
9563
9564   if (!is_add && table_index == ~0)
9565     {
9566       errmsg ("table index required for delete");
9567       return -99;
9568     }
9569
9570   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
9571
9572   mp->is_add = is_add;
9573   mp->del_chain = del_chain;
9574   mp->table_index = ntohl (table_index);
9575   mp->nbuckets = ntohl (nbuckets);
9576   mp->memory_size = ntohl (memory_size);
9577   mp->skip_n_vectors = ntohl (skip);
9578   mp->match_n_vectors = ntohl (match);
9579   mp->next_table_index = ntohl (next_table_index);
9580   mp->miss_next_index = ntohl (miss_next_index);
9581   mp->current_data_flag = ntohl (current_data_flag);
9582   mp->current_data_offset = ntohl (current_data_offset);
9583   clib_memcpy (mp->mask, mask, vec_len (mask));
9584
9585   vec_free (mask);
9586
9587   S (mp);
9588   W (ret);
9589   return ret;
9590 }
9591
9592 #if VPP_API_TEST_BUILTIN == 0
9593 uword
9594 unformat_l4_match (unformat_input_t * input, va_list * args)
9595 {
9596   u8 **matchp = va_arg (*args, u8 **);
9597
9598   u8 *proto_header = 0;
9599   int src_port = 0;
9600   int dst_port = 0;
9601
9602   tcpudp_header_t h;
9603
9604   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9605     {
9606       if (unformat (input, "src_port %d", &src_port))
9607         ;
9608       else if (unformat (input, "dst_port %d", &dst_port))
9609         ;
9610       else
9611         return 0;
9612     }
9613
9614   h.src_port = clib_host_to_net_u16 (src_port);
9615   h.dst_port = clib_host_to_net_u16 (dst_port);
9616   vec_validate (proto_header, sizeof (h) - 1);
9617   memcpy (proto_header, &h, sizeof (h));
9618
9619   *matchp = proto_header;
9620
9621   return 1;
9622 }
9623
9624 uword
9625 unformat_ip4_match (unformat_input_t * input, va_list * args)
9626 {
9627   u8 **matchp = va_arg (*args, u8 **);
9628   u8 *match = 0;
9629   ip4_header_t *ip;
9630   int version = 0;
9631   u32 version_val;
9632   int hdr_length = 0;
9633   u32 hdr_length_val;
9634   int src = 0, dst = 0;
9635   ip4_address_t src_val, dst_val;
9636   int proto = 0;
9637   u32 proto_val;
9638   int tos = 0;
9639   u32 tos_val;
9640   int length = 0;
9641   u32 length_val;
9642   int fragment_id = 0;
9643   u32 fragment_id_val;
9644   int ttl = 0;
9645   int ttl_val;
9646   int checksum = 0;
9647   u32 checksum_val;
9648
9649   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9650     {
9651       if (unformat (input, "version %d", &version_val))
9652         version = 1;
9653       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9654         hdr_length = 1;
9655       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9656         src = 1;
9657       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9658         dst = 1;
9659       else if (unformat (input, "proto %d", &proto_val))
9660         proto = 1;
9661       else if (unformat (input, "tos %d", &tos_val))
9662         tos = 1;
9663       else if (unformat (input, "length %d", &length_val))
9664         length = 1;
9665       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9666         fragment_id = 1;
9667       else if (unformat (input, "ttl %d", &ttl_val))
9668         ttl = 1;
9669       else if (unformat (input, "checksum %d", &checksum_val))
9670         checksum = 1;
9671       else
9672         break;
9673     }
9674
9675   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9676       + ttl + checksum == 0)
9677     return 0;
9678
9679   /*
9680    * Aligned because we use the real comparison functions
9681    */
9682   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9683
9684   ip = (ip4_header_t *) match;
9685
9686   /* These are realistically matched in practice */
9687   if (src)
9688     ip->src_address.as_u32 = src_val.as_u32;
9689
9690   if (dst)
9691     ip->dst_address.as_u32 = dst_val.as_u32;
9692
9693   if (proto)
9694     ip->protocol = proto_val;
9695
9696
9697   /* These are not, but they're included for completeness */
9698   if (version)
9699     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9700
9701   if (hdr_length)
9702     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9703
9704   if (tos)
9705     ip->tos = tos_val;
9706
9707   if (length)
9708     ip->length = clib_host_to_net_u16 (length_val);
9709
9710   if (ttl)
9711     ip->ttl = ttl_val;
9712
9713   if (checksum)
9714     ip->checksum = clib_host_to_net_u16 (checksum_val);
9715
9716   *matchp = match;
9717   return 1;
9718 }
9719
9720 uword
9721 unformat_ip6_match (unformat_input_t * input, va_list * args)
9722 {
9723   u8 **matchp = va_arg (*args, u8 **);
9724   u8 *match = 0;
9725   ip6_header_t *ip;
9726   int version = 0;
9727   u32 version_val;
9728   u8 traffic_class = 0;
9729   u32 traffic_class_val = 0;
9730   u8 flow_label = 0;
9731   u8 flow_label_val;
9732   int src = 0, dst = 0;
9733   ip6_address_t src_val, dst_val;
9734   int proto = 0;
9735   u32 proto_val;
9736   int payload_length = 0;
9737   u32 payload_length_val;
9738   int hop_limit = 0;
9739   int hop_limit_val;
9740   u32 ip_version_traffic_class_and_flow_label;
9741
9742   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9743     {
9744       if (unformat (input, "version %d", &version_val))
9745         version = 1;
9746       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9747         traffic_class = 1;
9748       else if (unformat (input, "flow_label %d", &flow_label_val))
9749         flow_label = 1;
9750       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9751         src = 1;
9752       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9753         dst = 1;
9754       else if (unformat (input, "proto %d", &proto_val))
9755         proto = 1;
9756       else if (unformat (input, "payload_length %d", &payload_length_val))
9757         payload_length = 1;
9758       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9759         hop_limit = 1;
9760       else
9761         break;
9762     }
9763
9764   if (version + traffic_class + flow_label + src + dst + proto +
9765       payload_length + hop_limit == 0)
9766     return 0;
9767
9768   /*
9769    * Aligned because we use the real comparison functions
9770    */
9771   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9772
9773   ip = (ip6_header_t *) match;
9774
9775   if (src)
9776     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9777
9778   if (dst)
9779     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9780
9781   if (proto)
9782     ip->protocol = proto_val;
9783
9784   ip_version_traffic_class_and_flow_label = 0;
9785
9786   if (version)
9787     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9788
9789   if (traffic_class)
9790     ip_version_traffic_class_and_flow_label |=
9791       (traffic_class_val & 0xFF) << 20;
9792
9793   if (flow_label)
9794     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9795
9796   ip->ip_version_traffic_class_and_flow_label =
9797     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9798
9799   if (payload_length)
9800     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9801
9802   if (hop_limit)
9803     ip->hop_limit = hop_limit_val;
9804
9805   *matchp = match;
9806   return 1;
9807 }
9808
9809 uword
9810 unformat_l3_match (unformat_input_t * input, va_list * args)
9811 {
9812   u8 **matchp = va_arg (*args, u8 **);
9813
9814   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9815     {
9816       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9817         return 1;
9818       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9819         return 1;
9820       else
9821         break;
9822     }
9823   return 0;
9824 }
9825
9826 uword
9827 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9828 {
9829   u8 *tagp = va_arg (*args, u8 *);
9830   u32 tag;
9831
9832   if (unformat (input, "%d", &tag))
9833     {
9834       tagp[0] = (tag >> 8) & 0x0F;
9835       tagp[1] = tag & 0xFF;
9836       return 1;
9837     }
9838
9839   return 0;
9840 }
9841
9842 uword
9843 unformat_l2_match (unformat_input_t * input, va_list * args)
9844 {
9845   u8 **matchp = va_arg (*args, u8 **);
9846   u8 *match = 0;
9847   u8 src = 0;
9848   u8 src_val[6];
9849   u8 dst = 0;
9850   u8 dst_val[6];
9851   u8 proto = 0;
9852   u16 proto_val;
9853   u8 tag1 = 0;
9854   u8 tag1_val[2];
9855   u8 tag2 = 0;
9856   u8 tag2_val[2];
9857   int len = 14;
9858   u8 ignore_tag1 = 0;
9859   u8 ignore_tag2 = 0;
9860   u8 cos1 = 0;
9861   u8 cos2 = 0;
9862   u32 cos1_val = 0;
9863   u32 cos2_val = 0;
9864
9865   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9866     {
9867       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9868         src = 1;
9869       else
9870         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9871         dst = 1;
9872       else if (unformat (input, "proto %U",
9873                          unformat_ethernet_type_host_byte_order, &proto_val))
9874         proto = 1;
9875       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9876         tag1 = 1;
9877       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9878         tag2 = 1;
9879       else if (unformat (input, "ignore-tag1"))
9880         ignore_tag1 = 1;
9881       else if (unformat (input, "ignore-tag2"))
9882         ignore_tag2 = 1;
9883       else if (unformat (input, "cos1 %d", &cos1_val))
9884         cos1 = 1;
9885       else if (unformat (input, "cos2 %d", &cos2_val))
9886         cos2 = 1;
9887       else
9888         break;
9889     }
9890   if ((src + dst + proto + tag1 + tag2 +
9891        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9892     return 0;
9893
9894   if (tag1 || ignore_tag1 || cos1)
9895     len = 18;
9896   if (tag2 || ignore_tag2 || cos2)
9897     len = 22;
9898
9899   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9900
9901   if (dst)
9902     clib_memcpy (match, dst_val, 6);
9903
9904   if (src)
9905     clib_memcpy (match + 6, src_val, 6);
9906
9907   if (tag2)
9908     {
9909       /* inner vlan tag */
9910       match[19] = tag2_val[1];
9911       match[18] = tag2_val[0];
9912       if (cos2)
9913         match[18] |= (cos2_val & 0x7) << 5;
9914       if (proto)
9915         {
9916           match[21] = proto_val & 0xff;
9917           match[20] = proto_val >> 8;
9918         }
9919       if (tag1)
9920         {
9921           match[15] = tag1_val[1];
9922           match[14] = tag1_val[0];
9923         }
9924       if (cos1)
9925         match[14] |= (cos1_val & 0x7) << 5;
9926       *matchp = match;
9927       return 1;
9928     }
9929   if (tag1)
9930     {
9931       match[15] = tag1_val[1];
9932       match[14] = tag1_val[0];
9933       if (proto)
9934         {
9935           match[17] = proto_val & 0xff;
9936           match[16] = proto_val >> 8;
9937         }
9938       if (cos1)
9939         match[14] |= (cos1_val & 0x7) << 5;
9940
9941       *matchp = match;
9942       return 1;
9943     }
9944   if (cos2)
9945     match[18] |= (cos2_val & 0x7) << 5;
9946   if (cos1)
9947     match[14] |= (cos1_val & 0x7) << 5;
9948   if (proto)
9949     {
9950       match[13] = proto_val & 0xff;
9951       match[12] = proto_val >> 8;
9952     }
9953
9954   *matchp = match;
9955   return 1;
9956 }
9957 #endif
9958
9959 uword
9960 api_unformat_classify_match (unformat_input_t * input, va_list * args)
9961 {
9962   u8 **matchp = va_arg (*args, u8 **);
9963   u32 skip_n_vectors = va_arg (*args, u32);
9964   u32 match_n_vectors = va_arg (*args, u32);
9965
9966   u8 *match = 0;
9967   u8 *l2 = 0;
9968   u8 *l3 = 0;
9969   u8 *l4 = 0;
9970
9971   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9972     {
9973       if (unformat (input, "hex %U", unformat_hex_string, &match))
9974         ;
9975       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9976         ;
9977       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9978         ;
9979       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9980         ;
9981       else
9982         break;
9983     }
9984
9985   if (l4 && !l3)
9986     {
9987       vec_free (match);
9988       vec_free (l2);
9989       vec_free (l4);
9990       return 0;
9991     }
9992
9993   if (match || l2 || l3 || l4)
9994     {
9995       if (l2 || l3 || l4)
9996         {
9997           /* "Win a free Ethernet header in every packet" */
9998           if (l2 == 0)
9999             vec_validate_aligned (l2, 13, sizeof (u32x4));
10000           match = l2;
10001           if (vec_len (l3))
10002             {
10003               vec_append_aligned (match, l3, sizeof (u32x4));
10004               vec_free (l3);
10005             }
10006           if (vec_len (l4))
10007             {
10008               vec_append_aligned (match, l4, sizeof (u32x4));
10009               vec_free (l4);
10010             }
10011         }
10012
10013       /* Make sure the vector is big enough even if key is all 0's */
10014       vec_validate_aligned
10015         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10016          sizeof (u32x4));
10017
10018       /* Set size, include skipped vectors */
10019       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10020
10021       *matchp = match;
10022
10023       return 1;
10024     }
10025
10026   return 0;
10027 }
10028
10029 static int
10030 api_classify_add_del_session (vat_main_t * vam)
10031 {
10032   unformat_input_t *i = vam->input;
10033   vl_api_classify_add_del_session_t *mp;
10034   int is_add = 1;
10035   u32 table_index = ~0;
10036   u32 hit_next_index = ~0;
10037   u32 opaque_index = ~0;
10038   u8 *match = 0;
10039   i32 advance = 0;
10040   u32 skip_n_vectors = 0;
10041   u32 match_n_vectors = 0;
10042   u32 action = 0;
10043   u32 metadata = 0;
10044   int ret;
10045
10046   /*
10047    * Warning: you have to supply skip_n and match_n
10048    * because the API client cant simply look at the classify
10049    * table object.
10050    */
10051
10052   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10053     {
10054       if (unformat (i, "del"))
10055         is_add = 0;
10056       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10057                          &hit_next_index))
10058         ;
10059       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10060                          &hit_next_index))
10061         ;
10062       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10063                          &hit_next_index))
10064         ;
10065       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10066         ;
10067       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10068         ;
10069       else if (unformat (i, "opaque-index %d", &opaque_index))
10070         ;
10071       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10072         ;
10073       else if (unformat (i, "match_n %d", &match_n_vectors))
10074         ;
10075       else if (unformat (i, "match %U", api_unformat_classify_match,
10076                          &match, skip_n_vectors, match_n_vectors))
10077         ;
10078       else if (unformat (i, "advance %d", &advance))
10079         ;
10080       else if (unformat (i, "table-index %d", &table_index))
10081         ;
10082       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10083         action = 1;
10084       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10085         action = 2;
10086       else if (unformat (i, "action %d", &action))
10087         ;
10088       else if (unformat (i, "metadata %d", &metadata))
10089         ;
10090       else
10091         break;
10092     }
10093
10094   if (table_index == ~0)
10095     {
10096       errmsg ("Table index required");
10097       return -99;
10098     }
10099
10100   if (is_add && match == 0)
10101     {
10102       errmsg ("Match value required");
10103       return -99;
10104     }
10105
10106   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10107
10108   mp->is_add = is_add;
10109   mp->table_index = ntohl (table_index);
10110   mp->hit_next_index = ntohl (hit_next_index);
10111   mp->opaque_index = ntohl (opaque_index);
10112   mp->advance = ntohl (advance);
10113   mp->action = action;
10114   mp->metadata = ntohl (metadata);
10115   clib_memcpy (mp->match, match, vec_len (match));
10116   vec_free (match);
10117
10118   S (mp);
10119   W (ret);
10120   return ret;
10121 }
10122
10123 static int
10124 api_classify_set_interface_ip_table (vat_main_t * vam)
10125 {
10126   unformat_input_t *i = vam->input;
10127   vl_api_classify_set_interface_ip_table_t *mp;
10128   u32 sw_if_index;
10129   int sw_if_index_set;
10130   u32 table_index = ~0;
10131   u8 is_ipv6 = 0;
10132   int ret;
10133
10134   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10135     {
10136       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10137         sw_if_index_set = 1;
10138       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10139         sw_if_index_set = 1;
10140       else if (unformat (i, "table %d", &table_index))
10141         ;
10142       else
10143         {
10144           clib_warning ("parse error '%U'", format_unformat_error, i);
10145           return -99;
10146         }
10147     }
10148
10149   if (sw_if_index_set == 0)
10150     {
10151       errmsg ("missing interface name or sw_if_index");
10152       return -99;
10153     }
10154
10155
10156   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10157
10158   mp->sw_if_index = ntohl (sw_if_index);
10159   mp->table_index = ntohl (table_index);
10160   mp->is_ipv6 = is_ipv6;
10161
10162   S (mp);
10163   W (ret);
10164   return ret;
10165 }
10166
10167 static int
10168 api_classify_set_interface_l2_tables (vat_main_t * vam)
10169 {
10170   unformat_input_t *i = vam->input;
10171   vl_api_classify_set_interface_l2_tables_t *mp;
10172   u32 sw_if_index;
10173   int sw_if_index_set;
10174   u32 ip4_table_index = ~0;
10175   u32 ip6_table_index = ~0;
10176   u32 other_table_index = ~0;
10177   u32 is_input = 1;
10178   int ret;
10179
10180   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10181     {
10182       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10183         sw_if_index_set = 1;
10184       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10185         sw_if_index_set = 1;
10186       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10187         ;
10188       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10189         ;
10190       else if (unformat (i, "other-table %d", &other_table_index))
10191         ;
10192       else if (unformat (i, "is-input %d", &is_input))
10193         ;
10194       else
10195         {
10196           clib_warning ("parse error '%U'", format_unformat_error, i);
10197           return -99;
10198         }
10199     }
10200
10201   if (sw_if_index_set == 0)
10202     {
10203       errmsg ("missing interface name or sw_if_index");
10204       return -99;
10205     }
10206
10207
10208   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10209
10210   mp->sw_if_index = ntohl (sw_if_index);
10211   mp->ip4_table_index = ntohl (ip4_table_index);
10212   mp->ip6_table_index = ntohl (ip6_table_index);
10213   mp->other_table_index = ntohl (other_table_index);
10214   mp->is_input = (u8) is_input;
10215
10216   S (mp);
10217   W (ret);
10218   return ret;
10219 }
10220
10221 static int
10222 api_set_ipfix_exporter (vat_main_t * vam)
10223 {
10224   unformat_input_t *i = vam->input;
10225   vl_api_set_ipfix_exporter_t *mp;
10226   ip4_address_t collector_address;
10227   u8 collector_address_set = 0;
10228   u32 collector_port = ~0;
10229   ip4_address_t src_address;
10230   u8 src_address_set = 0;
10231   u32 vrf_id = ~0;
10232   u32 path_mtu = ~0;
10233   u32 template_interval = ~0;
10234   u8 udp_checksum = 0;
10235   int ret;
10236
10237   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10238     {
10239       if (unformat (i, "collector_address %U", unformat_ip4_address,
10240                     &collector_address))
10241         collector_address_set = 1;
10242       else if (unformat (i, "collector_port %d", &collector_port))
10243         ;
10244       else if (unformat (i, "src_address %U", unformat_ip4_address,
10245                          &src_address))
10246         src_address_set = 1;
10247       else if (unformat (i, "vrf_id %d", &vrf_id))
10248         ;
10249       else if (unformat (i, "path_mtu %d", &path_mtu))
10250         ;
10251       else if (unformat (i, "template_interval %d", &template_interval))
10252         ;
10253       else if (unformat (i, "udp_checksum"))
10254         udp_checksum = 1;
10255       else
10256         break;
10257     }
10258
10259   if (collector_address_set == 0)
10260     {
10261       errmsg ("collector_address required");
10262       return -99;
10263     }
10264
10265   if (src_address_set == 0)
10266     {
10267       errmsg ("src_address required");
10268       return -99;
10269     }
10270
10271   M (SET_IPFIX_EXPORTER, mp);
10272
10273   memcpy (mp->collector_address, collector_address.data,
10274           sizeof (collector_address.data));
10275   mp->collector_port = htons ((u16) collector_port);
10276   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
10277   mp->vrf_id = htonl (vrf_id);
10278   mp->path_mtu = htonl (path_mtu);
10279   mp->template_interval = htonl (template_interval);
10280   mp->udp_checksum = udp_checksum;
10281
10282   S (mp);
10283   W (ret);
10284   return ret;
10285 }
10286
10287 static int
10288 api_set_ipfix_classify_stream (vat_main_t * vam)
10289 {
10290   unformat_input_t *i = vam->input;
10291   vl_api_set_ipfix_classify_stream_t *mp;
10292   u32 domain_id = 0;
10293   u32 src_port = UDP_DST_PORT_ipfix;
10294   int ret;
10295
10296   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10297     {
10298       if (unformat (i, "domain %d", &domain_id))
10299         ;
10300       else if (unformat (i, "src_port %d", &src_port))
10301         ;
10302       else
10303         {
10304           errmsg ("unknown input `%U'", format_unformat_error, i);
10305           return -99;
10306         }
10307     }
10308
10309   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10310
10311   mp->domain_id = htonl (domain_id);
10312   mp->src_port = htons ((u16) src_port);
10313
10314   S (mp);
10315   W (ret);
10316   return ret;
10317 }
10318
10319 static int
10320 api_ipfix_classify_table_add_del (vat_main_t * vam)
10321 {
10322   unformat_input_t *i = vam->input;
10323   vl_api_ipfix_classify_table_add_del_t *mp;
10324   int is_add = -1;
10325   u32 classify_table_index = ~0;
10326   u8 ip_version = 0;
10327   u8 transport_protocol = 255;
10328   int ret;
10329
10330   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10331     {
10332       if (unformat (i, "add"))
10333         is_add = 1;
10334       else if (unformat (i, "del"))
10335         is_add = 0;
10336       else if (unformat (i, "table %d", &classify_table_index))
10337         ;
10338       else if (unformat (i, "ip4"))
10339         ip_version = 4;
10340       else if (unformat (i, "ip6"))
10341         ip_version = 6;
10342       else if (unformat (i, "tcp"))
10343         transport_protocol = 6;
10344       else if (unformat (i, "udp"))
10345         transport_protocol = 17;
10346       else
10347         {
10348           errmsg ("unknown input `%U'", format_unformat_error, i);
10349           return -99;
10350         }
10351     }
10352
10353   if (is_add == -1)
10354     {
10355       errmsg ("expecting: add|del");
10356       return -99;
10357     }
10358   if (classify_table_index == ~0)
10359     {
10360       errmsg ("classifier table not specified");
10361       return -99;
10362     }
10363   if (ip_version == 0)
10364     {
10365       errmsg ("IP version not specified");
10366       return -99;
10367     }
10368
10369   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10370
10371   mp->is_add = is_add;
10372   mp->table_id = htonl (classify_table_index);
10373   mp->ip_version = ip_version;
10374   mp->transport_protocol = transport_protocol;
10375
10376   S (mp);
10377   W (ret);
10378   return ret;
10379 }
10380
10381 static int
10382 api_get_node_index (vat_main_t * vam)
10383 {
10384   unformat_input_t *i = vam->input;
10385   vl_api_get_node_index_t *mp;
10386   u8 *name = 0;
10387   int ret;
10388
10389   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10390     {
10391       if (unformat (i, "node %s", &name))
10392         ;
10393       else
10394         break;
10395     }
10396   if (name == 0)
10397     {
10398       errmsg ("node name required");
10399       return -99;
10400     }
10401   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10402     {
10403       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10404       return -99;
10405     }
10406
10407   M (GET_NODE_INDEX, mp);
10408   clib_memcpy (mp->node_name, name, vec_len (name));
10409   vec_free (name);
10410
10411   S (mp);
10412   W (ret);
10413   return ret;
10414 }
10415
10416 static int
10417 api_get_next_index (vat_main_t * vam)
10418 {
10419   unformat_input_t *i = vam->input;
10420   vl_api_get_next_index_t *mp;
10421   u8 *node_name = 0, *next_node_name = 0;
10422   int ret;
10423
10424   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10425     {
10426       if (unformat (i, "node-name %s", &node_name))
10427         ;
10428       else if (unformat (i, "next-node-name %s", &next_node_name))
10429         break;
10430     }
10431
10432   if (node_name == 0)
10433     {
10434       errmsg ("node name required");
10435       return -99;
10436     }
10437   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10438     {
10439       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10440       return -99;
10441     }
10442
10443   if (next_node_name == 0)
10444     {
10445       errmsg ("next node name required");
10446       return -99;
10447     }
10448   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10449     {
10450       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10451       return -99;
10452     }
10453
10454   M (GET_NEXT_INDEX, mp);
10455   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10456   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10457   vec_free (node_name);
10458   vec_free (next_node_name);
10459
10460   S (mp);
10461   W (ret);
10462   return ret;
10463 }
10464
10465 static int
10466 api_add_node_next (vat_main_t * vam)
10467 {
10468   unformat_input_t *i = vam->input;
10469   vl_api_add_node_next_t *mp;
10470   u8 *name = 0;
10471   u8 *next = 0;
10472   int ret;
10473
10474   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10475     {
10476       if (unformat (i, "node %s", &name))
10477         ;
10478       else if (unformat (i, "next %s", &next))
10479         ;
10480       else
10481         break;
10482     }
10483   if (name == 0)
10484     {
10485       errmsg ("node name required");
10486       return -99;
10487     }
10488   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10489     {
10490       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10491       return -99;
10492     }
10493   if (next == 0)
10494     {
10495       errmsg ("next node required");
10496       return -99;
10497     }
10498   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10499     {
10500       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10501       return -99;
10502     }
10503
10504   M (ADD_NODE_NEXT, mp);
10505   clib_memcpy (mp->node_name, name, vec_len (name));
10506   clib_memcpy (mp->next_name, next, vec_len (next));
10507   vec_free (name);
10508   vec_free (next);
10509
10510   S (mp);
10511   W (ret);
10512   return ret;
10513 }
10514
10515 static int
10516 api_l2tpv3_create_tunnel (vat_main_t * vam)
10517 {
10518   unformat_input_t *i = vam->input;
10519   ip6_address_t client_address, our_address;
10520   int client_address_set = 0;
10521   int our_address_set = 0;
10522   u32 local_session_id = 0;
10523   u32 remote_session_id = 0;
10524   u64 local_cookie = 0;
10525   u64 remote_cookie = 0;
10526   u8 l2_sublayer_present = 0;
10527   vl_api_l2tpv3_create_tunnel_t *mp;
10528   int ret;
10529
10530   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10531     {
10532       if (unformat (i, "client_address %U", unformat_ip6_address,
10533                     &client_address))
10534         client_address_set = 1;
10535       else if (unformat (i, "our_address %U", unformat_ip6_address,
10536                          &our_address))
10537         our_address_set = 1;
10538       else if (unformat (i, "local_session_id %d", &local_session_id))
10539         ;
10540       else if (unformat (i, "remote_session_id %d", &remote_session_id))
10541         ;
10542       else if (unformat (i, "local_cookie %lld", &local_cookie))
10543         ;
10544       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10545         ;
10546       else if (unformat (i, "l2-sublayer-present"))
10547         l2_sublayer_present = 1;
10548       else
10549         break;
10550     }
10551
10552   if (client_address_set == 0)
10553     {
10554       errmsg ("client_address required");
10555       return -99;
10556     }
10557
10558   if (our_address_set == 0)
10559     {
10560       errmsg ("our_address required");
10561       return -99;
10562     }
10563
10564   M (L2TPV3_CREATE_TUNNEL, mp);
10565
10566   clib_memcpy (mp->client_address, client_address.as_u8,
10567                sizeof (mp->client_address));
10568
10569   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10570
10571   mp->local_session_id = ntohl (local_session_id);
10572   mp->remote_session_id = ntohl (remote_session_id);
10573   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10574   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10575   mp->l2_sublayer_present = l2_sublayer_present;
10576   mp->is_ipv6 = 1;
10577
10578   S (mp);
10579   W (ret);
10580   return ret;
10581 }
10582
10583 static int
10584 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10585 {
10586   unformat_input_t *i = vam->input;
10587   u32 sw_if_index;
10588   u8 sw_if_index_set = 0;
10589   u64 new_local_cookie = 0;
10590   u64 new_remote_cookie = 0;
10591   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10592   int ret;
10593
10594   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10595     {
10596       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10597         sw_if_index_set = 1;
10598       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10599         sw_if_index_set = 1;
10600       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10601         ;
10602       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10603         ;
10604       else
10605         break;
10606     }
10607
10608   if (sw_if_index_set == 0)
10609     {
10610       errmsg ("missing interface name or sw_if_index");
10611       return -99;
10612     }
10613
10614   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
10615
10616   mp->sw_if_index = ntohl (sw_if_index);
10617   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10618   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10619
10620   S (mp);
10621   W (ret);
10622   return ret;
10623 }
10624
10625 static int
10626 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10627 {
10628   unformat_input_t *i = vam->input;
10629   vl_api_l2tpv3_interface_enable_disable_t *mp;
10630   u32 sw_if_index;
10631   u8 sw_if_index_set = 0;
10632   u8 enable_disable = 1;
10633   int ret;
10634
10635   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10636     {
10637       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10638         sw_if_index_set = 1;
10639       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10640         sw_if_index_set = 1;
10641       else if (unformat (i, "enable"))
10642         enable_disable = 1;
10643       else if (unformat (i, "disable"))
10644         enable_disable = 0;
10645       else
10646         break;
10647     }
10648
10649   if (sw_if_index_set == 0)
10650     {
10651       errmsg ("missing interface name or sw_if_index");
10652       return -99;
10653     }
10654
10655   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
10656
10657   mp->sw_if_index = ntohl (sw_if_index);
10658   mp->enable_disable = enable_disable;
10659
10660   S (mp);
10661   W (ret);
10662   return ret;
10663 }
10664
10665 static int
10666 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10667 {
10668   unformat_input_t *i = vam->input;
10669   vl_api_l2tpv3_set_lookup_key_t *mp;
10670   u8 key = ~0;
10671   int ret;
10672
10673   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10674     {
10675       if (unformat (i, "lookup_v6_src"))
10676         key = L2T_LOOKUP_SRC_ADDRESS;
10677       else if (unformat (i, "lookup_v6_dst"))
10678         key = L2T_LOOKUP_DST_ADDRESS;
10679       else if (unformat (i, "lookup_session_id"))
10680         key = L2T_LOOKUP_SESSION_ID;
10681       else
10682         break;
10683     }
10684
10685   if (key == (u8) ~ 0)
10686     {
10687       errmsg ("l2tp session lookup key unset");
10688       return -99;
10689     }
10690
10691   M (L2TPV3_SET_LOOKUP_KEY, mp);
10692
10693   mp->key = key;
10694
10695   S (mp);
10696   W (ret);
10697   return ret;
10698 }
10699
10700 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10701   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10702 {
10703   vat_main_t *vam = &vat_main;
10704
10705   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10706          format_ip6_address, mp->our_address,
10707          format_ip6_address, mp->client_address,
10708          clib_net_to_host_u32 (mp->sw_if_index));
10709
10710   print (vam->ofp,
10711          "   local cookies %016llx %016llx remote cookie %016llx",
10712          clib_net_to_host_u64 (mp->local_cookie[0]),
10713          clib_net_to_host_u64 (mp->local_cookie[1]),
10714          clib_net_to_host_u64 (mp->remote_cookie));
10715
10716   print (vam->ofp, "   local session-id %d remote session-id %d",
10717          clib_net_to_host_u32 (mp->local_session_id),
10718          clib_net_to_host_u32 (mp->remote_session_id));
10719
10720   print (vam->ofp, "   l2 specific sublayer %s\n",
10721          mp->l2_sublayer_present ? "preset" : "absent");
10722
10723 }
10724
10725 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10726   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10727 {
10728   vat_main_t *vam = &vat_main;
10729   vat_json_node_t *node = NULL;
10730   struct in6_addr addr;
10731
10732   if (VAT_JSON_ARRAY != vam->json_tree.type)
10733     {
10734       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10735       vat_json_init_array (&vam->json_tree);
10736     }
10737   node = vat_json_array_add (&vam->json_tree);
10738
10739   vat_json_init_object (node);
10740
10741   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10742   vat_json_object_add_ip6 (node, "our_address", addr);
10743   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10744   vat_json_object_add_ip6 (node, "client_address", addr);
10745
10746   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10747   vat_json_init_array (lc);
10748   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10749   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10750   vat_json_object_add_uint (node, "remote_cookie",
10751                             clib_net_to_host_u64 (mp->remote_cookie));
10752
10753   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10754   vat_json_object_add_uint (node, "local_session_id",
10755                             clib_net_to_host_u32 (mp->local_session_id));
10756   vat_json_object_add_uint (node, "remote_session_id",
10757                             clib_net_to_host_u32 (mp->remote_session_id));
10758   vat_json_object_add_string_copy (node, "l2_sublayer",
10759                                    mp->l2_sublayer_present ? (u8 *) "present"
10760                                    : (u8 *) "absent");
10761 }
10762
10763 static int
10764 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10765 {
10766   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10767   vl_api_control_ping_t *mp_ping;
10768   int ret;
10769
10770   /* Get list of l2tpv3-tunnel interfaces */
10771   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
10772   S (mp);
10773
10774   /* Use a control ping for synchronization */
10775   M (CONTROL_PING, mp_ping);
10776   S (mp_ping);
10777
10778   W (ret);
10779   return ret;
10780 }
10781
10782
10783 static void vl_api_sw_interface_tap_details_t_handler
10784   (vl_api_sw_interface_tap_details_t * mp)
10785 {
10786   vat_main_t *vam = &vat_main;
10787
10788   print (vam->ofp, "%-16s %d",
10789          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10790 }
10791
10792 static void vl_api_sw_interface_tap_details_t_handler_json
10793   (vl_api_sw_interface_tap_details_t * mp)
10794 {
10795   vat_main_t *vam = &vat_main;
10796   vat_json_node_t *node = NULL;
10797
10798   if (VAT_JSON_ARRAY != vam->json_tree.type)
10799     {
10800       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10801       vat_json_init_array (&vam->json_tree);
10802     }
10803   node = vat_json_array_add (&vam->json_tree);
10804
10805   vat_json_init_object (node);
10806   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10807   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10808 }
10809
10810 static int
10811 api_sw_interface_tap_dump (vat_main_t * vam)
10812 {
10813   vl_api_sw_interface_tap_dump_t *mp;
10814   vl_api_control_ping_t *mp_ping;
10815   int ret;
10816
10817   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10818   /* Get list of tap interfaces */
10819   M (SW_INTERFACE_TAP_DUMP, mp);
10820   S (mp);
10821
10822   /* Use a control ping for synchronization */
10823   M (CONTROL_PING, mp_ping);
10824   S (mp_ping);
10825
10826   W (ret);
10827   return ret;
10828 }
10829
10830 static uword unformat_vxlan_decap_next
10831   (unformat_input_t * input, va_list * args)
10832 {
10833   u32 *result = va_arg (*args, u32 *);
10834   u32 tmp;
10835
10836   if (unformat (input, "l2"))
10837     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10838   else if (unformat (input, "%d", &tmp))
10839     *result = tmp;
10840   else
10841     return 0;
10842   return 1;
10843 }
10844
10845 static int
10846 api_vxlan_add_del_tunnel (vat_main_t * vam)
10847 {
10848   unformat_input_t *line_input = vam->input;
10849   vl_api_vxlan_add_del_tunnel_t *mp;
10850   ip46_address_t src, dst;
10851   u8 is_add = 1;
10852   u8 ipv4_set = 0, ipv6_set = 0;
10853   u8 src_set = 0;
10854   u8 dst_set = 0;
10855   u8 grp_set = 0;
10856   u32 mcast_sw_if_index = ~0;
10857   u32 encap_vrf_id = 0;
10858   u32 decap_next_index = ~0;
10859   u32 vni = 0;
10860   int ret;
10861
10862   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10863   memset (&src, 0, sizeof src);
10864   memset (&dst, 0, sizeof dst);
10865
10866   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10867     {
10868       if (unformat (line_input, "del"))
10869         is_add = 0;
10870       else
10871         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10872         {
10873           ipv4_set = 1;
10874           src_set = 1;
10875         }
10876       else
10877         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10878         {
10879           ipv4_set = 1;
10880           dst_set = 1;
10881         }
10882       else
10883         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10884         {
10885           ipv6_set = 1;
10886           src_set = 1;
10887         }
10888       else
10889         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10890         {
10891           ipv6_set = 1;
10892           dst_set = 1;
10893         }
10894       else if (unformat (line_input, "group %U %U",
10895                          unformat_ip4_address, &dst.ip4,
10896                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10897         {
10898           grp_set = dst_set = 1;
10899           ipv4_set = 1;
10900         }
10901       else if (unformat (line_input, "group %U",
10902                          unformat_ip4_address, &dst.ip4))
10903         {
10904           grp_set = dst_set = 1;
10905           ipv4_set = 1;
10906         }
10907       else if (unformat (line_input, "group %U %U",
10908                          unformat_ip6_address, &dst.ip6,
10909                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10910         {
10911           grp_set = dst_set = 1;
10912           ipv6_set = 1;
10913         }
10914       else if (unformat (line_input, "group %U",
10915                          unformat_ip6_address, &dst.ip6))
10916         {
10917           grp_set = dst_set = 1;
10918           ipv6_set = 1;
10919         }
10920       else
10921         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10922         ;
10923       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10924         ;
10925       else if (unformat (line_input, "decap-next %U",
10926                          unformat_vxlan_decap_next, &decap_next_index))
10927         ;
10928       else if (unformat (line_input, "vni %d", &vni))
10929         ;
10930       else
10931         {
10932           errmsg ("parse error '%U'", format_unformat_error, line_input);
10933           return -99;
10934         }
10935     }
10936
10937   if (src_set == 0)
10938     {
10939       errmsg ("tunnel src address not specified");
10940       return -99;
10941     }
10942   if (dst_set == 0)
10943     {
10944       errmsg ("tunnel dst address not specified");
10945       return -99;
10946     }
10947
10948   if (grp_set && !ip46_address_is_multicast (&dst))
10949     {
10950       errmsg ("tunnel group address not multicast");
10951       return -99;
10952     }
10953   if (grp_set && mcast_sw_if_index == ~0)
10954     {
10955       errmsg ("tunnel nonexistent multicast device");
10956       return -99;
10957     }
10958   if (grp_set == 0 && ip46_address_is_multicast (&dst))
10959     {
10960       errmsg ("tunnel dst address must be unicast");
10961       return -99;
10962     }
10963
10964
10965   if (ipv4_set && ipv6_set)
10966     {
10967       errmsg ("both IPv4 and IPv6 addresses specified");
10968       return -99;
10969     }
10970
10971   if ((vni == 0) || (vni >> 24))
10972     {
10973       errmsg ("vni not specified or out of range");
10974       return -99;
10975     }
10976
10977   M (VXLAN_ADD_DEL_TUNNEL, mp);
10978
10979   if (ipv6_set)
10980     {
10981       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10982       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10983     }
10984   else
10985     {
10986       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10987       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10988     }
10989   mp->encap_vrf_id = ntohl (encap_vrf_id);
10990   mp->decap_next_index = ntohl (decap_next_index);
10991   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10992   mp->vni = ntohl (vni);
10993   mp->is_add = is_add;
10994   mp->is_ipv6 = ipv6_set;
10995
10996   S (mp);
10997   W (ret);
10998   return ret;
10999 }
11000
11001 static void vl_api_vxlan_tunnel_details_t_handler
11002   (vl_api_vxlan_tunnel_details_t * mp)
11003 {
11004   vat_main_t *vam = &vat_main;
11005   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
11006   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
11007
11008   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
11009          ntohl (mp->sw_if_index),
11010          format_ip46_address, &src, IP46_TYPE_ANY,
11011          format_ip46_address, &dst, IP46_TYPE_ANY,
11012          ntohl (mp->encap_vrf_id),
11013          ntohl (mp->decap_next_index), ntohl (mp->vni),
11014          ntohl (mp->mcast_sw_if_index));
11015 }
11016
11017 static void vl_api_vxlan_tunnel_details_t_handler_json
11018   (vl_api_vxlan_tunnel_details_t * mp)
11019 {
11020   vat_main_t *vam = &vat_main;
11021   vat_json_node_t *node = NULL;
11022
11023   if (VAT_JSON_ARRAY != vam->json_tree.type)
11024     {
11025       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11026       vat_json_init_array (&vam->json_tree);
11027     }
11028   node = vat_json_array_add (&vam->json_tree);
11029
11030   vat_json_init_object (node);
11031   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11032   if (mp->is_ipv6)
11033     {
11034       struct in6_addr ip6;
11035
11036       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
11037       vat_json_object_add_ip6 (node, "src_address", ip6);
11038       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
11039       vat_json_object_add_ip6 (node, "dst_address", ip6);
11040     }
11041   else
11042     {
11043       struct in_addr ip4;
11044
11045       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
11046       vat_json_object_add_ip4 (node, "src_address", ip4);
11047       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
11048       vat_json_object_add_ip4 (node, "dst_address", ip4);
11049     }
11050   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11051   vat_json_object_add_uint (node, "decap_next_index",
11052                             ntohl (mp->decap_next_index));
11053   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11054   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11055   vat_json_object_add_uint (node, "mcast_sw_if_index",
11056                             ntohl (mp->mcast_sw_if_index));
11057 }
11058
11059 static int
11060 api_vxlan_tunnel_dump (vat_main_t * vam)
11061 {
11062   unformat_input_t *i = vam->input;
11063   vl_api_vxlan_tunnel_dump_t *mp;
11064   vl_api_control_ping_t *mp_ping;
11065   u32 sw_if_index;
11066   u8 sw_if_index_set = 0;
11067   int ret;
11068
11069   /* Parse args required to build the message */
11070   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11071     {
11072       if (unformat (i, "sw_if_index %d", &sw_if_index))
11073         sw_if_index_set = 1;
11074       else
11075         break;
11076     }
11077
11078   if (sw_if_index_set == 0)
11079     {
11080       sw_if_index = ~0;
11081     }
11082
11083   if (!vam->json_output)
11084     {
11085       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
11086              "sw_if_index", "src_address", "dst_address",
11087              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11088     }
11089
11090   /* Get list of vxlan-tunnel interfaces */
11091   M (VXLAN_TUNNEL_DUMP, mp);
11092
11093   mp->sw_if_index = htonl (sw_if_index);
11094
11095   S (mp);
11096
11097   /* Use a control ping for synchronization */
11098   M (CONTROL_PING, mp_ping);
11099   S (mp_ping);
11100
11101   W (ret);
11102   return ret;
11103 }
11104
11105 static int
11106 api_gre_add_del_tunnel (vat_main_t * vam)
11107 {
11108   unformat_input_t *line_input = vam->input;
11109   vl_api_gre_add_del_tunnel_t *mp;
11110   ip4_address_t src4, dst4;
11111   ip6_address_t src6, dst6;
11112   u8 is_add = 1;
11113   u8 ipv4_set = 0;
11114   u8 ipv6_set = 0;
11115   u8 teb = 0;
11116   u8 src_set = 0;
11117   u8 dst_set = 0;
11118   u32 outer_fib_id = 0;
11119   int ret;
11120
11121   memset (&src4, 0, sizeof src4);
11122   memset (&dst4, 0, sizeof dst4);
11123   memset (&src6, 0, sizeof src6);
11124   memset (&dst6, 0, sizeof dst6);
11125
11126   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11127     {
11128       if (unformat (line_input, "del"))
11129         is_add = 0;
11130       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
11131         {
11132           src_set = 1;
11133           ipv4_set = 1;
11134         }
11135       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
11136         {
11137           dst_set = 1;
11138           ipv4_set = 1;
11139         }
11140       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
11141         {
11142           src_set = 1;
11143           ipv6_set = 1;
11144         }
11145       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
11146         {
11147           dst_set = 1;
11148           ipv6_set = 1;
11149         }
11150       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
11151         ;
11152       else if (unformat (line_input, "teb"))
11153         teb = 1;
11154       else
11155         {
11156           errmsg ("parse error '%U'", format_unformat_error, line_input);
11157           return -99;
11158         }
11159     }
11160
11161   if (src_set == 0)
11162     {
11163       errmsg ("tunnel src address not specified");
11164       return -99;
11165     }
11166   if (dst_set == 0)
11167     {
11168       errmsg ("tunnel dst address not specified");
11169       return -99;
11170     }
11171   if (ipv4_set && ipv6_set)
11172     {
11173       errmsg ("both IPv4 and IPv6 addresses specified");
11174       return -99;
11175     }
11176
11177
11178   M (GRE_ADD_DEL_TUNNEL, mp);
11179
11180   if (ipv4_set)
11181     {
11182       clib_memcpy (&mp->src_address, &src4, 4);
11183       clib_memcpy (&mp->dst_address, &dst4, 4);
11184     }
11185   else
11186     {
11187       clib_memcpy (&mp->src_address, &src6, 16);
11188       clib_memcpy (&mp->dst_address, &dst6, 16);
11189     }
11190   mp->outer_fib_id = ntohl (outer_fib_id);
11191   mp->is_add = is_add;
11192   mp->teb = teb;
11193   mp->is_ipv6 = ipv6_set;
11194
11195   S (mp);
11196   W (ret);
11197   return ret;
11198 }
11199
11200 static void vl_api_gre_tunnel_details_t_handler
11201   (vl_api_gre_tunnel_details_t * mp)
11202 {
11203   vat_main_t *vam = &vat_main;
11204   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
11205   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
11206
11207   print (vam->ofp, "%11d%24U%24U%6d%14d",
11208          ntohl (mp->sw_if_index),
11209          format_ip46_address, &src, IP46_TYPE_ANY,
11210          format_ip46_address, &dst, IP46_TYPE_ANY,
11211          mp->teb, ntohl (mp->outer_fib_id));
11212 }
11213
11214 static void vl_api_gre_tunnel_details_t_handler_json
11215   (vl_api_gre_tunnel_details_t * mp)
11216 {
11217   vat_main_t *vam = &vat_main;
11218   vat_json_node_t *node = NULL;
11219   struct in_addr ip4;
11220   struct in6_addr ip6;
11221
11222   if (VAT_JSON_ARRAY != vam->json_tree.type)
11223     {
11224       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11225       vat_json_init_array (&vam->json_tree);
11226     }
11227   node = vat_json_array_add (&vam->json_tree);
11228
11229   vat_json_init_object (node);
11230   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11231   if (!mp->is_ipv6)
11232     {
11233       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
11234       vat_json_object_add_ip4 (node, "src_address", ip4);
11235       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
11236       vat_json_object_add_ip4 (node, "dst_address", ip4);
11237     }
11238   else
11239     {
11240       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
11241       vat_json_object_add_ip6 (node, "src_address", ip6);
11242       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
11243       vat_json_object_add_ip6 (node, "dst_address", ip6);
11244     }
11245   vat_json_object_add_uint (node, "teb", mp->teb);
11246   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
11247   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
11248 }
11249
11250 static int
11251 api_gre_tunnel_dump (vat_main_t * vam)
11252 {
11253   unformat_input_t *i = vam->input;
11254   vl_api_gre_tunnel_dump_t *mp;
11255   vl_api_control_ping_t *mp_ping;
11256   u32 sw_if_index;
11257   u8 sw_if_index_set = 0;
11258   int ret;
11259
11260   /* Parse args required to build the message */
11261   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11262     {
11263       if (unformat (i, "sw_if_index %d", &sw_if_index))
11264         sw_if_index_set = 1;
11265       else
11266         break;
11267     }
11268
11269   if (sw_if_index_set == 0)
11270     {
11271       sw_if_index = ~0;
11272     }
11273
11274   if (!vam->json_output)
11275     {
11276       print (vam->ofp, "%11s%24s%24s%6s%14s",
11277              "sw_if_index", "src_address", "dst_address", "teb",
11278              "outer_fib_id");
11279     }
11280
11281   /* Get list of gre-tunnel interfaces */
11282   M (GRE_TUNNEL_DUMP, mp);
11283
11284   mp->sw_if_index = htonl (sw_if_index);
11285
11286   S (mp);
11287
11288   /* Use a control ping for synchronization */
11289   M (CONTROL_PING, mp_ping);
11290   S (mp_ping);
11291
11292   W (ret);
11293   return ret;
11294 }
11295
11296 static int
11297 api_l2_fib_clear_table (vat_main_t * vam)
11298 {
11299 //  unformat_input_t * i = vam->input;
11300   vl_api_l2_fib_clear_table_t *mp;
11301   int ret;
11302
11303   M (L2_FIB_CLEAR_TABLE, mp);
11304
11305   S (mp);
11306   W (ret);
11307   return ret;
11308 }
11309
11310 static int
11311 api_l2_interface_efp_filter (vat_main_t * vam)
11312 {
11313   unformat_input_t *i = vam->input;
11314   vl_api_l2_interface_efp_filter_t *mp;
11315   u32 sw_if_index;
11316   u8 enable = 1;
11317   u8 sw_if_index_set = 0;
11318   int ret;
11319
11320   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11321     {
11322       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11323         sw_if_index_set = 1;
11324       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11325         sw_if_index_set = 1;
11326       else if (unformat (i, "enable"))
11327         enable = 1;
11328       else if (unformat (i, "disable"))
11329         enable = 0;
11330       else
11331         {
11332           clib_warning ("parse error '%U'", format_unformat_error, i);
11333           return -99;
11334         }
11335     }
11336
11337   if (sw_if_index_set == 0)
11338     {
11339       errmsg ("missing sw_if_index");
11340       return -99;
11341     }
11342
11343   M (L2_INTERFACE_EFP_FILTER, mp);
11344
11345   mp->sw_if_index = ntohl (sw_if_index);
11346   mp->enable_disable = enable;
11347
11348   S (mp);
11349   W (ret);
11350   return ret;
11351 }
11352
11353 #define foreach_vtr_op                          \
11354 _("disable",  L2_VTR_DISABLED)                  \
11355 _("push-1",  L2_VTR_PUSH_1)                     \
11356 _("push-2",  L2_VTR_PUSH_2)                     \
11357 _("pop-1",  L2_VTR_POP_1)                       \
11358 _("pop-2",  L2_VTR_POP_2)                       \
11359 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
11360 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
11361 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
11362 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
11363
11364 static int
11365 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
11366 {
11367   unformat_input_t *i = vam->input;
11368   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
11369   u32 sw_if_index;
11370   u8 sw_if_index_set = 0;
11371   u8 vtr_op_set = 0;
11372   u32 vtr_op = 0;
11373   u32 push_dot1q = 1;
11374   u32 tag1 = ~0;
11375   u32 tag2 = ~0;
11376   int ret;
11377
11378   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11379     {
11380       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11381         sw_if_index_set = 1;
11382       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11383         sw_if_index_set = 1;
11384       else if (unformat (i, "vtr_op %d", &vtr_op))
11385         vtr_op_set = 1;
11386 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
11387       foreach_vtr_op
11388 #undef _
11389         else if (unformat (i, "push_dot1q %d", &push_dot1q))
11390         ;
11391       else if (unformat (i, "tag1 %d", &tag1))
11392         ;
11393       else if (unformat (i, "tag2 %d", &tag2))
11394         ;
11395       else
11396         {
11397           clib_warning ("parse error '%U'", format_unformat_error, i);
11398           return -99;
11399         }
11400     }
11401
11402   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
11403     {
11404       errmsg ("missing vtr operation or sw_if_index");
11405       return -99;
11406     }
11407
11408   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
11409   mp->sw_if_index = ntohl (sw_if_index);
11410   mp->vtr_op = ntohl (vtr_op);
11411   mp->push_dot1q = ntohl (push_dot1q);
11412   mp->tag1 = ntohl (tag1);
11413   mp->tag2 = ntohl (tag2);
11414
11415   S (mp);
11416   W (ret);
11417   return ret;
11418 }
11419
11420 static int
11421 api_create_vhost_user_if (vat_main_t * vam)
11422 {
11423   unformat_input_t *i = vam->input;
11424   vl_api_create_vhost_user_if_t *mp;
11425   u8 *file_name;
11426   u8 is_server = 0;
11427   u8 file_name_set = 0;
11428   u32 custom_dev_instance = ~0;
11429   u8 hwaddr[6];
11430   u8 use_custom_mac = 0;
11431   u8 *tag = 0;
11432   int ret;
11433   u8 operation_mode = VHOST_USER_POLLING_MODE;
11434
11435   /* Shut up coverity */
11436   memset (hwaddr, 0, sizeof (hwaddr));
11437
11438   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11439     {
11440       if (unformat (i, "socket %s", &file_name))
11441         {
11442           file_name_set = 1;
11443         }
11444       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11445         ;
11446       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
11447         use_custom_mac = 1;
11448       else if (unformat (i, "server"))
11449         is_server = 1;
11450       else if (unformat (i, "tag %s", &tag))
11451         ;
11452       else if (unformat (i, "mode %U",
11453                          api_unformat_vhost_user_operation_mode,
11454                          &operation_mode))
11455         ;
11456       else
11457         break;
11458     }
11459
11460   if (file_name_set == 0)
11461     {
11462       errmsg ("missing socket file name");
11463       return -99;
11464     }
11465
11466   if (vec_len (file_name) > 255)
11467     {
11468       errmsg ("socket file name too long");
11469       return -99;
11470     }
11471   vec_add1 (file_name, 0);
11472
11473   M (CREATE_VHOST_USER_IF, mp);
11474
11475   mp->operation_mode = operation_mode;
11476   mp->is_server = is_server;
11477   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11478   vec_free (file_name);
11479   if (custom_dev_instance != ~0)
11480     {
11481       mp->renumber = 1;
11482       mp->custom_dev_instance = ntohl (custom_dev_instance);
11483     }
11484   mp->use_custom_mac = use_custom_mac;
11485   clib_memcpy (mp->mac_address, hwaddr, 6);
11486   if (tag)
11487     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
11488   vec_free (tag);
11489
11490   S (mp);
11491   W (ret);
11492   return ret;
11493 }
11494
11495 static int
11496 api_modify_vhost_user_if (vat_main_t * vam)
11497 {
11498   unformat_input_t *i = vam->input;
11499   vl_api_modify_vhost_user_if_t *mp;
11500   u8 *file_name;
11501   u8 is_server = 0;
11502   u8 file_name_set = 0;
11503   u32 custom_dev_instance = ~0;
11504   u8 sw_if_index_set = 0;
11505   u32 sw_if_index = (u32) ~ 0;
11506   int ret;
11507   u8 operation_mode = VHOST_USER_POLLING_MODE;
11508
11509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11510     {
11511       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11512         sw_if_index_set = 1;
11513       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11514         sw_if_index_set = 1;
11515       else if (unformat (i, "socket %s", &file_name))
11516         {
11517           file_name_set = 1;
11518         }
11519       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11520         ;
11521       else if (unformat (i, "server"))
11522         is_server = 1;
11523       else if (unformat (i, "mode %U",
11524                          api_unformat_vhost_user_operation_mode,
11525                          &operation_mode))
11526         ;
11527       else
11528         break;
11529     }
11530
11531   if (sw_if_index_set == 0)
11532     {
11533       errmsg ("missing sw_if_index or interface name");
11534       return -99;
11535     }
11536
11537   if (file_name_set == 0)
11538     {
11539       errmsg ("missing socket file name");
11540       return -99;
11541     }
11542
11543   if (vec_len (file_name) > 255)
11544     {
11545       errmsg ("socket file name too long");
11546       return -99;
11547     }
11548   vec_add1 (file_name, 0);
11549
11550   M (MODIFY_VHOST_USER_IF, mp);
11551
11552   mp->operation_mode = operation_mode;
11553   mp->sw_if_index = ntohl (sw_if_index);
11554   mp->is_server = is_server;
11555   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11556   vec_free (file_name);
11557   if (custom_dev_instance != ~0)
11558     {
11559       mp->renumber = 1;
11560       mp->custom_dev_instance = ntohl (custom_dev_instance);
11561     }
11562
11563   S (mp);
11564   W (ret);
11565   return ret;
11566 }
11567
11568 static int
11569 api_delete_vhost_user_if (vat_main_t * vam)
11570 {
11571   unformat_input_t *i = vam->input;
11572   vl_api_delete_vhost_user_if_t *mp;
11573   u32 sw_if_index = ~0;
11574   u8 sw_if_index_set = 0;
11575   int ret;
11576
11577   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11578     {
11579       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11580         sw_if_index_set = 1;
11581       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11582         sw_if_index_set = 1;
11583       else
11584         break;
11585     }
11586
11587   if (sw_if_index_set == 0)
11588     {
11589       errmsg ("missing sw_if_index or interface name");
11590       return -99;
11591     }
11592
11593
11594   M (DELETE_VHOST_USER_IF, mp);
11595
11596   mp->sw_if_index = ntohl (sw_if_index);
11597
11598   S (mp);
11599   W (ret);
11600   return ret;
11601 }
11602
11603 static void vl_api_sw_interface_vhost_user_details_t_handler
11604   (vl_api_sw_interface_vhost_user_details_t * mp)
11605 {
11606   vat_main_t *vam = &vat_main;
11607
11608   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %U %s",
11609          (char *) mp->interface_name,
11610          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11611          clib_net_to_host_u64 (mp->features), mp->is_server,
11612          ntohl (mp->num_regions), api_format_vhost_user_operation_mode,
11613          mp->operation_mode, (char *) mp->sock_filename);
11614   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
11615 }
11616
11617 static void vl_api_sw_interface_vhost_user_details_t_handler_json
11618   (vl_api_sw_interface_vhost_user_details_t * mp)
11619 {
11620   vat_main_t *vam = &vat_main;
11621   vat_json_node_t *node = NULL;
11622
11623   if (VAT_JSON_ARRAY != vam->json_tree.type)
11624     {
11625       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11626       vat_json_init_array (&vam->json_tree);
11627     }
11628   node = vat_json_array_add (&vam->json_tree);
11629
11630   vat_json_init_object (node);
11631   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11632   vat_json_object_add_string_copy (node, "interface_name",
11633                                    mp->interface_name);
11634   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11635                             ntohl (mp->virtio_net_hdr_sz));
11636   vat_json_object_add_uint (node, "features",
11637                             clib_net_to_host_u64 (mp->features));
11638   vat_json_object_add_uint (node, "is_server", mp->is_server);
11639   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11640   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11641   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11642   vat_json_object_add_uint (node, "mode", mp->operation_mode);
11643 }
11644
11645 static int
11646 api_sw_interface_vhost_user_dump (vat_main_t * vam)
11647 {
11648   vl_api_sw_interface_vhost_user_dump_t *mp;
11649   vl_api_control_ping_t *mp_ping;
11650   int ret;
11651   print (vam->ofp,
11652          "Interface name            idx hdr_sz features server regions mode"
11653          "      filename");
11654
11655   /* Get list of vhost-user interfaces */
11656   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
11657   S (mp);
11658
11659   /* Use a control ping for synchronization */
11660   M (CONTROL_PING, mp_ping);
11661   S (mp_ping);
11662
11663   W (ret);
11664   return ret;
11665 }
11666
11667 static int
11668 api_show_version (vat_main_t * vam)
11669 {
11670   vl_api_show_version_t *mp;
11671   int ret;
11672
11673   M (SHOW_VERSION, mp);
11674
11675   S (mp);
11676   W (ret);
11677   return ret;
11678 }
11679
11680
11681 static int
11682 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11683 {
11684   unformat_input_t *line_input = vam->input;
11685   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11686   ip4_address_t local4, remote4;
11687   ip6_address_t local6, remote6;
11688   u8 is_add = 1;
11689   u8 ipv4_set = 0, ipv6_set = 0;
11690   u8 local_set = 0;
11691   u8 remote_set = 0;
11692   u32 encap_vrf_id = 0;
11693   u32 decap_vrf_id = 0;
11694   u8 protocol = ~0;
11695   u32 vni;
11696   u8 vni_set = 0;
11697   int ret;
11698
11699   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11700     {
11701       if (unformat (line_input, "del"))
11702         is_add = 0;
11703       else if (unformat (line_input, "local %U",
11704                          unformat_ip4_address, &local4))
11705         {
11706           local_set = 1;
11707           ipv4_set = 1;
11708         }
11709       else if (unformat (line_input, "remote %U",
11710                          unformat_ip4_address, &remote4))
11711         {
11712           remote_set = 1;
11713           ipv4_set = 1;
11714         }
11715       else if (unformat (line_input, "local %U",
11716                          unformat_ip6_address, &local6))
11717         {
11718           local_set = 1;
11719           ipv6_set = 1;
11720         }
11721       else if (unformat (line_input, "remote %U",
11722                          unformat_ip6_address, &remote6))
11723         {
11724           remote_set = 1;
11725           ipv6_set = 1;
11726         }
11727       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11728         ;
11729       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11730         ;
11731       else if (unformat (line_input, "vni %d", &vni))
11732         vni_set = 1;
11733       else if (unformat (line_input, "next-ip4"))
11734         protocol = 1;
11735       else if (unformat (line_input, "next-ip6"))
11736         protocol = 2;
11737       else if (unformat (line_input, "next-ethernet"))
11738         protocol = 3;
11739       else if (unformat (line_input, "next-nsh"))
11740         protocol = 4;
11741       else
11742         {
11743           errmsg ("parse error '%U'", format_unformat_error, line_input);
11744           return -99;
11745         }
11746     }
11747
11748   if (local_set == 0)
11749     {
11750       errmsg ("tunnel local address not specified");
11751       return -99;
11752     }
11753   if (remote_set == 0)
11754     {
11755       errmsg ("tunnel remote address not specified");
11756       return -99;
11757     }
11758   if (ipv4_set && ipv6_set)
11759     {
11760       errmsg ("both IPv4 and IPv6 addresses specified");
11761       return -99;
11762     }
11763
11764   if (vni_set == 0)
11765     {
11766       errmsg ("vni not specified");
11767       return -99;
11768     }
11769
11770   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
11771
11772
11773   if (ipv6_set)
11774     {
11775       clib_memcpy (&mp->local, &local6, sizeof (local6));
11776       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11777     }
11778   else
11779     {
11780       clib_memcpy (&mp->local, &local4, sizeof (local4));
11781       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11782     }
11783
11784   mp->encap_vrf_id = ntohl (encap_vrf_id);
11785   mp->decap_vrf_id = ntohl (decap_vrf_id);
11786   mp->protocol = protocol;
11787   mp->vni = ntohl (vni);
11788   mp->is_add = is_add;
11789   mp->is_ipv6 = ipv6_set;
11790
11791   S (mp);
11792   W (ret);
11793   return ret;
11794 }
11795
11796 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11797   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11798 {
11799   vat_main_t *vam = &vat_main;
11800
11801   print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11802          ntohl (mp->sw_if_index),
11803          format_ip46_address, &(mp->local[0]),
11804          format_ip46_address, &(mp->remote[0]),
11805          ntohl (mp->vni),
11806          ntohl (mp->protocol),
11807          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11808 }
11809
11810 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11811   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11812 {
11813   vat_main_t *vam = &vat_main;
11814   vat_json_node_t *node = NULL;
11815   struct in_addr ip4;
11816   struct in6_addr ip6;
11817
11818   if (VAT_JSON_ARRAY != vam->json_tree.type)
11819     {
11820       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11821       vat_json_init_array (&vam->json_tree);
11822     }
11823   node = vat_json_array_add (&vam->json_tree);
11824
11825   vat_json_init_object (node);
11826   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11827   if (mp->is_ipv6)
11828     {
11829       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11830       vat_json_object_add_ip6 (node, "local", ip6);
11831       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11832       vat_json_object_add_ip6 (node, "remote", ip6);
11833     }
11834   else
11835     {
11836       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11837       vat_json_object_add_ip4 (node, "local", ip4);
11838       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11839       vat_json_object_add_ip4 (node, "remote", ip4);
11840     }
11841   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11842   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11843   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11844   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11845   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11846 }
11847
11848 static int
11849 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11850 {
11851   unformat_input_t *i = vam->input;
11852   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11853   vl_api_control_ping_t *mp_ping;
11854   u32 sw_if_index;
11855   u8 sw_if_index_set = 0;
11856   int ret;
11857
11858   /* Parse args required to build the message */
11859   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11860     {
11861       if (unformat (i, "sw_if_index %d", &sw_if_index))
11862         sw_if_index_set = 1;
11863       else
11864         break;
11865     }
11866
11867   if (sw_if_index_set == 0)
11868     {
11869       sw_if_index = ~0;
11870     }
11871
11872   if (!vam->json_output)
11873     {
11874       print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11875              "sw_if_index", "local", "remote", "vni",
11876              "protocol", "encap_vrf_id", "decap_vrf_id");
11877     }
11878
11879   /* Get list of vxlan-tunnel interfaces */
11880   M (VXLAN_GPE_TUNNEL_DUMP, mp);
11881
11882   mp->sw_if_index = htonl (sw_if_index);
11883
11884   S (mp);
11885
11886   /* Use a control ping for synchronization */
11887   M (CONTROL_PING, mp_ping);
11888   S (mp_ping);
11889
11890   W (ret);
11891   return ret;
11892 }
11893
11894 u8 *
11895 format_l2_fib_mac_address (u8 * s, va_list * args)
11896 {
11897   u8 *a = va_arg (*args, u8 *);
11898
11899   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11900                  a[2], a[3], a[4], a[5], a[6], a[7]);
11901 }
11902
11903 static void vl_api_l2_fib_table_details_t_handler
11904   (vl_api_l2_fib_table_details_t * mp)
11905 {
11906   vat_main_t *vam = &vat_main;
11907
11908   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11909          "       %d       %d     %d",
11910          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11911          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11912          mp->bvi_mac);
11913 }
11914
11915 static void vl_api_l2_fib_table_details_t_handler_json
11916   (vl_api_l2_fib_table_details_t * mp)
11917 {
11918   vat_main_t *vam = &vat_main;
11919   vat_json_node_t *node = NULL;
11920
11921   if (VAT_JSON_ARRAY != vam->json_tree.type)
11922     {
11923       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11924       vat_json_init_array (&vam->json_tree);
11925     }
11926   node = vat_json_array_add (&vam->json_tree);
11927
11928   vat_json_init_object (node);
11929   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11930   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11931   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11932   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11933   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11934   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11935 }
11936
11937 static int
11938 api_l2_fib_table_dump (vat_main_t * vam)
11939 {
11940   unformat_input_t *i = vam->input;
11941   vl_api_l2_fib_table_dump_t *mp;
11942   vl_api_control_ping_t *mp_ping;
11943   u32 bd_id;
11944   u8 bd_id_set = 0;
11945   int ret;
11946
11947   /* Parse args required to build the message */
11948   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11949     {
11950       if (unformat (i, "bd_id %d", &bd_id))
11951         bd_id_set = 1;
11952       else
11953         break;
11954     }
11955
11956   if (bd_id_set == 0)
11957     {
11958       errmsg ("missing bridge domain");
11959       return -99;
11960     }
11961
11962   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
11963
11964   /* Get list of l2 fib entries */
11965   M (L2_FIB_TABLE_DUMP, mp);
11966
11967   mp->bd_id = ntohl (bd_id);
11968   S (mp);
11969
11970   /* Use a control ping for synchronization */
11971   M (CONTROL_PING, mp_ping);
11972   S (mp_ping);
11973
11974   W (ret);
11975   return ret;
11976 }
11977
11978
11979 static int
11980 api_interface_name_renumber (vat_main_t * vam)
11981 {
11982   unformat_input_t *line_input = vam->input;
11983   vl_api_interface_name_renumber_t *mp;
11984   u32 sw_if_index = ~0;
11985   u32 new_show_dev_instance = ~0;
11986   int ret;
11987
11988   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11989     {
11990       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
11991                     &sw_if_index))
11992         ;
11993       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11994         ;
11995       else if (unformat (line_input, "new_show_dev_instance %d",
11996                          &new_show_dev_instance))
11997         ;
11998       else
11999         break;
12000     }
12001
12002   if (sw_if_index == ~0)
12003     {
12004       errmsg ("missing interface name or sw_if_index");
12005       return -99;
12006     }
12007
12008   if (new_show_dev_instance == ~0)
12009     {
12010       errmsg ("missing new_show_dev_instance");
12011       return -99;
12012     }
12013
12014   M (INTERFACE_NAME_RENUMBER, mp);
12015
12016   mp->sw_if_index = ntohl (sw_if_index);
12017   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
12018
12019   S (mp);
12020   W (ret);
12021   return ret;
12022 }
12023
12024 static int
12025 api_want_ip4_arp_events (vat_main_t * vam)
12026 {
12027   unformat_input_t *line_input = vam->input;
12028   vl_api_want_ip4_arp_events_t *mp;
12029   ip4_address_t address;
12030   int address_set = 0;
12031   u32 enable_disable = 1;
12032   int ret;
12033
12034   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12035     {
12036       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
12037         address_set = 1;
12038       else if (unformat (line_input, "del"))
12039         enable_disable = 0;
12040       else
12041         break;
12042     }
12043
12044   if (address_set == 0)
12045     {
12046       errmsg ("missing addresses");
12047       return -99;
12048     }
12049
12050   M (WANT_IP4_ARP_EVENTS, mp);
12051   mp->enable_disable = enable_disable;
12052   mp->pid = htonl (getpid ());
12053   mp->address = address.as_u32;
12054
12055   S (mp);
12056   W (ret);
12057   return ret;
12058 }
12059
12060 static int
12061 api_want_ip6_nd_events (vat_main_t * vam)
12062 {
12063   unformat_input_t *line_input = vam->input;
12064   vl_api_want_ip6_nd_events_t *mp;
12065   ip6_address_t address;
12066   int address_set = 0;
12067   u32 enable_disable = 1;
12068   int ret;
12069
12070   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12071     {
12072       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
12073         address_set = 1;
12074       else if (unformat (line_input, "del"))
12075         enable_disable = 0;
12076       else
12077         break;
12078     }
12079
12080   if (address_set == 0)
12081     {
12082       errmsg ("missing addresses");
12083       return -99;
12084     }
12085
12086   M (WANT_IP6_ND_EVENTS, mp);
12087   mp->enable_disable = enable_disable;
12088   mp->pid = htonl (getpid ());
12089   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
12090
12091   S (mp);
12092   W (ret);
12093   return ret;
12094 }
12095
12096 static int
12097 api_input_acl_set_interface (vat_main_t * vam)
12098 {
12099   unformat_input_t *i = vam->input;
12100   vl_api_input_acl_set_interface_t *mp;
12101   u32 sw_if_index;
12102   int sw_if_index_set;
12103   u32 ip4_table_index = ~0;
12104   u32 ip6_table_index = ~0;
12105   u32 l2_table_index = ~0;
12106   u8 is_add = 1;
12107   int ret;
12108
12109   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12110     {
12111       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12112         sw_if_index_set = 1;
12113       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12114         sw_if_index_set = 1;
12115       else if (unformat (i, "del"))
12116         is_add = 0;
12117       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12118         ;
12119       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12120         ;
12121       else if (unformat (i, "l2-table %d", &l2_table_index))
12122         ;
12123       else
12124         {
12125           clib_warning ("parse error '%U'", format_unformat_error, i);
12126           return -99;
12127         }
12128     }
12129
12130   if (sw_if_index_set == 0)
12131     {
12132       errmsg ("missing interface name or sw_if_index");
12133       return -99;
12134     }
12135
12136   M (INPUT_ACL_SET_INTERFACE, mp);
12137
12138   mp->sw_if_index = ntohl (sw_if_index);
12139   mp->ip4_table_index = ntohl (ip4_table_index);
12140   mp->ip6_table_index = ntohl (ip6_table_index);
12141   mp->l2_table_index = ntohl (l2_table_index);
12142   mp->is_add = is_add;
12143
12144   S (mp);
12145   W (ret);
12146   return ret;
12147 }
12148
12149 static int
12150 api_ip_address_dump (vat_main_t * vam)
12151 {
12152   unformat_input_t *i = vam->input;
12153   vl_api_ip_address_dump_t *mp;
12154   vl_api_control_ping_t *mp_ping;
12155   u32 sw_if_index = ~0;
12156   u8 sw_if_index_set = 0;
12157   u8 ipv4_set = 0;
12158   u8 ipv6_set = 0;
12159   int ret;
12160
12161   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12162     {
12163       if (unformat (i, "sw_if_index %d", &sw_if_index))
12164         sw_if_index_set = 1;
12165       else
12166         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12167         sw_if_index_set = 1;
12168       else if (unformat (i, "ipv4"))
12169         ipv4_set = 1;
12170       else if (unformat (i, "ipv6"))
12171         ipv6_set = 1;
12172       else
12173         break;
12174     }
12175
12176   if (ipv4_set && ipv6_set)
12177     {
12178       errmsg ("ipv4 and ipv6 flags cannot be both set");
12179       return -99;
12180     }
12181
12182   if ((!ipv4_set) && (!ipv6_set))
12183     {
12184       errmsg ("no ipv4 nor ipv6 flag set");
12185       return -99;
12186     }
12187
12188   if (sw_if_index_set == 0)
12189     {
12190       errmsg ("missing interface name or sw_if_index");
12191       return -99;
12192     }
12193
12194   vam->current_sw_if_index = sw_if_index;
12195   vam->is_ipv6 = ipv6_set;
12196
12197   M (IP_ADDRESS_DUMP, mp);
12198   mp->sw_if_index = ntohl (sw_if_index);
12199   mp->is_ipv6 = ipv6_set;
12200   S (mp);
12201
12202   /* Use a control ping for synchronization */
12203   M (CONTROL_PING, mp_ping);
12204   S (mp_ping);
12205
12206   W (ret);
12207   return ret;
12208 }
12209
12210 static int
12211 api_ip_dump (vat_main_t * vam)
12212 {
12213   vl_api_ip_dump_t *mp;
12214   vl_api_control_ping_t *mp_ping;
12215   unformat_input_t *in = vam->input;
12216   int ipv4_set = 0;
12217   int ipv6_set = 0;
12218   int is_ipv6;
12219   int i;
12220   int ret;
12221
12222   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
12223     {
12224       if (unformat (in, "ipv4"))
12225         ipv4_set = 1;
12226       else if (unformat (in, "ipv6"))
12227         ipv6_set = 1;
12228       else
12229         break;
12230     }
12231
12232   if (ipv4_set && ipv6_set)
12233     {
12234       errmsg ("ipv4 and ipv6 flags cannot be both set");
12235       return -99;
12236     }
12237
12238   if ((!ipv4_set) && (!ipv6_set))
12239     {
12240       errmsg ("no ipv4 nor ipv6 flag set");
12241       return -99;
12242     }
12243
12244   is_ipv6 = ipv6_set;
12245   vam->is_ipv6 = is_ipv6;
12246
12247   /* free old data */
12248   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
12249     {
12250       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
12251     }
12252   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
12253
12254   M (IP_DUMP, mp);
12255   mp->is_ipv6 = ipv6_set;
12256   S (mp);
12257
12258   /* Use a control ping for synchronization */
12259   M (CONTROL_PING, mp_ping);
12260   S (mp_ping);
12261
12262   W (ret);
12263   return ret;
12264 }
12265
12266 static int
12267 api_ipsec_spd_add_del (vat_main_t * vam)
12268 {
12269   unformat_input_t *i = vam->input;
12270   vl_api_ipsec_spd_add_del_t *mp;
12271   u32 spd_id = ~0;
12272   u8 is_add = 1;
12273   int ret;
12274
12275   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12276     {
12277       if (unformat (i, "spd_id %d", &spd_id))
12278         ;
12279       else if (unformat (i, "del"))
12280         is_add = 0;
12281       else
12282         {
12283           clib_warning ("parse error '%U'", format_unformat_error, i);
12284           return -99;
12285         }
12286     }
12287   if (spd_id == ~0)
12288     {
12289       errmsg ("spd_id must be set");
12290       return -99;
12291     }
12292
12293   M (IPSEC_SPD_ADD_DEL, mp);
12294
12295   mp->spd_id = ntohl (spd_id);
12296   mp->is_add = is_add;
12297
12298   S (mp);
12299   W (ret);
12300   return ret;
12301 }
12302
12303 static int
12304 api_ipsec_interface_add_del_spd (vat_main_t * vam)
12305 {
12306   unformat_input_t *i = vam->input;
12307   vl_api_ipsec_interface_add_del_spd_t *mp;
12308   u32 sw_if_index;
12309   u8 sw_if_index_set = 0;
12310   u32 spd_id = (u32) ~ 0;
12311   u8 is_add = 1;
12312   int ret;
12313
12314   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12315     {
12316       if (unformat (i, "del"))
12317         is_add = 0;
12318       else if (unformat (i, "spd_id %d", &spd_id))
12319         ;
12320       else
12321         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12322         sw_if_index_set = 1;
12323       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12324         sw_if_index_set = 1;
12325       else
12326         {
12327           clib_warning ("parse error '%U'", format_unformat_error, i);
12328           return -99;
12329         }
12330
12331     }
12332
12333   if (spd_id == (u32) ~ 0)
12334     {
12335       errmsg ("spd_id must be set");
12336       return -99;
12337     }
12338
12339   if (sw_if_index_set == 0)
12340     {
12341       errmsg ("missing interface name or sw_if_index");
12342       return -99;
12343     }
12344
12345   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
12346
12347   mp->spd_id = ntohl (spd_id);
12348   mp->sw_if_index = ntohl (sw_if_index);
12349   mp->is_add = is_add;
12350
12351   S (mp);
12352   W (ret);
12353   return ret;
12354 }
12355
12356 static int
12357 api_ipsec_spd_add_del_entry (vat_main_t * vam)
12358 {
12359   unformat_input_t *i = vam->input;
12360   vl_api_ipsec_spd_add_del_entry_t *mp;
12361   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
12362   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
12363   i32 priority = 0;
12364   u32 rport_start = 0, rport_stop = (u32) ~ 0;
12365   u32 lport_start = 0, lport_stop = (u32) ~ 0;
12366   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
12367   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
12368   int ret;
12369
12370   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
12371   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
12372   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
12373   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
12374   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
12375   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
12376
12377   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12378     {
12379       if (unformat (i, "del"))
12380         is_add = 0;
12381       if (unformat (i, "outbound"))
12382         is_outbound = 1;
12383       if (unformat (i, "inbound"))
12384         is_outbound = 0;
12385       else if (unformat (i, "spd_id %d", &spd_id))
12386         ;
12387       else if (unformat (i, "sa_id %d", &sa_id))
12388         ;
12389       else if (unformat (i, "priority %d", &priority))
12390         ;
12391       else if (unformat (i, "protocol %d", &protocol))
12392         ;
12393       else if (unformat (i, "lport_start %d", &lport_start))
12394         ;
12395       else if (unformat (i, "lport_stop %d", &lport_stop))
12396         ;
12397       else if (unformat (i, "rport_start %d", &rport_start))
12398         ;
12399       else if (unformat (i, "rport_stop %d", &rport_stop))
12400         ;
12401       else
12402         if (unformat
12403             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
12404         {
12405           is_ipv6 = 0;
12406           is_ip_any = 0;
12407         }
12408       else
12409         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
12410         {
12411           is_ipv6 = 0;
12412           is_ip_any = 0;
12413         }
12414       else
12415         if (unformat
12416             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
12417         {
12418           is_ipv6 = 0;
12419           is_ip_any = 0;
12420         }
12421       else
12422         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
12423         {
12424           is_ipv6 = 0;
12425           is_ip_any = 0;
12426         }
12427       else
12428         if (unformat
12429             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
12430         {
12431           is_ipv6 = 1;
12432           is_ip_any = 0;
12433         }
12434       else
12435         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
12436         {
12437           is_ipv6 = 1;
12438           is_ip_any = 0;
12439         }
12440       else
12441         if (unformat
12442             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
12443         {
12444           is_ipv6 = 1;
12445           is_ip_any = 0;
12446         }
12447       else
12448         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
12449         {
12450           is_ipv6 = 1;
12451           is_ip_any = 0;
12452         }
12453       else
12454         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
12455         {
12456           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
12457             {
12458               clib_warning ("unsupported action: 'resolve'");
12459               return -99;
12460             }
12461         }
12462       else
12463         {
12464           clib_warning ("parse error '%U'", format_unformat_error, i);
12465           return -99;
12466         }
12467
12468     }
12469
12470   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
12471
12472   mp->spd_id = ntohl (spd_id);
12473   mp->priority = ntohl (priority);
12474   mp->is_outbound = is_outbound;
12475
12476   mp->is_ipv6 = is_ipv6;
12477   if (is_ipv6 || is_ip_any)
12478     {
12479       clib_memcpy (mp->remote_address_start, &raddr6_start,
12480                    sizeof (ip6_address_t));
12481       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
12482                    sizeof (ip6_address_t));
12483       clib_memcpy (mp->local_address_start, &laddr6_start,
12484                    sizeof (ip6_address_t));
12485       clib_memcpy (mp->local_address_stop, &laddr6_stop,
12486                    sizeof (ip6_address_t));
12487     }
12488   else
12489     {
12490       clib_memcpy (mp->remote_address_start, &raddr4_start,
12491                    sizeof (ip4_address_t));
12492       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
12493                    sizeof (ip4_address_t));
12494       clib_memcpy (mp->local_address_start, &laddr4_start,
12495                    sizeof (ip4_address_t));
12496       clib_memcpy (mp->local_address_stop, &laddr4_stop,
12497                    sizeof (ip4_address_t));
12498     }
12499   mp->protocol = (u8) protocol;
12500   mp->local_port_start = ntohs ((u16) lport_start);
12501   mp->local_port_stop = ntohs ((u16) lport_stop);
12502   mp->remote_port_start = ntohs ((u16) rport_start);
12503   mp->remote_port_stop = ntohs ((u16) rport_stop);
12504   mp->policy = (u8) policy;
12505   mp->sa_id = ntohl (sa_id);
12506   mp->is_add = is_add;
12507   mp->is_ip_any = is_ip_any;
12508   S (mp);
12509   W (ret);
12510   return ret;
12511 }
12512
12513 static int
12514 api_ipsec_sad_add_del_entry (vat_main_t * vam)
12515 {
12516   unformat_input_t *i = vam->input;
12517   vl_api_ipsec_sad_add_del_entry_t *mp;
12518   u32 sad_id = 0, spi = 0;
12519   u8 *ck = 0, *ik = 0;
12520   u8 is_add = 1;
12521
12522   u8 protocol = IPSEC_PROTOCOL_AH;
12523   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
12524   u32 crypto_alg = 0, integ_alg = 0;
12525   ip4_address_t tun_src4;
12526   ip4_address_t tun_dst4;
12527   ip6_address_t tun_src6;
12528   ip6_address_t tun_dst6;
12529   int ret;
12530
12531   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12532     {
12533       if (unformat (i, "del"))
12534         is_add = 0;
12535       else if (unformat (i, "sad_id %d", &sad_id))
12536         ;
12537       else if (unformat (i, "spi %d", &spi))
12538         ;
12539       else if (unformat (i, "esp"))
12540         protocol = IPSEC_PROTOCOL_ESP;
12541       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
12542         {
12543           is_tunnel = 1;
12544           is_tunnel_ipv6 = 0;
12545         }
12546       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
12547         {
12548           is_tunnel = 1;
12549           is_tunnel_ipv6 = 0;
12550         }
12551       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
12552         {
12553           is_tunnel = 1;
12554           is_tunnel_ipv6 = 1;
12555         }
12556       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
12557         {
12558           is_tunnel = 1;
12559           is_tunnel_ipv6 = 1;
12560         }
12561       else
12562         if (unformat
12563             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12564         {
12565           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12566               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12567             {
12568               clib_warning ("unsupported crypto-alg: '%U'",
12569                             format_ipsec_crypto_alg, crypto_alg);
12570               return -99;
12571             }
12572         }
12573       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12574         ;
12575       else
12576         if (unformat
12577             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12578         {
12579           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12580               integ_alg >= IPSEC_INTEG_N_ALG)
12581             {
12582               clib_warning ("unsupported integ-alg: '%U'",
12583                             format_ipsec_integ_alg, integ_alg);
12584               return -99;
12585             }
12586         }
12587       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12588         ;
12589       else
12590         {
12591           clib_warning ("parse error '%U'", format_unformat_error, i);
12592           return -99;
12593         }
12594
12595     }
12596
12597   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
12598
12599   mp->sad_id = ntohl (sad_id);
12600   mp->is_add = is_add;
12601   mp->protocol = protocol;
12602   mp->spi = ntohl (spi);
12603   mp->is_tunnel = is_tunnel;
12604   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12605   mp->crypto_algorithm = crypto_alg;
12606   mp->integrity_algorithm = integ_alg;
12607   mp->crypto_key_length = vec_len (ck);
12608   mp->integrity_key_length = vec_len (ik);
12609
12610   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12611     mp->crypto_key_length = sizeof (mp->crypto_key);
12612
12613   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12614     mp->integrity_key_length = sizeof (mp->integrity_key);
12615
12616   if (ck)
12617     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12618   if (ik)
12619     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12620
12621   if (is_tunnel)
12622     {
12623       if (is_tunnel_ipv6)
12624         {
12625           clib_memcpy (mp->tunnel_src_address, &tun_src6,
12626                        sizeof (ip6_address_t));
12627           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12628                        sizeof (ip6_address_t));
12629         }
12630       else
12631         {
12632           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12633                        sizeof (ip4_address_t));
12634           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12635                        sizeof (ip4_address_t));
12636         }
12637     }
12638
12639   S (mp);
12640   W (ret);
12641   return ret;
12642 }
12643
12644 static int
12645 api_ipsec_sa_set_key (vat_main_t * vam)
12646 {
12647   unformat_input_t *i = vam->input;
12648   vl_api_ipsec_sa_set_key_t *mp;
12649   u32 sa_id;
12650   u8 *ck = 0, *ik = 0;
12651   int ret;
12652
12653   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12654     {
12655       if (unformat (i, "sa_id %d", &sa_id))
12656         ;
12657       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12658         ;
12659       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12660         ;
12661       else
12662         {
12663           clib_warning ("parse error '%U'", format_unformat_error, i);
12664           return -99;
12665         }
12666     }
12667
12668   M (IPSEC_SA_SET_KEY, mp);
12669
12670   mp->sa_id = ntohl (sa_id);
12671   mp->crypto_key_length = vec_len (ck);
12672   mp->integrity_key_length = vec_len (ik);
12673
12674   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12675     mp->crypto_key_length = sizeof (mp->crypto_key);
12676
12677   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12678     mp->integrity_key_length = sizeof (mp->integrity_key);
12679
12680   if (ck)
12681     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12682   if (ik)
12683     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12684
12685   S (mp);
12686   W (ret);
12687   return ret;
12688 }
12689
12690 static int
12691 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
12692 {
12693   unformat_input_t *i = vam->input;
12694   vl_api_ipsec_tunnel_if_add_del_t *mp;
12695   u32 local_spi = 0, remote_spi = 0;
12696   u32 crypto_alg = 0, integ_alg = 0;
12697   u8 *lck = NULL, *rck = NULL;
12698   u8 *lik = NULL, *rik = NULL;
12699   ip4_address_t local_ip = { {0} };
12700   ip4_address_t remote_ip = { {0} };
12701   u8 is_add = 1;
12702   u8 esn = 0;
12703   u8 anti_replay = 0;
12704   int ret;
12705
12706   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12707     {
12708       if (unformat (i, "del"))
12709         is_add = 0;
12710       else if (unformat (i, "esn"))
12711         esn = 1;
12712       else if (unformat (i, "anti_replay"))
12713         anti_replay = 1;
12714       else if (unformat (i, "local_spi %d", &local_spi))
12715         ;
12716       else if (unformat (i, "remote_spi %d", &remote_spi))
12717         ;
12718       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
12719         ;
12720       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
12721         ;
12722       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
12723         ;
12724       else
12725         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
12726         ;
12727       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
12728         ;
12729       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
12730         ;
12731       else
12732         if (unformat
12733             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12734         {
12735           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12736               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12737             {
12738               errmsg ("unsupported crypto-alg: '%U'\n",
12739                       format_ipsec_crypto_alg, crypto_alg);
12740               return -99;
12741             }
12742         }
12743       else
12744         if (unformat
12745             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12746         {
12747           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12748               integ_alg >= IPSEC_INTEG_N_ALG)
12749             {
12750               errmsg ("unsupported integ-alg: '%U'\n",
12751                       format_ipsec_integ_alg, integ_alg);
12752               return -99;
12753             }
12754         }
12755       else
12756         {
12757           errmsg ("parse error '%U'\n", format_unformat_error, i);
12758           return -99;
12759         }
12760     }
12761
12762   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
12763
12764   mp->is_add = is_add;
12765   mp->esn = esn;
12766   mp->anti_replay = anti_replay;
12767
12768   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
12769   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
12770
12771   mp->local_spi = htonl (local_spi);
12772   mp->remote_spi = htonl (remote_spi);
12773   mp->crypto_alg = (u8) crypto_alg;
12774
12775   mp->local_crypto_key_len = 0;
12776   if (lck)
12777     {
12778       mp->local_crypto_key_len = vec_len (lck);
12779       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
12780         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
12781       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
12782     }
12783
12784   mp->remote_crypto_key_len = 0;
12785   if (rck)
12786     {
12787       mp->remote_crypto_key_len = vec_len (rck);
12788       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
12789         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
12790       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
12791     }
12792
12793   mp->integ_alg = (u8) integ_alg;
12794
12795   mp->local_integ_key_len = 0;
12796   if (lik)
12797     {
12798       mp->local_integ_key_len = vec_len (lik);
12799       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
12800         mp->local_integ_key_len = sizeof (mp->local_integ_key);
12801       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
12802     }
12803
12804   mp->remote_integ_key_len = 0;
12805   if (rik)
12806     {
12807       mp->remote_integ_key_len = vec_len (rik);
12808       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
12809         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
12810       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
12811     }
12812
12813   S (mp);
12814   W (ret);
12815   return ret;
12816 }
12817
12818 static int
12819 api_ikev2_profile_add_del (vat_main_t * vam)
12820 {
12821   unformat_input_t *i = vam->input;
12822   vl_api_ikev2_profile_add_del_t *mp;
12823   u8 is_add = 1;
12824   u8 *name = 0;
12825   int ret;
12826
12827   const char *valid_chars = "a-zA-Z0-9_";
12828
12829   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12830     {
12831       if (unformat (i, "del"))
12832         is_add = 0;
12833       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12834         vec_add1 (name, 0);
12835       else
12836         {
12837           errmsg ("parse error '%U'", format_unformat_error, i);
12838           return -99;
12839         }
12840     }
12841
12842   if (!vec_len (name))
12843     {
12844       errmsg ("profile name must be specified");
12845       return -99;
12846     }
12847
12848   if (vec_len (name) > 64)
12849     {
12850       errmsg ("profile name too long");
12851       return -99;
12852     }
12853
12854   M (IKEV2_PROFILE_ADD_DEL, mp);
12855
12856   clib_memcpy (mp->name, name, vec_len (name));
12857   mp->is_add = is_add;
12858   vec_free (name);
12859
12860   S (mp);
12861   W (ret);
12862   return ret;
12863 }
12864
12865 static int
12866 api_ikev2_profile_set_auth (vat_main_t * vam)
12867 {
12868   unformat_input_t *i = vam->input;
12869   vl_api_ikev2_profile_set_auth_t *mp;
12870   u8 *name = 0;
12871   u8 *data = 0;
12872   u32 auth_method = 0;
12873   u8 is_hex = 0;
12874   int ret;
12875
12876   const char *valid_chars = "a-zA-Z0-9_";
12877
12878   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12879     {
12880       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12881         vec_add1 (name, 0);
12882       else if (unformat (i, "auth_method %U",
12883                          unformat_ikev2_auth_method, &auth_method))
12884         ;
12885       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12886         is_hex = 1;
12887       else if (unformat (i, "auth_data %v", &data))
12888         ;
12889       else
12890         {
12891           errmsg ("parse error '%U'", format_unformat_error, i);
12892           return -99;
12893         }
12894     }
12895
12896   if (!vec_len (name))
12897     {
12898       errmsg ("profile name must be specified");
12899       return -99;
12900     }
12901
12902   if (vec_len (name) > 64)
12903     {
12904       errmsg ("profile name too long");
12905       return -99;
12906     }
12907
12908   if (!vec_len (data))
12909     {
12910       errmsg ("auth_data must be specified");
12911       return -99;
12912     }
12913
12914   if (!auth_method)
12915     {
12916       errmsg ("auth_method must be specified");
12917       return -99;
12918     }
12919
12920   M (IKEV2_PROFILE_SET_AUTH, mp);
12921
12922   mp->is_hex = is_hex;
12923   mp->auth_method = (u8) auth_method;
12924   mp->data_len = vec_len (data);
12925   clib_memcpy (mp->name, name, vec_len (name));
12926   clib_memcpy (mp->data, data, vec_len (data));
12927   vec_free (name);
12928   vec_free (data);
12929
12930   S (mp);
12931   W (ret);
12932   return ret;
12933 }
12934
12935 static int
12936 api_ikev2_profile_set_id (vat_main_t * vam)
12937 {
12938   unformat_input_t *i = vam->input;
12939   vl_api_ikev2_profile_set_id_t *mp;
12940   u8 *name = 0;
12941   u8 *data = 0;
12942   u8 is_local = 0;
12943   u32 id_type = 0;
12944   ip4_address_t ip4;
12945   int ret;
12946
12947   const char *valid_chars = "a-zA-Z0-9_";
12948
12949   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12950     {
12951       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12952         vec_add1 (name, 0);
12953       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12954         ;
12955       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12956         {
12957           data = vec_new (u8, 4);
12958           clib_memcpy (data, ip4.as_u8, 4);
12959         }
12960       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12961         ;
12962       else if (unformat (i, "id_data %v", &data))
12963         ;
12964       else if (unformat (i, "local"))
12965         is_local = 1;
12966       else if (unformat (i, "remote"))
12967         is_local = 0;
12968       else
12969         {
12970           errmsg ("parse error '%U'", format_unformat_error, i);
12971           return -99;
12972         }
12973     }
12974
12975   if (!vec_len (name))
12976     {
12977       errmsg ("profile name must be specified");
12978       return -99;
12979     }
12980
12981   if (vec_len (name) > 64)
12982     {
12983       errmsg ("profile name too long");
12984       return -99;
12985     }
12986
12987   if (!vec_len (data))
12988     {
12989       errmsg ("id_data must be specified");
12990       return -99;
12991     }
12992
12993   if (!id_type)
12994     {
12995       errmsg ("id_type must be specified");
12996       return -99;
12997     }
12998
12999   M (IKEV2_PROFILE_SET_ID, mp);
13000
13001   mp->is_local = is_local;
13002   mp->id_type = (u8) id_type;
13003   mp->data_len = vec_len (data);
13004   clib_memcpy (mp->name, name, vec_len (name));
13005   clib_memcpy (mp->data, data, vec_len (data));
13006   vec_free (name);
13007   vec_free (data);
13008
13009   S (mp);
13010   W (ret);
13011   return ret;
13012 }
13013
13014 static int
13015 api_ikev2_profile_set_ts (vat_main_t * vam)
13016 {
13017   unformat_input_t *i = vam->input;
13018   vl_api_ikev2_profile_set_ts_t *mp;
13019   u8 *name = 0;
13020   u8 is_local = 0;
13021   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
13022   ip4_address_t start_addr, end_addr;
13023
13024   const char *valid_chars = "a-zA-Z0-9_";
13025   int ret;
13026
13027   start_addr.as_u32 = 0;
13028   end_addr.as_u32 = (u32) ~ 0;
13029
13030   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13031     {
13032       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13033         vec_add1 (name, 0);
13034       else if (unformat (i, "protocol %d", &proto))
13035         ;
13036       else if (unformat (i, "start_port %d", &start_port))
13037         ;
13038       else if (unformat (i, "end_port %d", &end_port))
13039         ;
13040       else
13041         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
13042         ;
13043       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
13044         ;
13045       else if (unformat (i, "local"))
13046         is_local = 1;
13047       else if (unformat (i, "remote"))
13048         is_local = 0;
13049       else
13050         {
13051           errmsg ("parse error '%U'", format_unformat_error, i);
13052           return -99;
13053         }
13054     }
13055
13056   if (!vec_len (name))
13057     {
13058       errmsg ("profile name must be specified");
13059       return -99;
13060     }
13061
13062   if (vec_len (name) > 64)
13063     {
13064       errmsg ("profile name too long");
13065       return -99;
13066     }
13067
13068   M (IKEV2_PROFILE_SET_TS, mp);
13069
13070   mp->is_local = is_local;
13071   mp->proto = (u8) proto;
13072   mp->start_port = (u16) start_port;
13073   mp->end_port = (u16) end_port;
13074   mp->start_addr = start_addr.as_u32;
13075   mp->end_addr = end_addr.as_u32;
13076   clib_memcpy (mp->name, name, vec_len (name));
13077   vec_free (name);
13078
13079   S (mp);
13080   W (ret);
13081   return ret;
13082 }
13083
13084 static int
13085 api_ikev2_set_local_key (vat_main_t * vam)
13086 {
13087   unformat_input_t *i = vam->input;
13088   vl_api_ikev2_set_local_key_t *mp;
13089   u8 *file = 0;
13090   int ret;
13091
13092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13093     {
13094       if (unformat (i, "file %v", &file))
13095         vec_add1 (file, 0);
13096       else
13097         {
13098           errmsg ("parse error '%U'", format_unformat_error, i);
13099           return -99;
13100         }
13101     }
13102
13103   if (!vec_len (file))
13104     {
13105       errmsg ("RSA key file must be specified");
13106       return -99;
13107     }
13108
13109   if (vec_len (file) > 256)
13110     {
13111       errmsg ("file name too long");
13112       return -99;
13113     }
13114
13115   M (IKEV2_SET_LOCAL_KEY, mp);
13116
13117   clib_memcpy (mp->key_file, file, vec_len (file));
13118   vec_free (file);
13119
13120   S (mp);
13121   W (ret);
13122   return ret;
13123 }
13124
13125 static int
13126 api_ikev2_set_responder (vat_main_t * vam)
13127 {
13128   unformat_input_t *i = vam->input;
13129   vl_api_ikev2_set_responder_t *mp;
13130   int ret;
13131   u8 *name = 0;
13132   u32 sw_if_index = ~0;
13133   ip4_address_t address;
13134
13135   const char *valid_chars = "a-zA-Z0-9_";
13136
13137   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13138     {
13139       if (unformat
13140           (i, "%U interface %d address %U", unformat_token, valid_chars,
13141            &name, &sw_if_index, unformat_ip4_address, &address))
13142         vec_add1 (name, 0);
13143       else
13144         {
13145           errmsg ("parse error '%U'", format_unformat_error, i);
13146           return -99;
13147         }
13148     }
13149
13150   if (!vec_len (name))
13151     {
13152       errmsg ("profile name must be specified");
13153       return -99;
13154     }
13155
13156   if (vec_len (name) > 64)
13157     {
13158       errmsg ("profile name too long");
13159       return -99;
13160     }
13161
13162   M (IKEV2_SET_RESPONDER, mp);
13163
13164   clib_memcpy (mp->name, name, vec_len (name));
13165   vec_free (name);
13166
13167   mp->sw_if_index = sw_if_index;
13168   clib_memcpy (mp->address, &address, sizeof (address));
13169
13170   S (mp);
13171   W (ret);
13172   return ret;
13173 }
13174
13175 static int
13176 api_ikev2_set_ike_transforms (vat_main_t * vam)
13177 {
13178   unformat_input_t *i = vam->input;
13179   vl_api_ikev2_set_ike_transforms_t *mp;
13180   int ret;
13181   u8 *name = 0;
13182   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13183
13184   const char *valid_chars = "a-zA-Z0-9_";
13185
13186   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13187     {
13188       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13189                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13190         vec_add1 (name, 0);
13191       else
13192         {
13193           errmsg ("parse error '%U'", format_unformat_error, i);
13194           return -99;
13195         }
13196     }
13197
13198   if (!vec_len (name))
13199     {
13200       errmsg ("profile name must be specified");
13201       return -99;
13202     }
13203
13204   if (vec_len (name) > 64)
13205     {
13206       errmsg ("profile name too long");
13207       return -99;
13208     }
13209
13210   M (IKEV2_SET_IKE_TRANSFORMS, mp);
13211
13212   clib_memcpy (mp->name, name, vec_len (name));
13213   vec_free (name);
13214   mp->crypto_alg = crypto_alg;
13215   mp->crypto_key_size = crypto_key_size;
13216   mp->integ_alg = integ_alg;
13217   mp->dh_group = dh_group;
13218
13219   S (mp);
13220   W (ret);
13221   return ret;
13222 }
13223
13224
13225 static int
13226 api_ikev2_set_esp_transforms (vat_main_t * vam)
13227 {
13228   unformat_input_t *i = vam->input;
13229   vl_api_ikev2_set_esp_transforms_t *mp;
13230   int ret;
13231   u8 *name = 0;
13232   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13233
13234   const char *valid_chars = "a-zA-Z0-9_";
13235
13236   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13237     {
13238       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13239                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13240         vec_add1 (name, 0);
13241       else
13242         {
13243           errmsg ("parse error '%U'", format_unformat_error, i);
13244           return -99;
13245         }
13246     }
13247
13248   if (!vec_len (name))
13249     {
13250       errmsg ("profile name must be specified");
13251       return -99;
13252     }
13253
13254   if (vec_len (name) > 64)
13255     {
13256       errmsg ("profile name too long");
13257       return -99;
13258     }
13259
13260   M (IKEV2_SET_ESP_TRANSFORMS, mp);
13261
13262   clib_memcpy (mp->name, name, vec_len (name));
13263   vec_free (name);
13264   mp->crypto_alg = crypto_alg;
13265   mp->crypto_key_size = crypto_key_size;
13266   mp->integ_alg = integ_alg;
13267   mp->dh_group = dh_group;
13268
13269   S (mp);
13270   W (ret);
13271   return ret;
13272 }
13273
13274 static int
13275 api_ikev2_set_sa_lifetime (vat_main_t * vam)
13276 {
13277   unformat_input_t *i = vam->input;
13278   vl_api_ikev2_set_sa_lifetime_t *mp;
13279   int ret;
13280   u8 *name = 0;
13281   u64 lifetime, lifetime_maxdata;
13282   u32 lifetime_jitter, handover;
13283
13284   const char *valid_chars = "a-zA-Z0-9_";
13285
13286   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13287     {
13288       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
13289                     &lifetime, &lifetime_jitter, &handover,
13290                     &lifetime_maxdata))
13291         vec_add1 (name, 0);
13292       else
13293         {
13294           errmsg ("parse error '%U'", format_unformat_error, i);
13295           return -99;
13296         }
13297     }
13298
13299   if (!vec_len (name))
13300     {
13301       errmsg ("profile name must be specified");
13302       return -99;
13303     }
13304
13305   if (vec_len (name) > 64)
13306     {
13307       errmsg ("profile name too long");
13308       return -99;
13309     }
13310
13311   M (IKEV2_SET_SA_LIFETIME, mp);
13312
13313   clib_memcpy (mp->name, name, vec_len (name));
13314   vec_free (name);
13315   mp->lifetime = lifetime;
13316   mp->lifetime_jitter = lifetime_jitter;
13317   mp->handover = handover;
13318   mp->lifetime_maxdata = lifetime_maxdata;
13319
13320   S (mp);
13321   W (ret);
13322   return ret;
13323 }
13324
13325 static int
13326 api_ikev2_initiate_sa_init (vat_main_t * vam)
13327 {
13328   unformat_input_t *i = vam->input;
13329   vl_api_ikev2_initiate_sa_init_t *mp;
13330   int ret;
13331   u8 *name = 0;
13332
13333   const char *valid_chars = "a-zA-Z0-9_";
13334
13335   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13336     {
13337       if (unformat (i, "%U", unformat_token, valid_chars, &name))
13338         vec_add1 (name, 0);
13339       else
13340         {
13341           errmsg ("parse error '%U'", format_unformat_error, i);
13342           return -99;
13343         }
13344     }
13345
13346   if (!vec_len (name))
13347     {
13348       errmsg ("profile name must be specified");
13349       return -99;
13350     }
13351
13352   if (vec_len (name) > 64)
13353     {
13354       errmsg ("profile name too long");
13355       return -99;
13356     }
13357
13358   M (IKEV2_INITIATE_SA_INIT, mp);
13359
13360   clib_memcpy (mp->name, name, vec_len (name));
13361   vec_free (name);
13362
13363   S (mp);
13364   W (ret);
13365   return ret;
13366 }
13367
13368 static int
13369 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
13370 {
13371   unformat_input_t *i = vam->input;
13372   vl_api_ikev2_initiate_del_ike_sa_t *mp;
13373   int ret;
13374   u64 ispi;
13375
13376
13377   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13378     {
13379       if (unformat (i, "%lx", &ispi))
13380         ;
13381       else
13382         {
13383           errmsg ("parse error '%U'", format_unformat_error, i);
13384           return -99;
13385         }
13386     }
13387
13388   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
13389
13390   mp->ispi = ispi;
13391
13392   S (mp);
13393   W (ret);
13394   return ret;
13395 }
13396
13397 static int
13398 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
13399 {
13400   unformat_input_t *i = vam->input;
13401   vl_api_ikev2_initiate_del_child_sa_t *mp;
13402   int ret;
13403   u32 ispi;
13404
13405
13406   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13407     {
13408       if (unformat (i, "%x", &ispi))
13409         ;
13410       else
13411         {
13412           errmsg ("parse error '%U'", format_unformat_error, i);
13413           return -99;
13414         }
13415     }
13416
13417   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
13418
13419   mp->ispi = ispi;
13420
13421   S (mp);
13422   W (ret);
13423   return ret;
13424 }
13425
13426 static int
13427 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
13428 {
13429   unformat_input_t *i = vam->input;
13430   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
13431   int ret;
13432   u32 ispi;
13433
13434
13435   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13436     {
13437       if (unformat (i, "%x", &ispi))
13438         ;
13439       else
13440         {
13441           errmsg ("parse error '%U'", format_unformat_error, i);
13442           return -99;
13443         }
13444     }
13445
13446   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
13447
13448   mp->ispi = ispi;
13449
13450   S (mp);
13451   W (ret);
13452   return ret;
13453 }
13454
13455 /*
13456  * MAP
13457  */
13458 static int
13459 api_map_add_domain (vat_main_t * vam)
13460 {
13461   unformat_input_t *i = vam->input;
13462   vl_api_map_add_domain_t *mp;
13463
13464   ip4_address_t ip4_prefix;
13465   ip6_address_t ip6_prefix;
13466   ip6_address_t ip6_src;
13467   u32 num_m_args = 0;
13468   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
13469     0, psid_length = 0;
13470   u8 is_translation = 0;
13471   u32 mtu = 0;
13472   u32 ip6_src_len = 128;
13473   int ret;
13474
13475   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13476     {
13477       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
13478                     &ip4_prefix, &ip4_prefix_len))
13479         num_m_args++;
13480       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
13481                          &ip6_prefix, &ip6_prefix_len))
13482         num_m_args++;
13483       else
13484         if (unformat
13485             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
13486              &ip6_src_len))
13487         num_m_args++;
13488       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
13489         num_m_args++;
13490       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
13491         num_m_args++;
13492       else if (unformat (i, "psid-offset %d", &psid_offset))
13493         num_m_args++;
13494       else if (unformat (i, "psid-len %d", &psid_length))
13495         num_m_args++;
13496       else if (unformat (i, "mtu %d", &mtu))
13497         num_m_args++;
13498       else if (unformat (i, "map-t"))
13499         is_translation = 1;
13500       else
13501         {
13502           clib_warning ("parse error '%U'", format_unformat_error, i);
13503           return -99;
13504         }
13505     }
13506
13507   if (num_m_args < 3)
13508     {
13509       errmsg ("mandatory argument(s) missing");
13510       return -99;
13511     }
13512
13513   /* Construct the API message */
13514   M (MAP_ADD_DOMAIN, mp);
13515
13516   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
13517   mp->ip4_prefix_len = ip4_prefix_len;
13518
13519   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
13520   mp->ip6_prefix_len = ip6_prefix_len;
13521
13522   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
13523   mp->ip6_src_prefix_len = ip6_src_len;
13524
13525   mp->ea_bits_len = ea_bits_len;
13526   mp->psid_offset = psid_offset;
13527   mp->psid_length = psid_length;
13528   mp->is_translation = is_translation;
13529   mp->mtu = htons (mtu);
13530
13531   /* send it... */
13532   S (mp);
13533
13534   /* Wait for a reply, return good/bad news  */
13535   W (ret);
13536   return ret;
13537 }
13538
13539 static int
13540 api_map_del_domain (vat_main_t * vam)
13541 {
13542   unformat_input_t *i = vam->input;
13543   vl_api_map_del_domain_t *mp;
13544
13545   u32 num_m_args = 0;
13546   u32 index;
13547   int ret;
13548
13549   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13550     {
13551       if (unformat (i, "index %d", &index))
13552         num_m_args++;
13553       else
13554         {
13555           clib_warning ("parse error '%U'", format_unformat_error, i);
13556           return -99;
13557         }
13558     }
13559
13560   if (num_m_args != 1)
13561     {
13562       errmsg ("mandatory argument(s) missing");
13563       return -99;
13564     }
13565
13566   /* Construct the API message */
13567   M (MAP_DEL_DOMAIN, mp);
13568
13569   mp->index = ntohl (index);
13570
13571   /* send it... */
13572   S (mp);
13573
13574   /* Wait for a reply, return good/bad news  */
13575   W (ret);
13576   return ret;
13577 }
13578
13579 static int
13580 api_map_add_del_rule (vat_main_t * vam)
13581 {
13582   unformat_input_t *i = vam->input;
13583   vl_api_map_add_del_rule_t *mp;
13584   u8 is_add = 1;
13585   ip6_address_t ip6_dst;
13586   u32 num_m_args = 0, index, psid = 0;
13587   int ret;
13588
13589   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13590     {
13591       if (unformat (i, "index %d", &index))
13592         num_m_args++;
13593       else if (unformat (i, "psid %d", &psid))
13594         num_m_args++;
13595       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
13596         num_m_args++;
13597       else if (unformat (i, "del"))
13598         {
13599           is_add = 0;
13600         }
13601       else
13602         {
13603           clib_warning ("parse error '%U'", format_unformat_error, i);
13604           return -99;
13605         }
13606     }
13607
13608   /* Construct the API message */
13609   M (MAP_ADD_DEL_RULE, mp);
13610
13611   mp->index = ntohl (index);
13612   mp->is_add = is_add;
13613   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
13614   mp->psid = ntohs (psid);
13615
13616   /* send it... */
13617   S (mp);
13618
13619   /* Wait for a reply, return good/bad news  */
13620   W (ret);
13621   return ret;
13622 }
13623
13624 static int
13625 api_map_domain_dump (vat_main_t * vam)
13626 {
13627   vl_api_map_domain_dump_t *mp;
13628   vl_api_control_ping_t *mp_ping;
13629   int ret;
13630
13631   /* Construct the API message */
13632   M (MAP_DOMAIN_DUMP, mp);
13633
13634   /* send it... */
13635   S (mp);
13636
13637   /* Use a control ping for synchronization */
13638   M (CONTROL_PING, mp_ping);
13639   S (mp_ping);
13640
13641   W (ret);
13642   return ret;
13643 }
13644
13645 static int
13646 api_map_rule_dump (vat_main_t * vam)
13647 {
13648   unformat_input_t *i = vam->input;
13649   vl_api_map_rule_dump_t *mp;
13650   vl_api_control_ping_t *mp_ping;
13651   u32 domain_index = ~0;
13652   int ret;
13653
13654   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13655     {
13656       if (unformat (i, "index %u", &domain_index))
13657         ;
13658       else
13659         break;
13660     }
13661
13662   if (domain_index == ~0)
13663     {
13664       clib_warning ("parse error: domain index expected");
13665       return -99;
13666     }
13667
13668   /* Construct the API message */
13669   M (MAP_RULE_DUMP, mp);
13670
13671   mp->domain_index = htonl (domain_index);
13672
13673   /* send it... */
13674   S (mp);
13675
13676   /* Use a control ping for synchronization */
13677   M (CONTROL_PING, mp_ping);
13678   S (mp_ping);
13679
13680   W (ret);
13681   return ret;
13682 }
13683
13684 static void vl_api_map_add_domain_reply_t_handler
13685   (vl_api_map_add_domain_reply_t * mp)
13686 {
13687   vat_main_t *vam = &vat_main;
13688   i32 retval = ntohl (mp->retval);
13689
13690   if (vam->async_mode)
13691     {
13692       vam->async_errors += (retval < 0);
13693     }
13694   else
13695     {
13696       vam->retval = retval;
13697       vam->result_ready = 1;
13698     }
13699 }
13700
13701 static void vl_api_map_add_domain_reply_t_handler_json
13702   (vl_api_map_add_domain_reply_t * mp)
13703 {
13704   vat_main_t *vam = &vat_main;
13705   vat_json_node_t node;
13706
13707   vat_json_init_object (&node);
13708   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
13709   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
13710
13711   vat_json_print (vam->ofp, &node);
13712   vat_json_free (&node);
13713
13714   vam->retval = ntohl (mp->retval);
13715   vam->result_ready = 1;
13716 }
13717
13718 static int
13719 api_get_first_msg_id (vat_main_t * vam)
13720 {
13721   vl_api_get_first_msg_id_t *mp;
13722   unformat_input_t *i = vam->input;
13723   u8 *name;
13724   u8 name_set = 0;
13725   int ret;
13726
13727   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13728     {
13729       if (unformat (i, "client %s", &name))
13730         name_set = 1;
13731       else
13732         break;
13733     }
13734
13735   if (name_set == 0)
13736     {
13737       errmsg ("missing client name");
13738       return -99;
13739     }
13740   vec_add1 (name, 0);
13741
13742   if (vec_len (name) > 63)
13743     {
13744       errmsg ("client name too long");
13745       return -99;
13746     }
13747
13748   M (GET_FIRST_MSG_ID, mp);
13749   clib_memcpy (mp->name, name, vec_len (name));
13750   S (mp);
13751   W (ret);
13752   return ret;
13753 }
13754
13755 static int
13756 api_cop_interface_enable_disable (vat_main_t * vam)
13757 {
13758   unformat_input_t *line_input = vam->input;
13759   vl_api_cop_interface_enable_disable_t *mp;
13760   u32 sw_if_index = ~0;
13761   u8 enable_disable = 1;
13762   int ret;
13763
13764   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13765     {
13766       if (unformat (line_input, "disable"))
13767         enable_disable = 0;
13768       if (unformat (line_input, "enable"))
13769         enable_disable = 1;
13770       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13771                          vam, &sw_if_index))
13772         ;
13773       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13774         ;
13775       else
13776         break;
13777     }
13778
13779   if (sw_if_index == ~0)
13780     {
13781       errmsg ("missing interface name or sw_if_index");
13782       return -99;
13783     }
13784
13785   /* Construct the API message */
13786   M (COP_INTERFACE_ENABLE_DISABLE, mp);
13787   mp->sw_if_index = ntohl (sw_if_index);
13788   mp->enable_disable = enable_disable;
13789
13790   /* send it... */
13791   S (mp);
13792   /* Wait for the reply */
13793   W (ret);
13794   return ret;
13795 }
13796
13797 static int
13798 api_cop_whitelist_enable_disable (vat_main_t * vam)
13799 {
13800   unformat_input_t *line_input = vam->input;
13801   vl_api_cop_whitelist_enable_disable_t *mp;
13802   u32 sw_if_index = ~0;
13803   u8 ip4 = 0, ip6 = 0, default_cop = 0;
13804   u32 fib_id = 0;
13805   int ret;
13806
13807   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13808     {
13809       if (unformat (line_input, "ip4"))
13810         ip4 = 1;
13811       else if (unformat (line_input, "ip6"))
13812         ip6 = 1;
13813       else if (unformat (line_input, "default"))
13814         default_cop = 1;
13815       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13816                          vam, &sw_if_index))
13817         ;
13818       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13819         ;
13820       else if (unformat (line_input, "fib-id %d", &fib_id))
13821         ;
13822       else
13823         break;
13824     }
13825
13826   if (sw_if_index == ~0)
13827     {
13828       errmsg ("missing interface name or sw_if_index");
13829       return -99;
13830     }
13831
13832   /* Construct the API message */
13833   M (COP_WHITELIST_ENABLE_DISABLE, mp);
13834   mp->sw_if_index = ntohl (sw_if_index);
13835   mp->fib_id = ntohl (fib_id);
13836   mp->ip4 = ip4;
13837   mp->ip6 = ip6;
13838   mp->default_cop = default_cop;
13839
13840   /* send it... */
13841   S (mp);
13842   /* Wait for the reply */
13843   W (ret);
13844   return ret;
13845 }
13846
13847 static int
13848 api_get_node_graph (vat_main_t * vam)
13849 {
13850   vl_api_get_node_graph_t *mp;
13851   int ret;
13852
13853   M (GET_NODE_GRAPH, mp);
13854
13855   /* send it... */
13856   S (mp);
13857   /* Wait for the reply */
13858   W (ret);
13859   return ret;
13860 }
13861
13862 /* *INDENT-OFF* */
13863 /** Used for parsing LISP eids */
13864 typedef CLIB_PACKED(struct{
13865   u8 addr[16];   /**< eid address */
13866   u32 len;       /**< prefix length if IP */
13867   u8 type;      /**< type of eid */
13868 }) lisp_eid_vat_t;
13869 /* *INDENT-ON* */
13870
13871 static uword
13872 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
13873 {
13874   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
13875
13876   memset (a, 0, sizeof (a[0]));
13877
13878   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
13879     {
13880       a->type = 0;              /* ipv4 type */
13881     }
13882   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
13883     {
13884       a->type = 1;              /* ipv6 type */
13885     }
13886   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
13887     {
13888       a->type = 2;              /* mac type */
13889     }
13890   else
13891     {
13892       return 0;
13893     }
13894
13895   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
13896     {
13897       return 0;
13898     }
13899
13900   return 1;
13901 }
13902
13903 static int
13904 lisp_eid_size_vat (u8 type)
13905 {
13906   switch (type)
13907     {
13908     case 0:
13909       return 4;
13910     case 1:
13911       return 16;
13912     case 2:
13913       return 6;
13914     }
13915   return 0;
13916 }
13917
13918 static void
13919 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
13920 {
13921   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
13922 }
13923
13924 static int
13925 api_one_add_del_locator_set (vat_main_t * vam)
13926 {
13927   unformat_input_t *input = vam->input;
13928   vl_api_one_add_del_locator_set_t *mp;
13929   u8 is_add = 1;
13930   u8 *locator_set_name = NULL;
13931   u8 locator_set_name_set = 0;
13932   vl_api_local_locator_t locator, *locators = 0;
13933   u32 sw_if_index, priority, weight;
13934   u32 data_len = 0;
13935
13936   int ret;
13937   /* Parse args required to build the message */
13938   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13939     {
13940       if (unformat (input, "del"))
13941         {
13942           is_add = 0;
13943         }
13944       else if (unformat (input, "locator-set %s", &locator_set_name))
13945         {
13946           locator_set_name_set = 1;
13947         }
13948       else if (unformat (input, "sw_if_index %u p %u w %u",
13949                          &sw_if_index, &priority, &weight))
13950         {
13951           locator.sw_if_index = htonl (sw_if_index);
13952           locator.priority = priority;
13953           locator.weight = weight;
13954           vec_add1 (locators, locator);
13955         }
13956       else
13957         if (unformat
13958             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
13959              &sw_if_index, &priority, &weight))
13960         {
13961           locator.sw_if_index = htonl (sw_if_index);
13962           locator.priority = priority;
13963           locator.weight = weight;
13964           vec_add1 (locators, locator);
13965         }
13966       else
13967         break;
13968     }
13969
13970   if (locator_set_name_set == 0)
13971     {
13972       errmsg ("missing locator-set name");
13973       vec_free (locators);
13974       return -99;
13975     }
13976
13977   if (vec_len (locator_set_name) > 64)
13978     {
13979       errmsg ("locator-set name too long");
13980       vec_free (locator_set_name);
13981       vec_free (locators);
13982       return -99;
13983     }
13984   vec_add1 (locator_set_name, 0);
13985
13986   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
13987
13988   /* Construct the API message */
13989   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
13990
13991   mp->is_add = is_add;
13992   clib_memcpy (mp->locator_set_name, locator_set_name,
13993                vec_len (locator_set_name));
13994   vec_free (locator_set_name);
13995
13996   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
13997   if (locators)
13998     clib_memcpy (mp->locators, locators, data_len);
13999   vec_free (locators);
14000
14001   /* send it... */
14002   S (mp);
14003
14004   /* Wait for a reply... */
14005   W (ret);
14006   return ret;
14007 }
14008
14009 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14010
14011 static int
14012 api_one_add_del_locator (vat_main_t * vam)
14013 {
14014   unformat_input_t *input = vam->input;
14015   vl_api_one_add_del_locator_t *mp;
14016   u32 tmp_if_index = ~0;
14017   u32 sw_if_index = ~0;
14018   u8 sw_if_index_set = 0;
14019   u8 sw_if_index_if_name_set = 0;
14020   u32 priority = ~0;
14021   u8 priority_set = 0;
14022   u32 weight = ~0;
14023   u8 weight_set = 0;
14024   u8 is_add = 1;
14025   u8 *locator_set_name = NULL;
14026   u8 locator_set_name_set = 0;
14027   int ret;
14028
14029   /* Parse args required to build the message */
14030   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14031     {
14032       if (unformat (input, "del"))
14033         {
14034           is_add = 0;
14035         }
14036       else if (unformat (input, "locator-set %s", &locator_set_name))
14037         {
14038           locator_set_name_set = 1;
14039         }
14040       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14041                          &tmp_if_index))
14042         {
14043           sw_if_index_if_name_set = 1;
14044           sw_if_index = tmp_if_index;
14045         }
14046       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14047         {
14048           sw_if_index_set = 1;
14049           sw_if_index = tmp_if_index;
14050         }
14051       else if (unformat (input, "p %d", &priority))
14052         {
14053           priority_set = 1;
14054         }
14055       else if (unformat (input, "w %d", &weight))
14056         {
14057           weight_set = 1;
14058         }
14059       else
14060         break;
14061     }
14062
14063   if (locator_set_name_set == 0)
14064     {
14065       errmsg ("missing locator-set name");
14066       return -99;
14067     }
14068
14069   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14070     {
14071       errmsg ("missing sw_if_index");
14072       vec_free (locator_set_name);
14073       return -99;
14074     }
14075
14076   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14077     {
14078       errmsg ("cannot use both params interface name and sw_if_index");
14079       vec_free (locator_set_name);
14080       return -99;
14081     }
14082
14083   if (priority_set == 0)
14084     {
14085       errmsg ("missing locator-set priority");
14086       vec_free (locator_set_name);
14087       return -99;
14088     }
14089
14090   if (weight_set == 0)
14091     {
14092       errmsg ("missing locator-set weight");
14093       vec_free (locator_set_name);
14094       return -99;
14095     }
14096
14097   if (vec_len (locator_set_name) > 64)
14098     {
14099       errmsg ("locator-set name too long");
14100       vec_free (locator_set_name);
14101       return -99;
14102     }
14103   vec_add1 (locator_set_name, 0);
14104
14105   /* Construct the API message */
14106   M (ONE_ADD_DEL_LOCATOR, mp);
14107
14108   mp->is_add = is_add;
14109   mp->sw_if_index = ntohl (sw_if_index);
14110   mp->priority = priority;
14111   mp->weight = weight;
14112   clib_memcpy (mp->locator_set_name, locator_set_name,
14113                vec_len (locator_set_name));
14114   vec_free (locator_set_name);
14115
14116   /* send it... */
14117   S (mp);
14118
14119   /* Wait for a reply... */
14120   W (ret);
14121   return ret;
14122 }
14123
14124 #define api_lisp_add_del_locator api_one_add_del_locator
14125
14126 uword
14127 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14128 {
14129   u32 *key_id = va_arg (*args, u32 *);
14130   u8 *s = 0;
14131
14132   if (unformat (input, "%s", &s))
14133     {
14134       if (!strcmp ((char *) s, "sha1"))
14135         key_id[0] = HMAC_SHA_1_96;
14136       else if (!strcmp ((char *) s, "sha256"))
14137         key_id[0] = HMAC_SHA_256_128;
14138       else
14139         {
14140           clib_warning ("invalid key_id: '%s'", s);
14141           key_id[0] = HMAC_NO_KEY;
14142         }
14143     }
14144   else
14145     return 0;
14146
14147   vec_free (s);
14148   return 1;
14149 }
14150
14151 static int
14152 api_one_add_del_local_eid (vat_main_t * vam)
14153 {
14154   unformat_input_t *input = vam->input;
14155   vl_api_one_add_del_local_eid_t *mp;
14156   u8 is_add = 1;
14157   u8 eid_set = 0;
14158   lisp_eid_vat_t _eid, *eid = &_eid;
14159   u8 *locator_set_name = 0;
14160   u8 locator_set_name_set = 0;
14161   u32 vni = 0;
14162   u16 key_id = 0;
14163   u8 *key = 0;
14164   int ret;
14165
14166   /* Parse args required to build the message */
14167   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14168     {
14169       if (unformat (input, "del"))
14170         {
14171           is_add = 0;
14172         }
14173       else if (unformat (input, "vni %d", &vni))
14174         {
14175           ;
14176         }
14177       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14178         {
14179           eid_set = 1;
14180         }
14181       else if (unformat (input, "locator-set %s", &locator_set_name))
14182         {
14183           locator_set_name_set = 1;
14184         }
14185       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14186         ;
14187       else if (unformat (input, "secret-key %_%v%_", &key))
14188         ;
14189       else
14190         break;
14191     }
14192
14193   if (locator_set_name_set == 0)
14194     {
14195       errmsg ("missing locator-set name");
14196       return -99;
14197     }
14198
14199   if (0 == eid_set)
14200     {
14201       errmsg ("EID address not set!");
14202       vec_free (locator_set_name);
14203       return -99;
14204     }
14205
14206   if (key && (0 == key_id))
14207     {
14208       errmsg ("invalid key_id!");
14209       return -99;
14210     }
14211
14212   if (vec_len (key) > 64)
14213     {
14214       errmsg ("key too long");
14215       vec_free (key);
14216       return -99;
14217     }
14218
14219   if (vec_len (locator_set_name) > 64)
14220     {
14221       errmsg ("locator-set name too long");
14222       vec_free (locator_set_name);
14223       return -99;
14224     }
14225   vec_add1 (locator_set_name, 0);
14226
14227   /* Construct the API message */
14228   M (ONE_ADD_DEL_LOCAL_EID, mp);
14229
14230   mp->is_add = is_add;
14231   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14232   mp->eid_type = eid->type;
14233   mp->prefix_len = eid->len;
14234   mp->vni = clib_host_to_net_u32 (vni);
14235   mp->key_id = clib_host_to_net_u16 (key_id);
14236   clib_memcpy (mp->locator_set_name, locator_set_name,
14237                vec_len (locator_set_name));
14238   clib_memcpy (mp->key, key, vec_len (key));
14239
14240   vec_free (locator_set_name);
14241   vec_free (key);
14242
14243   /* send it... */
14244   S (mp);
14245
14246   /* Wait for a reply... */
14247   W (ret);
14248   return ret;
14249 }
14250
14251 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14252
14253 static int
14254 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14255 {
14256   u32 dp_table = 0, vni = 0;;
14257   unformat_input_t *input = vam->input;
14258   vl_api_gpe_add_del_fwd_entry_t *mp;
14259   u8 is_add = 1;
14260   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14261   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14262   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14263   u32 action = ~0, w;
14264   ip4_address_t rmt_rloc4, lcl_rloc4;
14265   ip6_address_t rmt_rloc6, lcl_rloc6;
14266   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14267   int ret;
14268
14269   memset (&rloc, 0, sizeof (rloc));
14270
14271   /* Parse args required to build the message */
14272   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14273     {
14274       if (unformat (input, "del"))
14275         is_add = 0;
14276       else if (unformat (input, "add"))
14277         is_add = 1;
14278       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14279         {
14280           rmt_eid_set = 1;
14281         }
14282       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14283         {
14284           lcl_eid_set = 1;
14285         }
14286       else if (unformat (input, "vrf %d", &dp_table))
14287         ;
14288       else if (unformat (input, "bd %d", &dp_table))
14289         ;
14290       else if (unformat (input, "vni %d", &vni))
14291         ;
14292       else if (unformat (input, "w %d", &w))
14293         {
14294           if (!curr_rloc)
14295             {
14296               errmsg ("No RLOC configured for setting priority/weight!");
14297               return -99;
14298             }
14299           curr_rloc->weight = w;
14300         }
14301       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14302                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14303         {
14304           rloc.is_ip4 = 1;
14305
14306           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
14307           rloc.weight = 0;
14308           vec_add1 (lcl_locs, rloc);
14309
14310           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
14311           vec_add1 (rmt_locs, rloc);
14312           /* weight saved in rmt loc */
14313           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14314         }
14315       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14316                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14317         {
14318           rloc.is_ip4 = 0;
14319           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
14320           rloc.weight = 0;
14321           vec_add1 (lcl_locs, rloc);
14322
14323           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
14324           vec_add1 (rmt_locs, rloc);
14325           /* weight saved in rmt loc */
14326           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14327         }
14328       else if (unformat (input, "action %d", &action))
14329         {
14330           ;
14331         }
14332       else
14333         {
14334           clib_warning ("parse error '%U'", format_unformat_error, input);
14335           return -99;
14336         }
14337     }
14338
14339   if (!rmt_eid_set)
14340     {
14341       errmsg ("remote eid addresses not set");
14342       return -99;
14343     }
14344
14345   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14346     {
14347       errmsg ("eid types don't match");
14348       return -99;
14349     }
14350
14351   if (0 == rmt_locs && (u32) ~ 0 == action)
14352     {
14353       errmsg ("action not set for negative mapping");
14354       return -99;
14355     }
14356
14357   /* Construct the API message */
14358   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14359       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14360
14361   mp->is_add = is_add;
14362   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
14363   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
14364   mp->eid_type = rmt_eid->type;
14365   mp->dp_table = clib_host_to_net_u32 (dp_table);
14366   mp->vni = clib_host_to_net_u32 (vni);
14367   mp->rmt_len = rmt_eid->len;
14368   mp->lcl_len = lcl_eid->len;
14369   mp->action = action;
14370
14371   if (0 != rmt_locs && 0 != lcl_locs)
14372     {
14373       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14374       clib_memcpy (mp->locs, lcl_locs,
14375                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14376
14377       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14378       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14379                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14380     }
14381   vec_free (lcl_locs);
14382   vec_free (rmt_locs);
14383
14384   /* send it... */
14385   S (mp);
14386
14387   /* Wait for a reply... */
14388   W (ret);
14389   return ret;
14390 }
14391
14392 static int
14393 api_one_add_del_map_server (vat_main_t * vam)
14394 {
14395   unformat_input_t *input = vam->input;
14396   vl_api_one_add_del_map_server_t *mp;
14397   u8 is_add = 1;
14398   u8 ipv4_set = 0;
14399   u8 ipv6_set = 0;
14400   ip4_address_t ipv4;
14401   ip6_address_t ipv6;
14402   int ret;
14403
14404   /* Parse args required to build the message */
14405   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14406     {
14407       if (unformat (input, "del"))
14408         {
14409           is_add = 0;
14410         }
14411       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14412         {
14413           ipv4_set = 1;
14414         }
14415       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14416         {
14417           ipv6_set = 1;
14418         }
14419       else
14420         break;
14421     }
14422
14423   if (ipv4_set && ipv6_set)
14424     {
14425       errmsg ("both eid v4 and v6 addresses set");
14426       return -99;
14427     }
14428
14429   if (!ipv4_set && !ipv6_set)
14430     {
14431       errmsg ("eid addresses not set");
14432       return -99;
14433     }
14434
14435   /* Construct the API message */
14436   M (ONE_ADD_DEL_MAP_SERVER, mp);
14437
14438   mp->is_add = is_add;
14439   if (ipv6_set)
14440     {
14441       mp->is_ipv6 = 1;
14442       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14443     }
14444   else
14445     {
14446       mp->is_ipv6 = 0;
14447       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14448     }
14449
14450   /* send it... */
14451   S (mp);
14452
14453   /* Wait for a reply... */
14454   W (ret);
14455   return ret;
14456 }
14457
14458 #define api_lisp_add_del_map_server api_one_add_del_map_server
14459
14460 static int
14461 api_one_add_del_map_resolver (vat_main_t * vam)
14462 {
14463   unformat_input_t *input = vam->input;
14464   vl_api_one_add_del_map_resolver_t *mp;
14465   u8 is_add = 1;
14466   u8 ipv4_set = 0;
14467   u8 ipv6_set = 0;
14468   ip4_address_t ipv4;
14469   ip6_address_t ipv6;
14470   int ret;
14471
14472   /* Parse args required to build the message */
14473   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14474     {
14475       if (unformat (input, "del"))
14476         {
14477           is_add = 0;
14478         }
14479       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14480         {
14481           ipv4_set = 1;
14482         }
14483       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14484         {
14485           ipv6_set = 1;
14486         }
14487       else
14488         break;
14489     }
14490
14491   if (ipv4_set && ipv6_set)
14492     {
14493       errmsg ("both eid v4 and v6 addresses set");
14494       return -99;
14495     }
14496
14497   if (!ipv4_set && !ipv6_set)
14498     {
14499       errmsg ("eid addresses not set");
14500       return -99;
14501     }
14502
14503   /* Construct the API message */
14504   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14505
14506   mp->is_add = is_add;
14507   if (ipv6_set)
14508     {
14509       mp->is_ipv6 = 1;
14510       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14511     }
14512   else
14513     {
14514       mp->is_ipv6 = 0;
14515       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14516     }
14517
14518   /* send it... */
14519   S (mp);
14520
14521   /* Wait for a reply... */
14522   W (ret);
14523   return ret;
14524 }
14525
14526 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14527
14528 static int
14529 api_lisp_gpe_enable_disable (vat_main_t * vam)
14530 {
14531   unformat_input_t *input = vam->input;
14532   vl_api_gpe_enable_disable_t *mp;
14533   u8 is_set = 0;
14534   u8 is_en = 1;
14535   int ret;
14536
14537   /* Parse args required to build the message */
14538   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14539     {
14540       if (unformat (input, "enable"))
14541         {
14542           is_set = 1;
14543           is_en = 1;
14544         }
14545       else if (unformat (input, "disable"))
14546         {
14547           is_set = 1;
14548           is_en = 0;
14549         }
14550       else
14551         break;
14552     }
14553
14554   if (is_set == 0)
14555     {
14556       errmsg ("Value not set");
14557       return -99;
14558     }
14559
14560   /* Construct the API message */
14561   M (GPE_ENABLE_DISABLE, mp);
14562
14563   mp->is_en = is_en;
14564
14565   /* send it... */
14566   S (mp);
14567
14568   /* Wait for a reply... */
14569   W (ret);
14570   return ret;
14571 }
14572
14573 static int
14574 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14575 {
14576   unformat_input_t *input = vam->input;
14577   vl_api_one_rloc_probe_enable_disable_t *mp;
14578   u8 is_set = 0;
14579   u8 is_en = 0;
14580   int ret;
14581
14582   /* Parse args required to build the message */
14583   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14584     {
14585       if (unformat (input, "enable"))
14586         {
14587           is_set = 1;
14588           is_en = 1;
14589         }
14590       else if (unformat (input, "disable"))
14591         is_set = 1;
14592       else
14593         break;
14594     }
14595
14596   if (!is_set)
14597     {
14598       errmsg ("Value not set");
14599       return -99;
14600     }
14601
14602   /* Construct the API message */
14603   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14604
14605   mp->is_enabled = is_en;
14606
14607   /* send it... */
14608   S (mp);
14609
14610   /* Wait for a reply... */
14611   W (ret);
14612   return ret;
14613 }
14614
14615 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14616
14617 static int
14618 api_one_map_register_enable_disable (vat_main_t * vam)
14619 {
14620   unformat_input_t *input = vam->input;
14621   vl_api_one_map_register_enable_disable_t *mp;
14622   u8 is_set = 0;
14623   u8 is_en = 0;
14624   int ret;
14625
14626   /* Parse args required to build the message */
14627   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14628     {
14629       if (unformat (input, "enable"))
14630         {
14631           is_set = 1;
14632           is_en = 1;
14633         }
14634       else if (unformat (input, "disable"))
14635         is_set = 1;
14636       else
14637         break;
14638     }
14639
14640   if (!is_set)
14641     {
14642       errmsg ("Value not set");
14643       return -99;
14644     }
14645
14646   /* Construct the API message */
14647   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14648
14649   mp->is_enabled = is_en;
14650
14651   /* send it... */
14652   S (mp);
14653
14654   /* Wait for a reply... */
14655   W (ret);
14656   return ret;
14657 }
14658
14659 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14660
14661 static int
14662 api_one_enable_disable (vat_main_t * vam)
14663 {
14664   unformat_input_t *input = vam->input;
14665   vl_api_one_enable_disable_t *mp;
14666   u8 is_set = 0;
14667   u8 is_en = 0;
14668   int ret;
14669
14670   /* Parse args required to build the message */
14671   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14672     {
14673       if (unformat (input, "enable"))
14674         {
14675           is_set = 1;
14676           is_en = 1;
14677         }
14678       else if (unformat (input, "disable"))
14679         {
14680           is_set = 1;
14681         }
14682       else
14683         break;
14684     }
14685
14686   if (!is_set)
14687     {
14688       errmsg ("Value not set");
14689       return -99;
14690     }
14691
14692   /* Construct the API message */
14693   M (ONE_ENABLE_DISABLE, mp);
14694
14695   mp->is_en = is_en;
14696
14697   /* send it... */
14698   S (mp);
14699
14700   /* Wait for a reply... */
14701   W (ret);
14702   return ret;
14703 }
14704
14705 #define api_lisp_enable_disable api_one_enable_disable
14706
14707 static int
14708 api_show_one_map_register_state (vat_main_t * vam)
14709 {
14710   vl_api_show_one_map_register_state_t *mp;
14711   int ret;
14712
14713   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
14714
14715   /* send */
14716   S (mp);
14717
14718   /* wait for reply */
14719   W (ret);
14720   return ret;
14721 }
14722
14723 #define api_show_lisp_map_register_state api_show_one_map_register_state
14724
14725 static int
14726 api_show_one_rloc_probe_state (vat_main_t * vam)
14727 {
14728   vl_api_show_one_rloc_probe_state_t *mp;
14729   int ret;
14730
14731   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
14732
14733   /* send */
14734   S (mp);
14735
14736   /* wait for reply */
14737   W (ret);
14738   return ret;
14739 }
14740
14741 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
14742
14743 static int
14744 api_one_stats_enable_disable (vat_main_t * vam)
14745 {
14746   vl_api_one_stats_enable_disable_t *mp;
14747   unformat_input_t *input = vam->input;
14748   u8 is_set = 0;
14749   u8 is_en = 0;
14750   int ret;
14751
14752   /* Parse args required to build the message */
14753   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14754     {
14755       if (unformat (input, "enable"))
14756         {
14757           is_set = 1;
14758           is_en = 1;
14759         }
14760       else if (unformat (input, "disable"))
14761         {
14762           is_set = 1;
14763         }
14764       else
14765         break;
14766     }
14767
14768   if (!is_set)
14769     {
14770       errmsg ("Value not set");
14771       return -99;
14772     }
14773
14774   M (ONE_STATS_ENABLE_DISABLE, mp);
14775   mp->is_en = is_en;
14776
14777   /* send */
14778   S (mp);
14779
14780   /* wait for reply */
14781   W (ret);
14782   return ret;
14783 }
14784
14785 static int
14786 api_show_one_stats_enable_disable (vat_main_t * vam)
14787 {
14788   vl_api_show_one_stats_enable_disable_t *mp;
14789   int ret;
14790
14791   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
14792
14793   /* send */
14794   S (mp);
14795
14796   /* wait for reply */
14797   W (ret);
14798   return ret;
14799 }
14800
14801 static int
14802 api_show_one_map_request_mode (vat_main_t * vam)
14803 {
14804   vl_api_show_one_map_request_mode_t *mp;
14805   int ret;
14806
14807   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
14808
14809   /* send */
14810   S (mp);
14811
14812   /* wait for reply */
14813   W (ret);
14814   return ret;
14815 }
14816
14817 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
14818
14819 static int
14820 api_one_map_request_mode (vat_main_t * vam)
14821 {
14822   unformat_input_t *input = vam->input;
14823   vl_api_one_map_request_mode_t *mp;
14824   u8 mode = 0;
14825   int ret;
14826
14827   /* Parse args required to build the message */
14828   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14829     {
14830       if (unformat (input, "dst-only"))
14831         mode = 0;
14832       else if (unformat (input, "src-dst"))
14833         mode = 1;
14834       else
14835         {
14836           errmsg ("parse error '%U'", format_unformat_error, input);
14837           return -99;
14838         }
14839     }
14840
14841   M (ONE_MAP_REQUEST_MODE, mp);
14842
14843   mp->mode = mode;
14844
14845   /* send */
14846   S (mp);
14847
14848   /* wait for reply */
14849   W (ret);
14850   return ret;
14851 }
14852
14853 #define api_lisp_map_request_mode api_one_map_request_mode
14854
14855 /**
14856  * Enable/disable ONE proxy ITR.
14857  *
14858  * @param vam vpp API test context
14859  * @return return code
14860  */
14861 static int
14862 api_one_pitr_set_locator_set (vat_main_t * vam)
14863 {
14864   u8 ls_name_set = 0;
14865   unformat_input_t *input = vam->input;
14866   vl_api_one_pitr_set_locator_set_t *mp;
14867   u8 is_add = 1;
14868   u8 *ls_name = 0;
14869   int ret;
14870
14871   /* Parse args required to build the message */
14872   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14873     {
14874       if (unformat (input, "del"))
14875         is_add = 0;
14876       else if (unformat (input, "locator-set %s", &ls_name))
14877         ls_name_set = 1;
14878       else
14879         {
14880           errmsg ("parse error '%U'", format_unformat_error, input);
14881           return -99;
14882         }
14883     }
14884
14885   if (!ls_name_set)
14886     {
14887       errmsg ("locator-set name not set!");
14888       return -99;
14889     }
14890
14891   M (ONE_PITR_SET_LOCATOR_SET, mp);
14892
14893   mp->is_add = is_add;
14894   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
14895   vec_free (ls_name);
14896
14897   /* send */
14898   S (mp);
14899
14900   /* wait for reply */
14901   W (ret);
14902   return ret;
14903 }
14904
14905 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
14906
14907 static int
14908 api_show_one_pitr (vat_main_t * vam)
14909 {
14910   vl_api_show_one_pitr_t *mp;
14911   int ret;
14912
14913   if (!vam->json_output)
14914     {
14915       print (vam->ofp, "%=20s", "lisp status:");
14916     }
14917
14918   M (SHOW_ONE_PITR, mp);
14919   /* send it... */
14920   S (mp);
14921
14922   /* Wait for a reply... */
14923   W (ret);
14924   return ret;
14925 }
14926
14927 #define api_show_lisp_pitr api_show_one_pitr
14928
14929 static int
14930 api_one_use_petr (vat_main_t * vam)
14931 {
14932   unformat_input_t *input = vam->input;
14933   vl_api_one_use_petr_t *mp;
14934   u8 is_add = 0;
14935   ip_address_t ip;
14936   int ret;
14937
14938   memset (&ip, 0, sizeof (ip));
14939
14940   /* Parse args required to build the message */
14941   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14942     {
14943       if (unformat (input, "disable"))
14944         is_add = 0;
14945       else
14946         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
14947         {
14948           is_add = 1;
14949           ip_addr_version (&ip) = IP4;
14950         }
14951       else
14952         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
14953         {
14954           is_add = 1;
14955           ip_addr_version (&ip) = IP6;
14956         }
14957       else
14958         {
14959           errmsg ("parse error '%U'", format_unformat_error, input);
14960           return -99;
14961         }
14962     }
14963
14964   M (ONE_USE_PETR, mp);
14965
14966   mp->is_add = is_add;
14967   if (is_add)
14968     {
14969       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
14970       if (mp->is_ip4)
14971         clib_memcpy (mp->address, &ip, 4);
14972       else
14973         clib_memcpy (mp->address, &ip, 16);
14974     }
14975
14976   /* send */
14977   S (mp);
14978
14979   /* wait for reply */
14980   W (ret);
14981   return ret;
14982 }
14983
14984 #define api_lisp_use_petr api_one_use_petr
14985
14986 static int
14987 api_show_one_use_petr (vat_main_t * vam)
14988 {
14989   vl_api_show_one_use_petr_t *mp;
14990   int ret;
14991
14992   if (!vam->json_output)
14993     {
14994       print (vam->ofp, "%=20s", "Proxy-ETR status:");
14995     }
14996
14997   M (SHOW_ONE_USE_PETR, mp);
14998   /* send it... */
14999   S (mp);
15000
15001   /* Wait for a reply... */
15002   W (ret);
15003   return ret;
15004 }
15005
15006 #define api_show_lisp_use_petr api_show_one_use_petr
15007
15008 /**
15009  * Add/delete mapping between vni and vrf
15010  */
15011 static int
15012 api_one_eid_table_add_del_map (vat_main_t * vam)
15013 {
15014   unformat_input_t *input = vam->input;
15015   vl_api_one_eid_table_add_del_map_t *mp;
15016   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15017   u32 vni, vrf, bd_index;
15018   int ret;
15019
15020   /* Parse args required to build the message */
15021   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15022     {
15023       if (unformat (input, "del"))
15024         is_add = 0;
15025       else if (unformat (input, "vrf %d", &vrf))
15026         vrf_set = 1;
15027       else if (unformat (input, "bd_index %d", &bd_index))
15028         bd_index_set = 1;
15029       else if (unformat (input, "vni %d", &vni))
15030         vni_set = 1;
15031       else
15032         break;
15033     }
15034
15035   if (!vni_set || (!vrf_set && !bd_index_set))
15036     {
15037       errmsg ("missing arguments!");
15038       return -99;
15039     }
15040
15041   if (vrf_set && bd_index_set)
15042     {
15043       errmsg ("error: both vrf and bd entered!");
15044       return -99;
15045     }
15046
15047   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15048
15049   mp->is_add = is_add;
15050   mp->vni = htonl (vni);
15051   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15052   mp->is_l2 = bd_index_set;
15053
15054   /* send */
15055   S (mp);
15056
15057   /* wait for reply */
15058   W (ret);
15059   return ret;
15060 }
15061
15062 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15063
15064 uword
15065 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15066 {
15067   u32 *action = va_arg (*args, u32 *);
15068   u8 *s = 0;
15069
15070   if (unformat (input, "%s", &s))
15071     {
15072       if (!strcmp ((char *) s, "no-action"))
15073         action[0] = 0;
15074       else if (!strcmp ((char *) s, "natively-forward"))
15075         action[0] = 1;
15076       else if (!strcmp ((char *) s, "send-map-request"))
15077         action[0] = 2;
15078       else if (!strcmp ((char *) s, "drop"))
15079         action[0] = 3;
15080       else
15081         {
15082           clib_warning ("invalid action: '%s'", s);
15083           action[0] = 3;
15084         }
15085     }
15086   else
15087     return 0;
15088
15089   vec_free (s);
15090   return 1;
15091 }
15092
15093 /**
15094  * Add/del remote mapping to/from ONE control plane
15095  *
15096  * @param vam vpp API test context
15097  * @return return code
15098  */
15099 static int
15100 api_one_add_del_remote_mapping (vat_main_t * vam)
15101 {
15102   unformat_input_t *input = vam->input;
15103   vl_api_one_add_del_remote_mapping_t *mp;
15104   u32 vni = 0;
15105   lisp_eid_vat_t _eid, *eid = &_eid;
15106   lisp_eid_vat_t _seid, *seid = &_seid;
15107   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15108   u32 action = ~0, p, w, data_len;
15109   ip4_address_t rloc4;
15110   ip6_address_t rloc6;
15111   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15112   int ret;
15113
15114   memset (&rloc, 0, sizeof (rloc));
15115
15116   /* Parse args required to build the message */
15117   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15118     {
15119       if (unformat (input, "del-all"))
15120         {
15121           del_all = 1;
15122         }
15123       else if (unformat (input, "del"))
15124         {
15125           is_add = 0;
15126         }
15127       else if (unformat (input, "add"))
15128         {
15129           is_add = 1;
15130         }
15131       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15132         {
15133           eid_set = 1;
15134         }
15135       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15136         {
15137           seid_set = 1;
15138         }
15139       else if (unformat (input, "vni %d", &vni))
15140         {
15141           ;
15142         }
15143       else if (unformat (input, "p %d w %d", &p, &w))
15144         {
15145           if (!curr_rloc)
15146             {
15147               errmsg ("No RLOC configured for setting priority/weight!");
15148               return -99;
15149             }
15150           curr_rloc->priority = p;
15151           curr_rloc->weight = w;
15152         }
15153       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15154         {
15155           rloc.is_ip4 = 1;
15156           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
15157           vec_add1 (rlocs, rloc);
15158           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15159         }
15160       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15161         {
15162           rloc.is_ip4 = 0;
15163           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
15164           vec_add1 (rlocs, rloc);
15165           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15166         }
15167       else if (unformat (input, "action %U",
15168                          unformat_negative_mapping_action, &action))
15169         {
15170           ;
15171         }
15172       else
15173         {
15174           clib_warning ("parse error '%U'", format_unformat_error, input);
15175           return -99;
15176         }
15177     }
15178
15179   if (0 == eid_set)
15180     {
15181       errmsg ("missing params!");
15182       return -99;
15183     }
15184
15185   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15186     {
15187       errmsg ("no action set for negative map-reply!");
15188       return -99;
15189     }
15190
15191   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15192
15193   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15194   mp->is_add = is_add;
15195   mp->vni = htonl (vni);
15196   mp->action = (u8) action;
15197   mp->is_src_dst = seid_set;
15198   mp->eid_len = eid->len;
15199   mp->seid_len = seid->len;
15200   mp->del_all = del_all;
15201   mp->eid_type = eid->type;
15202   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15203   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
15204
15205   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15206   clib_memcpy (mp->rlocs, rlocs, data_len);
15207   vec_free (rlocs);
15208
15209   /* send it... */
15210   S (mp);
15211
15212   /* Wait for a reply... */
15213   W (ret);
15214   return ret;
15215 }
15216
15217 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15218
15219 /**
15220  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15221  * forwarding entries in data-plane accordingly.
15222  *
15223  * @param vam vpp API test context
15224  * @return return code
15225  */
15226 static int
15227 api_one_add_del_adjacency (vat_main_t * vam)
15228 {
15229   unformat_input_t *input = vam->input;
15230   vl_api_one_add_del_adjacency_t *mp;
15231   u32 vni = 0;
15232   ip4_address_t leid4, reid4;
15233   ip6_address_t leid6, reid6;
15234   u8 reid_mac[6] = { 0 };
15235   u8 leid_mac[6] = { 0 };
15236   u8 reid_type, leid_type;
15237   u32 leid_len = 0, reid_len = 0, len;
15238   u8 is_add = 1;
15239   int ret;
15240
15241   leid_type = reid_type = (u8) ~ 0;
15242
15243   /* Parse args required to build the message */
15244   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15245     {
15246       if (unformat (input, "del"))
15247         {
15248           is_add = 0;
15249         }
15250       else if (unformat (input, "add"))
15251         {
15252           is_add = 1;
15253         }
15254       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
15255                          &reid4, &len))
15256         {
15257           reid_type = 0;        /* ipv4 */
15258           reid_len = len;
15259         }
15260       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
15261                          &reid6, &len))
15262         {
15263           reid_type = 1;        /* ipv6 */
15264           reid_len = len;
15265         }
15266       else if (unformat (input, "reid %U", unformat_ethernet_address,
15267                          reid_mac))
15268         {
15269           reid_type = 2;        /* mac */
15270         }
15271       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
15272                          &leid4, &len))
15273         {
15274           leid_type = 0;        /* ipv4 */
15275           leid_len = len;
15276         }
15277       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
15278                          &leid6, &len))
15279         {
15280           leid_type = 1;        /* ipv6 */
15281           leid_len = len;
15282         }
15283       else if (unformat (input, "leid %U", unformat_ethernet_address,
15284                          leid_mac))
15285         {
15286           leid_type = 2;        /* mac */
15287         }
15288       else if (unformat (input, "vni %d", &vni))
15289         {
15290           ;
15291         }
15292       else
15293         {
15294           errmsg ("parse error '%U'", format_unformat_error, input);
15295           return -99;
15296         }
15297     }
15298
15299   if ((u8) ~ 0 == reid_type)
15300     {
15301       errmsg ("missing params!");
15302       return -99;
15303     }
15304
15305   if (leid_type != reid_type)
15306     {
15307       errmsg ("remote and local EIDs are of different types!");
15308       return -99;
15309     }
15310
15311   M (ONE_ADD_DEL_ADJACENCY, mp);
15312   mp->is_add = is_add;
15313   mp->vni = htonl (vni);
15314   mp->leid_len = leid_len;
15315   mp->reid_len = reid_len;
15316   mp->eid_type = reid_type;
15317
15318   switch (mp->eid_type)
15319     {
15320     case 0:
15321       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
15322       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
15323       break;
15324     case 1:
15325       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
15326       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
15327       break;
15328     case 2:
15329       clib_memcpy (mp->leid, leid_mac, 6);
15330       clib_memcpy (mp->reid, reid_mac, 6);
15331       break;
15332     default:
15333       errmsg ("unknown EID type %d!", mp->eid_type);
15334       return 0;
15335     }
15336
15337   /* send it... */
15338   S (mp);
15339
15340   /* Wait for a reply... */
15341   W (ret);
15342   return ret;
15343 }
15344
15345 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
15346
15347 uword
15348 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
15349 {
15350   u32 *mode = va_arg (*args, u32 *);
15351
15352   if (unformat (input, "lisp"))
15353     *mode = 0;
15354   else if (unformat (input, "vxlan"))
15355     *mode = 1;
15356   else
15357     return 0;
15358
15359   return 1;
15360 }
15361
15362 static int
15363 api_gpe_get_encap_mode (vat_main_t * vam)
15364 {
15365   vl_api_gpe_get_encap_mode_t *mp;
15366   int ret;
15367
15368   /* Construct the API message */
15369   M (GPE_GET_ENCAP_MODE, mp);
15370
15371   /* send it... */
15372   S (mp);
15373
15374   /* Wait for a reply... */
15375   W (ret);
15376   return ret;
15377 }
15378
15379 static int
15380 api_gpe_set_encap_mode (vat_main_t * vam)
15381 {
15382   unformat_input_t *input = vam->input;
15383   vl_api_gpe_set_encap_mode_t *mp;
15384   int ret;
15385   u32 mode = 0;
15386
15387   /* Parse args required to build the message */
15388   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15389     {
15390       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
15391         ;
15392       else
15393         break;
15394     }
15395
15396   /* Construct the API message */
15397   M (GPE_SET_ENCAP_MODE, mp);
15398
15399   mp->mode = mode;
15400
15401   /* send it... */
15402   S (mp);
15403
15404   /* Wait for a reply... */
15405   W (ret);
15406   return ret;
15407 }
15408
15409 static int
15410 api_lisp_gpe_add_del_iface (vat_main_t * vam)
15411 {
15412   unformat_input_t *input = vam->input;
15413   vl_api_gpe_add_del_iface_t *mp;
15414   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
15415   u32 dp_table = 0, vni = 0;
15416   int ret;
15417
15418   /* Parse args required to build the message */
15419   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15420     {
15421       if (unformat (input, "up"))
15422         {
15423           action_set = 1;
15424           is_add = 1;
15425         }
15426       else if (unformat (input, "down"))
15427         {
15428           action_set = 1;
15429           is_add = 0;
15430         }
15431       else if (unformat (input, "table_id %d", &dp_table))
15432         {
15433           dp_table_set = 1;
15434         }
15435       else if (unformat (input, "bd_id %d", &dp_table))
15436         {
15437           dp_table_set = 1;
15438           is_l2 = 1;
15439         }
15440       else if (unformat (input, "vni %d", &vni))
15441         {
15442           vni_set = 1;
15443         }
15444       else
15445         break;
15446     }
15447
15448   if (action_set == 0)
15449     {
15450       errmsg ("Action not set");
15451       return -99;
15452     }
15453   if (dp_table_set == 0 || vni_set == 0)
15454     {
15455       errmsg ("vni and dp_table must be set");
15456       return -99;
15457     }
15458
15459   /* Construct the API message */
15460   M (GPE_ADD_DEL_IFACE, mp);
15461
15462   mp->is_add = is_add;
15463   mp->dp_table = dp_table;
15464   mp->is_l2 = is_l2;
15465   mp->vni = vni;
15466
15467   /* send it... */
15468   S (mp);
15469
15470   /* Wait for a reply... */
15471   W (ret);
15472   return ret;
15473 }
15474
15475 /**
15476  * Add/del map request itr rlocs from ONE control plane and updates
15477  *
15478  * @param vam vpp API test context
15479  * @return return code
15480  */
15481 static int
15482 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
15483 {
15484   unformat_input_t *input = vam->input;
15485   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
15486   u8 *locator_set_name = 0;
15487   u8 locator_set_name_set = 0;
15488   u8 is_add = 1;
15489   int ret;
15490
15491   /* Parse args required to build the message */
15492   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15493     {
15494       if (unformat (input, "del"))
15495         {
15496           is_add = 0;
15497         }
15498       else if (unformat (input, "%_%v%_", &locator_set_name))
15499         {
15500           locator_set_name_set = 1;
15501         }
15502       else
15503         {
15504           clib_warning ("parse error '%U'", format_unformat_error, input);
15505           return -99;
15506         }
15507     }
15508
15509   if (is_add && !locator_set_name_set)
15510     {
15511       errmsg ("itr-rloc is not set!");
15512       return -99;
15513     }
15514
15515   if (is_add && vec_len (locator_set_name) > 64)
15516     {
15517       errmsg ("itr-rloc locator-set name too long");
15518       vec_free (locator_set_name);
15519       return -99;
15520     }
15521
15522   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
15523   mp->is_add = is_add;
15524   if (is_add)
15525     {
15526       clib_memcpy (mp->locator_set_name, locator_set_name,
15527                    vec_len (locator_set_name));
15528     }
15529   else
15530     {
15531       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
15532     }
15533   vec_free (locator_set_name);
15534
15535   /* send it... */
15536   S (mp);
15537
15538   /* Wait for a reply... */
15539   W (ret);
15540   return ret;
15541 }
15542
15543 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
15544
15545 static int
15546 api_one_locator_dump (vat_main_t * vam)
15547 {
15548   unformat_input_t *input = vam->input;
15549   vl_api_one_locator_dump_t *mp;
15550   vl_api_control_ping_t *mp_ping;
15551   u8 is_index_set = 0, is_name_set = 0;
15552   u8 *ls_name = 0;
15553   u32 ls_index = ~0;
15554   int ret;
15555
15556   /* Parse args required to build the message */
15557   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15558     {
15559       if (unformat (input, "ls_name %_%v%_", &ls_name))
15560         {
15561           is_name_set = 1;
15562         }
15563       else if (unformat (input, "ls_index %d", &ls_index))
15564         {
15565           is_index_set = 1;
15566         }
15567       else
15568         {
15569           errmsg ("parse error '%U'", format_unformat_error, input);
15570           return -99;
15571         }
15572     }
15573
15574   if (!is_index_set && !is_name_set)
15575     {
15576       errmsg ("error: expected one of index or name!");
15577       return -99;
15578     }
15579
15580   if (is_index_set && is_name_set)
15581     {
15582       errmsg ("error: only one param expected!");
15583       return -99;
15584     }
15585
15586   if (vec_len (ls_name) > 62)
15587     {
15588       errmsg ("error: locator set name too long!");
15589       return -99;
15590     }
15591
15592   if (!vam->json_output)
15593     {
15594       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
15595     }
15596
15597   M (ONE_LOCATOR_DUMP, mp);
15598   mp->is_index_set = is_index_set;
15599
15600   if (is_index_set)
15601     mp->ls_index = clib_host_to_net_u32 (ls_index);
15602   else
15603     {
15604       vec_add1 (ls_name, 0);
15605       strncpy ((char *) mp->ls_name, (char *) ls_name,
15606                sizeof (mp->ls_name) - 1);
15607     }
15608
15609   /* send it... */
15610   S (mp);
15611
15612   /* Use a control ping for synchronization */
15613   M (CONTROL_PING, mp_ping);
15614   S (mp_ping);
15615
15616   /* Wait for a reply... */
15617   W (ret);
15618   return ret;
15619 }
15620
15621 #define api_lisp_locator_dump api_one_locator_dump
15622
15623 static int
15624 api_one_locator_set_dump (vat_main_t * vam)
15625 {
15626   vl_api_one_locator_set_dump_t *mp;
15627   vl_api_control_ping_t *mp_ping;
15628   unformat_input_t *input = vam->input;
15629   u8 filter = 0;
15630   int ret;
15631
15632   /* Parse args required to build the message */
15633   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15634     {
15635       if (unformat (input, "local"))
15636         {
15637           filter = 1;
15638         }
15639       else if (unformat (input, "remote"))
15640         {
15641           filter = 2;
15642         }
15643       else
15644         {
15645           errmsg ("parse error '%U'", format_unformat_error, input);
15646           return -99;
15647         }
15648     }
15649
15650   if (!vam->json_output)
15651     {
15652       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
15653     }
15654
15655   M (ONE_LOCATOR_SET_DUMP, mp);
15656
15657   mp->filter = filter;
15658
15659   /* send it... */
15660   S (mp);
15661
15662   /* Use a control ping for synchronization */
15663   M (CONTROL_PING, mp_ping);
15664   S (mp_ping);
15665
15666   /* Wait for a reply... */
15667   W (ret);
15668   return ret;
15669 }
15670
15671 #define api_lisp_locator_set_dump api_one_locator_set_dump
15672
15673 static int
15674 api_one_eid_table_map_dump (vat_main_t * vam)
15675 {
15676   u8 is_l2 = 0;
15677   u8 mode_set = 0;
15678   unformat_input_t *input = vam->input;
15679   vl_api_one_eid_table_map_dump_t *mp;
15680   vl_api_control_ping_t *mp_ping;
15681   int ret;
15682
15683   /* Parse args required to build the message */
15684   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15685     {
15686       if (unformat (input, "l2"))
15687         {
15688           is_l2 = 1;
15689           mode_set = 1;
15690         }
15691       else if (unformat (input, "l3"))
15692         {
15693           is_l2 = 0;
15694           mode_set = 1;
15695         }
15696       else
15697         {
15698           errmsg ("parse error '%U'", format_unformat_error, input);
15699           return -99;
15700         }
15701     }
15702
15703   if (!mode_set)
15704     {
15705       errmsg ("expected one of 'l2' or 'l3' parameter!");
15706       return -99;
15707     }
15708
15709   if (!vam->json_output)
15710     {
15711       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
15712     }
15713
15714   M (ONE_EID_TABLE_MAP_DUMP, mp);
15715   mp->is_l2 = is_l2;
15716
15717   /* send it... */
15718   S (mp);
15719
15720   /* Use a control ping for synchronization */
15721   M (CONTROL_PING, mp_ping);
15722   S (mp_ping);
15723
15724   /* Wait for a reply... */
15725   W (ret);
15726   return ret;
15727 }
15728
15729 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
15730
15731 static int
15732 api_one_eid_table_vni_dump (vat_main_t * vam)
15733 {
15734   vl_api_one_eid_table_vni_dump_t *mp;
15735   vl_api_control_ping_t *mp_ping;
15736   int ret;
15737
15738   if (!vam->json_output)
15739     {
15740       print (vam->ofp, "VNI");
15741     }
15742
15743   M (ONE_EID_TABLE_VNI_DUMP, mp);
15744
15745   /* send it... */
15746   S (mp);
15747
15748   /* Use a control ping for synchronization */
15749   M (CONTROL_PING, mp_ping);
15750   S (mp_ping);
15751
15752   /* Wait for a reply... */
15753   W (ret);
15754   return ret;
15755 }
15756
15757 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
15758
15759 static int
15760 api_one_eid_table_dump (vat_main_t * vam)
15761 {
15762   unformat_input_t *i = vam->input;
15763   vl_api_one_eid_table_dump_t *mp;
15764   vl_api_control_ping_t *mp_ping;
15765   struct in_addr ip4;
15766   struct in6_addr ip6;
15767   u8 mac[6];
15768   u8 eid_type = ~0, eid_set = 0;
15769   u32 prefix_length = ~0, t, vni = 0;
15770   u8 filter = 0;
15771   int ret;
15772
15773   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15774     {
15775       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
15776         {
15777           eid_set = 1;
15778           eid_type = 0;
15779           prefix_length = t;
15780         }
15781       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
15782         {
15783           eid_set = 1;
15784           eid_type = 1;
15785           prefix_length = t;
15786         }
15787       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
15788         {
15789           eid_set = 1;
15790           eid_type = 2;
15791         }
15792       else if (unformat (i, "vni %d", &t))
15793         {
15794           vni = t;
15795         }
15796       else if (unformat (i, "local"))
15797         {
15798           filter = 1;
15799         }
15800       else if (unformat (i, "remote"))
15801         {
15802           filter = 2;
15803         }
15804       else
15805         {
15806           errmsg ("parse error '%U'", format_unformat_error, i);
15807           return -99;
15808         }
15809     }
15810
15811   if (!vam->json_output)
15812     {
15813       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
15814              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
15815     }
15816
15817   M (ONE_EID_TABLE_DUMP, mp);
15818
15819   mp->filter = filter;
15820   if (eid_set)
15821     {
15822       mp->eid_set = 1;
15823       mp->vni = htonl (vni);
15824       mp->eid_type = eid_type;
15825       switch (eid_type)
15826         {
15827         case 0:
15828           mp->prefix_length = prefix_length;
15829           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
15830           break;
15831         case 1:
15832           mp->prefix_length = prefix_length;
15833           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
15834           break;
15835         case 2:
15836           clib_memcpy (mp->eid, mac, sizeof (mac));
15837           break;
15838         default:
15839           errmsg ("unknown EID type %d!", eid_type);
15840           return -99;
15841         }
15842     }
15843
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_eid_table_dump api_one_eid_table_dump
15857
15858 static int
15859 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
15860 {
15861   unformat_input_t *i = vam->input;
15862   vl_api_gpe_fwd_entries_get_t *mp;
15863   u8 vni_set = 0;
15864   u32 vni = ~0;
15865   int ret;
15866
15867   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15868     {
15869       if (unformat (i, "vni %d", &vni))
15870         {
15871           vni_set = 1;
15872         }
15873       else
15874         {
15875           errmsg ("parse error '%U'", format_unformat_error, i);
15876           return -99;
15877         }
15878     }
15879
15880   if (!vni_set)
15881     {
15882       errmsg ("vni not set!");
15883       return -99;
15884     }
15885
15886   if (!vam->json_output)
15887     {
15888       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
15889              "leid", "reid");
15890     }
15891
15892   M (GPE_FWD_ENTRIES_GET, mp);
15893   mp->vni = clib_host_to_net_u32 (vni);
15894
15895   /* send it... */
15896   S (mp);
15897
15898   /* Wait for a reply... */
15899   W (ret);
15900   return ret;
15901 }
15902
15903 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
15904 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
15905 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
15906 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
15907
15908 static int
15909 api_one_adjacencies_get (vat_main_t * vam)
15910 {
15911   unformat_input_t *i = vam->input;
15912   vl_api_one_adjacencies_get_t *mp;
15913   u8 vni_set = 0;
15914   u32 vni = ~0;
15915   int ret;
15916
15917   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15918     {
15919       if (unformat (i, "vni %d", &vni))
15920         {
15921           vni_set = 1;
15922         }
15923       else
15924         {
15925           errmsg ("parse error '%U'", format_unformat_error, i);
15926           return -99;
15927         }
15928     }
15929
15930   if (!vni_set)
15931     {
15932       errmsg ("vni not set!");
15933       return -99;
15934     }
15935
15936   if (!vam->json_output)
15937     {
15938       print (vam->ofp, "%s %40s", "leid", "reid");
15939     }
15940
15941   M (ONE_ADJACENCIES_GET, mp);
15942   mp->vni = clib_host_to_net_u32 (vni);
15943
15944   /* send it... */
15945   S (mp);
15946
15947   /* Wait for a reply... */
15948   W (ret);
15949   return ret;
15950 }
15951
15952 #define api_lisp_adjacencies_get api_one_adjacencies_get
15953
15954 static int
15955 api_one_map_server_dump (vat_main_t * vam)
15956 {
15957   vl_api_one_map_server_dump_t *mp;
15958   vl_api_control_ping_t *mp_ping;
15959   int ret;
15960
15961   if (!vam->json_output)
15962     {
15963       print (vam->ofp, "%=20s", "Map server");
15964     }
15965
15966   M (ONE_MAP_SERVER_DUMP, mp);
15967   /* send it... */
15968   S (mp);
15969
15970   /* Use a control ping for synchronization */
15971   M (CONTROL_PING, mp_ping);
15972   S (mp_ping);
15973
15974   /* Wait for a reply... */
15975   W (ret);
15976   return ret;
15977 }
15978
15979 #define api_lisp_map_server_dump api_one_map_server_dump
15980
15981 static int
15982 api_one_map_resolver_dump (vat_main_t * vam)
15983 {
15984   vl_api_one_map_resolver_dump_t *mp;
15985   vl_api_control_ping_t *mp_ping;
15986   int ret;
15987
15988   if (!vam->json_output)
15989     {
15990       print (vam->ofp, "%=20s", "Map resolver");
15991     }
15992
15993   M (ONE_MAP_RESOLVER_DUMP, mp);
15994   /* send it... */
15995   S (mp);
15996
15997   /* Use a control ping for synchronization */
15998   M (CONTROL_PING, mp_ping);
15999   S (mp_ping);
16000
16001   /* Wait for a reply... */
16002   W (ret);
16003   return ret;
16004 }
16005
16006 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
16007
16008 static int
16009 api_one_stats_flush (vat_main_t * vam)
16010 {
16011   vl_api_one_stats_flush_t *mp;
16012   int ret = 0;
16013
16014   M (ONE_STATS_FLUSH, mp);
16015   S (mp);
16016   W (ret);
16017   return ret;
16018 }
16019
16020 static int
16021 api_one_stats_dump (vat_main_t * vam)
16022 {
16023   vl_api_one_stats_dump_t *mp;
16024   vl_api_control_ping_t *mp_ping;
16025   int ret;
16026
16027   M (ONE_STATS_DUMP, mp);
16028   /* send it... */
16029   S (mp);
16030
16031   /* Use a control ping for synchronization */
16032   M (CONTROL_PING, mp_ping);
16033   S (mp_ping);
16034
16035   /* Wait for a reply... */
16036   W (ret);
16037   return ret;
16038 }
16039
16040 static int
16041 api_show_one_status (vat_main_t * vam)
16042 {
16043   vl_api_show_one_status_t *mp;
16044   int ret;
16045
16046   if (!vam->json_output)
16047     {
16048       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
16049     }
16050
16051   M (SHOW_ONE_STATUS, mp);
16052   /* send it... */
16053   S (mp);
16054   /* Wait for a reply... */
16055   W (ret);
16056   return ret;
16057 }
16058
16059 #define api_show_lisp_status api_show_one_status
16060
16061 static int
16062 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
16063 {
16064   vl_api_gpe_fwd_entry_path_dump_t *mp;
16065   vl_api_control_ping_t *mp_ping;
16066   unformat_input_t *i = vam->input;
16067   u32 fwd_entry_index = ~0;
16068   int ret;
16069
16070   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16071     {
16072       if (unformat (i, "index %d", &fwd_entry_index))
16073         ;
16074       else
16075         break;
16076     }
16077
16078   if (~0 == fwd_entry_index)
16079     {
16080       errmsg ("no index specified!");
16081       return -99;
16082     }
16083
16084   if (!vam->json_output)
16085     {
16086       print (vam->ofp, "first line");
16087     }
16088
16089   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
16090
16091   /* send it... */
16092   S (mp);
16093   /* Use a control ping for synchronization */
16094   M (CONTROL_PING, mp_ping);
16095   S (mp_ping);
16096
16097   /* Wait for a reply... */
16098   W (ret);
16099   return ret;
16100 }
16101
16102 static int
16103 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
16104 {
16105   vl_api_one_get_map_request_itr_rlocs_t *mp;
16106   int ret;
16107
16108   if (!vam->json_output)
16109     {
16110       print (vam->ofp, "%=20s", "itr-rlocs:");
16111     }
16112
16113   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
16114   /* send it... */
16115   S (mp);
16116   /* Wait for a reply... */
16117   W (ret);
16118   return ret;
16119 }
16120
16121 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
16122
16123 static int
16124 api_af_packet_create (vat_main_t * vam)
16125 {
16126   unformat_input_t *i = vam->input;
16127   vl_api_af_packet_create_t *mp;
16128   u8 *host_if_name = 0;
16129   u8 hw_addr[6];
16130   u8 random_hw_addr = 1;
16131   int ret;
16132
16133   memset (hw_addr, 0, sizeof (hw_addr));
16134
16135   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16136     {
16137       if (unformat (i, "name %s", &host_if_name))
16138         vec_add1 (host_if_name, 0);
16139       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
16140         random_hw_addr = 0;
16141       else
16142         break;
16143     }
16144
16145   if (!vec_len (host_if_name))
16146     {
16147       errmsg ("host-interface name must be specified");
16148       return -99;
16149     }
16150
16151   if (vec_len (host_if_name) > 64)
16152     {
16153       errmsg ("host-interface name too long");
16154       return -99;
16155     }
16156
16157   M (AF_PACKET_CREATE, mp);
16158
16159   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
16160   clib_memcpy (mp->hw_addr, hw_addr, 6);
16161   mp->use_random_hw_addr = random_hw_addr;
16162   vec_free (host_if_name);
16163
16164   S (mp);
16165
16166   /* *INDENT-OFF* */
16167   W2 (ret,
16168       ({
16169         if (ret == 0)
16170           fprintf (vam->ofp ? vam->ofp : stderr,
16171                    " new sw_if_index = %d\n", vam->sw_if_index);
16172       }));
16173   /* *INDENT-ON* */
16174   return ret;
16175 }
16176
16177 static int
16178 api_af_packet_delete (vat_main_t * vam)
16179 {
16180   unformat_input_t *i = vam->input;
16181   vl_api_af_packet_delete_t *mp;
16182   u8 *host_if_name = 0;
16183   int ret;
16184
16185   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16186     {
16187       if (unformat (i, "name %s", &host_if_name))
16188         vec_add1 (host_if_name, 0);
16189       else
16190         break;
16191     }
16192
16193   if (!vec_len (host_if_name))
16194     {
16195       errmsg ("host-interface name must be specified");
16196       return -99;
16197     }
16198
16199   if (vec_len (host_if_name) > 64)
16200     {
16201       errmsg ("host-interface name too long");
16202       return -99;
16203     }
16204
16205   M (AF_PACKET_DELETE, mp);
16206
16207   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
16208   vec_free (host_if_name);
16209
16210   S (mp);
16211   W (ret);
16212   return ret;
16213 }
16214
16215 static int
16216 api_policer_add_del (vat_main_t * vam)
16217 {
16218   unformat_input_t *i = vam->input;
16219   vl_api_policer_add_del_t *mp;
16220   u8 is_add = 1;
16221   u8 *name = 0;
16222   u32 cir = 0;
16223   u32 eir = 0;
16224   u64 cb = 0;
16225   u64 eb = 0;
16226   u8 rate_type = 0;
16227   u8 round_type = 0;
16228   u8 type = 0;
16229   u8 color_aware = 0;
16230   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
16231   int ret;
16232
16233   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
16234   conform_action.dscp = 0;
16235   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
16236   exceed_action.dscp = 0;
16237   violate_action.action_type = SSE2_QOS_ACTION_DROP;
16238   violate_action.dscp = 0;
16239
16240   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16241     {
16242       if (unformat (i, "del"))
16243         is_add = 0;
16244       else if (unformat (i, "name %s", &name))
16245         vec_add1 (name, 0);
16246       else if (unformat (i, "cir %u", &cir))
16247         ;
16248       else if (unformat (i, "eir %u", &eir))
16249         ;
16250       else if (unformat (i, "cb %u", &cb))
16251         ;
16252       else if (unformat (i, "eb %u", &eb))
16253         ;
16254       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
16255                          &rate_type))
16256         ;
16257       else if (unformat (i, "round_type %U", unformat_policer_round_type,
16258                          &round_type))
16259         ;
16260       else if (unformat (i, "type %U", unformat_policer_type, &type))
16261         ;
16262       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
16263                          &conform_action))
16264         ;
16265       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
16266                          &exceed_action))
16267         ;
16268       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
16269                          &violate_action))
16270         ;
16271       else if (unformat (i, "color-aware"))
16272         color_aware = 1;
16273       else
16274         break;
16275     }
16276
16277   if (!vec_len (name))
16278     {
16279       errmsg ("policer name must be specified");
16280       return -99;
16281     }
16282
16283   if (vec_len (name) > 64)
16284     {
16285       errmsg ("policer name too long");
16286       return -99;
16287     }
16288
16289   M (POLICER_ADD_DEL, mp);
16290
16291   clib_memcpy (mp->name, name, vec_len (name));
16292   vec_free (name);
16293   mp->is_add = is_add;
16294   mp->cir = cir;
16295   mp->eir = eir;
16296   mp->cb = cb;
16297   mp->eb = eb;
16298   mp->rate_type = rate_type;
16299   mp->round_type = round_type;
16300   mp->type = type;
16301   mp->conform_action_type = conform_action.action_type;
16302   mp->conform_dscp = conform_action.dscp;
16303   mp->exceed_action_type = exceed_action.action_type;
16304   mp->exceed_dscp = exceed_action.dscp;
16305   mp->violate_action_type = violate_action.action_type;
16306   mp->violate_dscp = violate_action.dscp;
16307   mp->color_aware = color_aware;
16308
16309   S (mp);
16310   W (ret);
16311   return ret;
16312 }
16313
16314 static int
16315 api_policer_dump (vat_main_t * vam)
16316 {
16317   unformat_input_t *i = vam->input;
16318   vl_api_policer_dump_t *mp;
16319   vl_api_control_ping_t *mp_ping;
16320   u8 *match_name = 0;
16321   u8 match_name_valid = 0;
16322   int ret;
16323
16324   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16325     {
16326       if (unformat (i, "name %s", &match_name))
16327         {
16328           vec_add1 (match_name, 0);
16329           match_name_valid = 1;
16330         }
16331       else
16332         break;
16333     }
16334
16335   M (POLICER_DUMP, mp);
16336   mp->match_name_valid = match_name_valid;
16337   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
16338   vec_free (match_name);
16339   /* send it... */
16340   S (mp);
16341
16342   /* Use a control ping for synchronization */
16343   M (CONTROL_PING, mp_ping);
16344   S (mp_ping);
16345
16346   /* Wait for a reply... */
16347   W (ret);
16348   return ret;
16349 }
16350
16351 static int
16352 api_policer_classify_set_interface (vat_main_t * vam)
16353 {
16354   unformat_input_t *i = vam->input;
16355   vl_api_policer_classify_set_interface_t *mp;
16356   u32 sw_if_index;
16357   int sw_if_index_set;
16358   u32 ip4_table_index = ~0;
16359   u32 ip6_table_index = ~0;
16360   u32 l2_table_index = ~0;
16361   u8 is_add = 1;
16362   int ret;
16363
16364   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16365     {
16366       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16367         sw_if_index_set = 1;
16368       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16369         sw_if_index_set = 1;
16370       else if (unformat (i, "del"))
16371         is_add = 0;
16372       else if (unformat (i, "ip4-table %d", &ip4_table_index))
16373         ;
16374       else if (unformat (i, "ip6-table %d", &ip6_table_index))
16375         ;
16376       else if (unformat (i, "l2-table %d", &l2_table_index))
16377         ;
16378       else
16379         {
16380           clib_warning ("parse error '%U'", format_unformat_error, i);
16381           return -99;
16382         }
16383     }
16384
16385   if (sw_if_index_set == 0)
16386     {
16387       errmsg ("missing interface name or sw_if_index");
16388       return -99;
16389     }
16390
16391   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
16392
16393   mp->sw_if_index = ntohl (sw_if_index);
16394   mp->ip4_table_index = ntohl (ip4_table_index);
16395   mp->ip6_table_index = ntohl (ip6_table_index);
16396   mp->l2_table_index = ntohl (l2_table_index);
16397   mp->is_add = is_add;
16398
16399   S (mp);
16400   W (ret);
16401   return ret;
16402 }
16403
16404 static int
16405 api_policer_classify_dump (vat_main_t * vam)
16406 {
16407   unformat_input_t *i = vam->input;
16408   vl_api_policer_classify_dump_t *mp;
16409   vl_api_control_ping_t *mp_ping;
16410   u8 type = POLICER_CLASSIFY_N_TABLES;
16411   int ret;
16412
16413   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
16414     ;
16415   else
16416     {
16417       errmsg ("classify table type must be specified");
16418       return -99;
16419     }
16420
16421   if (!vam->json_output)
16422     {
16423       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
16424     }
16425
16426   M (POLICER_CLASSIFY_DUMP, mp);
16427   mp->type = type;
16428   /* send it... */
16429   S (mp);
16430
16431   /* Use a control ping for synchronization */
16432   M (CONTROL_PING, mp_ping);
16433   S (mp_ping);
16434
16435   /* Wait for a reply... */
16436   W (ret);
16437   return ret;
16438 }
16439
16440 static int
16441 api_netmap_create (vat_main_t * vam)
16442 {
16443   unformat_input_t *i = vam->input;
16444   vl_api_netmap_create_t *mp;
16445   u8 *if_name = 0;
16446   u8 hw_addr[6];
16447   u8 random_hw_addr = 1;
16448   u8 is_pipe = 0;
16449   u8 is_master = 0;
16450   int ret;
16451
16452   memset (hw_addr, 0, sizeof (hw_addr));
16453
16454   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16455     {
16456       if (unformat (i, "name %s", &if_name))
16457         vec_add1 (if_name, 0);
16458       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
16459         random_hw_addr = 0;
16460       else if (unformat (i, "pipe"))
16461         is_pipe = 1;
16462       else if (unformat (i, "master"))
16463         is_master = 1;
16464       else if (unformat (i, "slave"))
16465         is_master = 0;
16466       else
16467         break;
16468     }
16469
16470   if (!vec_len (if_name))
16471     {
16472       errmsg ("interface name must be specified");
16473       return -99;
16474     }
16475
16476   if (vec_len (if_name) > 64)
16477     {
16478       errmsg ("interface name too long");
16479       return -99;
16480     }
16481
16482   M (NETMAP_CREATE, mp);
16483
16484   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
16485   clib_memcpy (mp->hw_addr, hw_addr, 6);
16486   mp->use_random_hw_addr = random_hw_addr;
16487   mp->is_pipe = is_pipe;
16488   mp->is_master = is_master;
16489   vec_free (if_name);
16490
16491   S (mp);
16492   W (ret);
16493   return ret;
16494 }
16495
16496 static int
16497 api_netmap_delete (vat_main_t * vam)
16498 {
16499   unformat_input_t *i = vam->input;
16500   vl_api_netmap_delete_t *mp;
16501   u8 *if_name = 0;
16502   int ret;
16503
16504   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16505     {
16506       if (unformat (i, "name %s", &if_name))
16507         vec_add1 (if_name, 0);
16508       else
16509         break;
16510     }
16511
16512   if (!vec_len (if_name))
16513     {
16514       errmsg ("interface name must be specified");
16515       return -99;
16516     }
16517
16518   if (vec_len (if_name) > 64)
16519     {
16520       errmsg ("interface name too long");
16521       return -99;
16522     }
16523
16524   M (NETMAP_DELETE, mp);
16525
16526   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
16527   vec_free (if_name);
16528
16529   S (mp);
16530   W (ret);
16531   return ret;
16532 }
16533
16534 static void
16535 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
16536 {
16537   if (fp->afi == IP46_TYPE_IP6)
16538     print (vam->ofp,
16539            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16540            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16541            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16542            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16543            format_ip6_address, fp->next_hop);
16544   else if (fp->afi == IP46_TYPE_IP4)
16545     print (vam->ofp,
16546            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16547            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16548            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16549            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16550            format_ip4_address, fp->next_hop);
16551 }
16552
16553 static void
16554 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
16555                                  vl_api_fib_path2_t * fp)
16556 {
16557   struct in_addr ip4;
16558   struct in6_addr ip6;
16559
16560   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16561   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16562   vat_json_object_add_uint (node, "is_local", fp->is_local);
16563   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16564   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16565   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16566   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16567   if (fp->afi == IP46_TYPE_IP4)
16568     {
16569       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16570       vat_json_object_add_ip4 (node, "next_hop", ip4);
16571     }
16572   else if (fp->afi == IP46_TYPE_IP6)
16573     {
16574       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16575       vat_json_object_add_ip6 (node, "next_hop", ip6);
16576     }
16577 }
16578
16579 static void
16580 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
16581 {
16582   vat_main_t *vam = &vat_main;
16583   int count = ntohl (mp->mt_count);
16584   vl_api_fib_path2_t *fp;
16585   i32 i;
16586
16587   print (vam->ofp, "[%d]: sw_if_index %d via:",
16588          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
16589   fp = mp->mt_paths;
16590   for (i = 0; i < count; i++)
16591     {
16592       vl_api_mpls_fib_path_print (vam, fp);
16593       fp++;
16594     }
16595
16596   print (vam->ofp, "");
16597 }
16598
16599 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
16600 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
16601
16602 static void
16603 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
16604 {
16605   vat_main_t *vam = &vat_main;
16606   vat_json_node_t *node = NULL;
16607   int count = ntohl (mp->mt_count);
16608   vl_api_fib_path2_t *fp;
16609   i32 i;
16610
16611   if (VAT_JSON_ARRAY != vam->json_tree.type)
16612     {
16613       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16614       vat_json_init_array (&vam->json_tree);
16615     }
16616   node = vat_json_array_add (&vam->json_tree);
16617
16618   vat_json_init_object (node);
16619   vat_json_object_add_uint (node, "tunnel_index",
16620                             ntohl (mp->mt_tunnel_index));
16621   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
16622
16623   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
16624
16625   fp = mp->mt_paths;
16626   for (i = 0; i < count; i++)
16627     {
16628       vl_api_mpls_fib_path_json_print (node, fp);
16629       fp++;
16630     }
16631 }
16632
16633 static int
16634 api_mpls_tunnel_dump (vat_main_t * vam)
16635 {
16636   vl_api_mpls_tunnel_dump_t *mp;
16637   vl_api_control_ping_t *mp_ping;
16638   i32 index = -1;
16639   int ret;
16640
16641   /* Parse args required to build the message */
16642   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
16643     {
16644       if (!unformat (vam->input, "tunnel_index %d", &index))
16645         {
16646           index = -1;
16647           break;
16648         }
16649     }
16650
16651   print (vam->ofp, "  tunnel_index %d", index);
16652
16653   M (MPLS_TUNNEL_DUMP, mp);
16654   mp->tunnel_index = htonl (index);
16655   S (mp);
16656
16657   /* Use a control ping for synchronization */
16658   M (CONTROL_PING, mp_ping);
16659   S (mp_ping);
16660
16661   W (ret);
16662   return ret;
16663 }
16664
16665 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
16666 #define vl_api_mpls_fib_details_t_print vl_noop_handler
16667
16668
16669 static void
16670 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
16671 {
16672   vat_main_t *vam = &vat_main;
16673   int count = ntohl (mp->count);
16674   vl_api_fib_path2_t *fp;
16675   int i;
16676
16677   print (vam->ofp,
16678          "table-id %d, label %u, ess_bit %u",
16679          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
16680   fp = mp->path;
16681   for (i = 0; i < count; i++)
16682     {
16683       vl_api_mpls_fib_path_print (vam, fp);
16684       fp++;
16685     }
16686 }
16687
16688 static void vl_api_mpls_fib_details_t_handler_json
16689   (vl_api_mpls_fib_details_t * mp)
16690 {
16691   vat_main_t *vam = &vat_main;
16692   int count = ntohl (mp->count);
16693   vat_json_node_t *node = NULL;
16694   vl_api_fib_path2_t *fp;
16695   int i;
16696
16697   if (VAT_JSON_ARRAY != vam->json_tree.type)
16698     {
16699       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16700       vat_json_init_array (&vam->json_tree);
16701     }
16702   node = vat_json_array_add (&vam->json_tree);
16703
16704   vat_json_init_object (node);
16705   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16706   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
16707   vat_json_object_add_uint (node, "label", ntohl (mp->label));
16708   vat_json_object_add_uint (node, "path_count", count);
16709   fp = mp->path;
16710   for (i = 0; i < count; i++)
16711     {
16712       vl_api_mpls_fib_path_json_print (node, fp);
16713       fp++;
16714     }
16715 }
16716
16717 static int
16718 api_mpls_fib_dump (vat_main_t * vam)
16719 {
16720   vl_api_mpls_fib_dump_t *mp;
16721   vl_api_control_ping_t *mp_ping;
16722   int ret;
16723
16724   M (MPLS_FIB_DUMP, mp);
16725   S (mp);
16726
16727   /* Use a control ping for synchronization */
16728   M (CONTROL_PING, mp_ping);
16729   S (mp_ping);
16730
16731   W (ret);
16732   return ret;
16733 }
16734
16735 #define vl_api_ip_fib_details_t_endian vl_noop_handler
16736 #define vl_api_ip_fib_details_t_print vl_noop_handler
16737
16738 static void
16739 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
16740 {
16741   vat_main_t *vam = &vat_main;
16742   int count = ntohl (mp->count);
16743   vl_api_fib_path_t *fp;
16744   int i;
16745
16746   print (vam->ofp,
16747          "table-id %d, prefix %U/%d",
16748          ntohl (mp->table_id), format_ip4_address, mp->address,
16749          mp->address_length);
16750   fp = mp->path;
16751   for (i = 0; i < count; i++)
16752     {
16753       if (fp->afi == IP46_TYPE_IP6)
16754         print (vam->ofp,
16755                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16756                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16757                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16758                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16759                format_ip6_address, fp->next_hop);
16760       else if (fp->afi == IP46_TYPE_IP4)
16761         print (vam->ofp,
16762                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16763                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16764                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16765                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16766                format_ip4_address, fp->next_hop);
16767       fp++;
16768     }
16769 }
16770
16771 static void vl_api_ip_fib_details_t_handler_json
16772   (vl_api_ip_fib_details_t * mp)
16773 {
16774   vat_main_t *vam = &vat_main;
16775   int count = ntohl (mp->count);
16776   vat_json_node_t *node = NULL;
16777   struct in_addr ip4;
16778   struct in6_addr ip6;
16779   vl_api_fib_path_t *fp;
16780   int i;
16781
16782   if (VAT_JSON_ARRAY != vam->json_tree.type)
16783     {
16784       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16785       vat_json_init_array (&vam->json_tree);
16786     }
16787   node = vat_json_array_add (&vam->json_tree);
16788
16789   vat_json_init_object (node);
16790   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16791   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
16792   vat_json_object_add_ip4 (node, "prefix", ip4);
16793   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16794   vat_json_object_add_uint (node, "path_count", count);
16795   fp = mp->path;
16796   for (i = 0; i < count; i++)
16797     {
16798       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16799       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16800       vat_json_object_add_uint (node, "is_local", fp->is_local);
16801       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16802       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16803       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16804       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16805       if (fp->afi == IP46_TYPE_IP4)
16806         {
16807           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16808           vat_json_object_add_ip4 (node, "next_hop", ip4);
16809         }
16810       else if (fp->afi == IP46_TYPE_IP6)
16811         {
16812           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16813           vat_json_object_add_ip6 (node, "next_hop", ip6);
16814         }
16815     }
16816 }
16817
16818 static int
16819 api_ip_fib_dump (vat_main_t * vam)
16820 {
16821   vl_api_ip_fib_dump_t *mp;
16822   vl_api_control_ping_t *mp_ping;
16823   int ret;
16824
16825   M (IP_FIB_DUMP, mp);
16826   S (mp);
16827
16828   /* Use a control ping for synchronization */
16829   M (CONTROL_PING, mp_ping);
16830   S (mp_ping);
16831
16832   W (ret);
16833   return ret;
16834 }
16835
16836 static int
16837 api_ip_mfib_dump (vat_main_t * vam)
16838 {
16839   vl_api_ip_mfib_dump_t *mp;
16840   vl_api_control_ping_t *mp_ping;
16841   int ret;
16842
16843   M (IP_MFIB_DUMP, mp);
16844   S (mp);
16845
16846   /* Use a control ping for synchronization */
16847   M (CONTROL_PING, mp_ping);
16848   S (mp_ping);
16849
16850   W (ret);
16851   return ret;
16852 }
16853
16854 static void vl_api_ip_neighbor_details_t_handler
16855   (vl_api_ip_neighbor_details_t * mp)
16856 {
16857   vat_main_t *vam = &vat_main;
16858
16859   print (vam->ofp, "%c %U %U",
16860          (mp->is_static) ? 'S' : 'D',
16861          format_ethernet_address, &mp->mac_address,
16862          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
16863          &mp->ip_address);
16864 }
16865
16866 static void vl_api_ip_neighbor_details_t_handler_json
16867   (vl_api_ip_neighbor_details_t * mp)
16868 {
16869
16870   vat_main_t *vam = &vat_main;
16871   vat_json_node_t *node;
16872   struct in_addr ip4;
16873   struct in6_addr ip6;
16874
16875   if (VAT_JSON_ARRAY != vam->json_tree.type)
16876     {
16877       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16878       vat_json_init_array (&vam->json_tree);
16879     }
16880   node = vat_json_array_add (&vam->json_tree);
16881
16882   vat_json_init_object (node);
16883   vat_json_object_add_string_copy (node, "flag",
16884                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
16885                                    "dynamic");
16886
16887   vat_json_object_add_string_copy (node, "link_layer",
16888                                    format (0, "%U", format_ethernet_address,
16889                                            &mp->mac_address));
16890
16891   if (mp->is_ipv6)
16892     {
16893       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
16894       vat_json_object_add_ip6 (node, "ip_address", ip6);
16895     }
16896   else
16897     {
16898       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
16899       vat_json_object_add_ip4 (node, "ip_address", ip4);
16900     }
16901 }
16902
16903 static int
16904 api_ip_neighbor_dump (vat_main_t * vam)
16905 {
16906   unformat_input_t *i = vam->input;
16907   vl_api_ip_neighbor_dump_t *mp;
16908   vl_api_control_ping_t *mp_ping;
16909   u8 is_ipv6 = 0;
16910   u32 sw_if_index = ~0;
16911   int ret;
16912
16913   /* Parse args required to build the message */
16914   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16915     {
16916       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16917         ;
16918       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16919         ;
16920       else if (unformat (i, "ip6"))
16921         is_ipv6 = 1;
16922       else
16923         break;
16924     }
16925
16926   if (sw_if_index == ~0)
16927     {
16928       errmsg ("missing interface name or sw_if_index");
16929       return -99;
16930     }
16931
16932   M (IP_NEIGHBOR_DUMP, mp);
16933   mp->is_ipv6 = (u8) is_ipv6;
16934   mp->sw_if_index = ntohl (sw_if_index);
16935   S (mp);
16936
16937   /* Use a control ping for synchronization */
16938   M (CONTROL_PING, mp_ping);
16939   S (mp_ping);
16940
16941   W (ret);
16942   return ret;
16943 }
16944
16945 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
16946 #define vl_api_ip6_fib_details_t_print vl_noop_handler
16947
16948 static void
16949 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
16950 {
16951   vat_main_t *vam = &vat_main;
16952   int count = ntohl (mp->count);
16953   vl_api_fib_path_t *fp;
16954   int i;
16955
16956   print (vam->ofp,
16957          "table-id %d, prefix %U/%d",
16958          ntohl (mp->table_id), format_ip6_address, mp->address,
16959          mp->address_length);
16960   fp = mp->path;
16961   for (i = 0; i < count; i++)
16962     {
16963       if (fp->afi == IP46_TYPE_IP6)
16964         print (vam->ofp,
16965                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16966                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16967                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16968                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16969                format_ip6_address, fp->next_hop);
16970       else if (fp->afi == IP46_TYPE_IP4)
16971         print (vam->ofp,
16972                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16973                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16974                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16975                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16976                format_ip4_address, fp->next_hop);
16977       fp++;
16978     }
16979 }
16980
16981 static void vl_api_ip6_fib_details_t_handler_json
16982   (vl_api_ip6_fib_details_t * mp)
16983 {
16984   vat_main_t *vam = &vat_main;
16985   int count = ntohl (mp->count);
16986   vat_json_node_t *node = NULL;
16987   struct in_addr ip4;
16988   struct in6_addr ip6;
16989   vl_api_fib_path_t *fp;
16990   int i;
16991
16992   if (VAT_JSON_ARRAY != vam->json_tree.type)
16993     {
16994       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16995       vat_json_init_array (&vam->json_tree);
16996     }
16997   node = vat_json_array_add (&vam->json_tree);
16998
16999   vat_json_init_object (node);
17000   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
17001   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
17002   vat_json_object_add_ip6 (node, "prefix", ip6);
17003   vat_json_object_add_uint (node, "mask_length", mp->address_length);
17004   vat_json_object_add_uint (node, "path_count", count);
17005   fp = mp->path;
17006   for (i = 0; i < count; i++)
17007     {
17008       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17009       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17010       vat_json_object_add_uint (node, "is_local", fp->is_local);
17011       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
17012       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
17013       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
17014       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
17015       if (fp->afi == IP46_TYPE_IP4)
17016         {
17017           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
17018           vat_json_object_add_ip4 (node, "next_hop", ip4);
17019         }
17020       else if (fp->afi == IP46_TYPE_IP6)
17021         {
17022           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
17023           vat_json_object_add_ip6 (node, "next_hop", ip6);
17024         }
17025     }
17026 }
17027
17028 static int
17029 api_ip6_fib_dump (vat_main_t * vam)
17030 {
17031   vl_api_ip6_fib_dump_t *mp;
17032   vl_api_control_ping_t *mp_ping;
17033   int ret;
17034
17035   M (IP6_FIB_DUMP, mp);
17036   S (mp);
17037
17038   /* Use a control ping for synchronization */
17039   M (CONTROL_PING, mp_ping);
17040   S (mp_ping);
17041
17042   W (ret);
17043   return ret;
17044 }
17045
17046 static int
17047 api_ip6_mfib_dump (vat_main_t * vam)
17048 {
17049   vl_api_ip6_mfib_dump_t *mp;
17050   vl_api_control_ping_t *mp_ping;
17051   int ret;
17052
17053   M (IP6_MFIB_DUMP, mp);
17054   S (mp);
17055
17056   /* Use a control ping for synchronization */
17057   M (CONTROL_PING, mp_ping);
17058   S (mp_ping);
17059
17060   W (ret);
17061   return ret;
17062 }
17063
17064 int
17065 api_classify_table_ids (vat_main_t * vam)
17066 {
17067   vl_api_classify_table_ids_t *mp;
17068   int ret;
17069
17070   /* Construct the API message */
17071   M (CLASSIFY_TABLE_IDS, mp);
17072   mp->context = 0;
17073
17074   S (mp);
17075   W (ret);
17076   return ret;
17077 }
17078
17079 int
17080 api_classify_table_by_interface (vat_main_t * vam)
17081 {
17082   unformat_input_t *input = vam->input;
17083   vl_api_classify_table_by_interface_t *mp;
17084
17085   u32 sw_if_index = ~0;
17086   int ret;
17087   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17088     {
17089       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17090         ;
17091       else if (unformat (input, "sw_if_index %d", &sw_if_index))
17092         ;
17093       else
17094         break;
17095     }
17096   if (sw_if_index == ~0)
17097     {
17098       errmsg ("missing interface name or sw_if_index");
17099       return -99;
17100     }
17101
17102   /* Construct the API message */
17103   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
17104   mp->context = 0;
17105   mp->sw_if_index = ntohl (sw_if_index);
17106
17107   S (mp);
17108   W (ret);
17109   return ret;
17110 }
17111
17112 int
17113 api_classify_table_info (vat_main_t * vam)
17114 {
17115   unformat_input_t *input = vam->input;
17116   vl_api_classify_table_info_t *mp;
17117
17118   u32 table_id = ~0;
17119   int ret;
17120   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17121     {
17122       if (unformat (input, "table_id %d", &table_id))
17123         ;
17124       else
17125         break;
17126     }
17127   if (table_id == ~0)
17128     {
17129       errmsg ("missing table id");
17130       return -99;
17131     }
17132
17133   /* Construct the API message */
17134   M (CLASSIFY_TABLE_INFO, mp);
17135   mp->context = 0;
17136   mp->table_id = ntohl (table_id);
17137
17138   S (mp);
17139   W (ret);
17140   return ret;
17141 }
17142
17143 int
17144 api_classify_session_dump (vat_main_t * vam)
17145 {
17146   unformat_input_t *input = vam->input;
17147   vl_api_classify_session_dump_t *mp;
17148   vl_api_control_ping_t *mp_ping;
17149
17150   u32 table_id = ~0;
17151   int ret;
17152   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17153     {
17154       if (unformat (input, "table_id %d", &table_id))
17155         ;
17156       else
17157         break;
17158     }
17159   if (table_id == ~0)
17160     {
17161       errmsg ("missing table id");
17162       return -99;
17163     }
17164
17165   /* Construct the API message */
17166   M (CLASSIFY_SESSION_DUMP, mp);
17167   mp->context = 0;
17168   mp->table_id = ntohl (table_id);
17169   S (mp);
17170
17171   /* Use a control ping for synchronization */
17172   M (CONTROL_PING, mp_ping);
17173   S (mp_ping);
17174
17175   W (ret);
17176   return ret;
17177 }
17178
17179 static void
17180 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
17181 {
17182   vat_main_t *vam = &vat_main;
17183
17184   print (vam->ofp, "collector_address %U, collector_port %d, "
17185          "src_address %U, vrf_id %d, path_mtu %u, "
17186          "template_interval %u, udp_checksum %d",
17187          format_ip4_address, mp->collector_address,
17188          ntohs (mp->collector_port),
17189          format_ip4_address, mp->src_address,
17190          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
17191          ntohl (mp->template_interval), mp->udp_checksum);
17192
17193   vam->retval = 0;
17194   vam->result_ready = 1;
17195 }
17196
17197 static void
17198   vl_api_ipfix_exporter_details_t_handler_json
17199   (vl_api_ipfix_exporter_details_t * mp)
17200 {
17201   vat_main_t *vam = &vat_main;
17202   vat_json_node_t node;
17203   struct in_addr collector_address;
17204   struct in_addr src_address;
17205
17206   vat_json_init_object (&node);
17207   clib_memcpy (&collector_address, &mp->collector_address,
17208                sizeof (collector_address));
17209   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
17210   vat_json_object_add_uint (&node, "collector_port",
17211                             ntohs (mp->collector_port));
17212   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
17213   vat_json_object_add_ip4 (&node, "src_address", src_address);
17214   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
17215   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
17216   vat_json_object_add_uint (&node, "template_interval",
17217                             ntohl (mp->template_interval));
17218   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
17219
17220   vat_json_print (vam->ofp, &node);
17221   vat_json_free (&node);
17222   vam->retval = 0;
17223   vam->result_ready = 1;
17224 }
17225
17226 int
17227 api_ipfix_exporter_dump (vat_main_t * vam)
17228 {
17229   vl_api_ipfix_exporter_dump_t *mp;
17230   int ret;
17231
17232   /* Construct the API message */
17233   M (IPFIX_EXPORTER_DUMP, mp);
17234   mp->context = 0;
17235
17236   S (mp);
17237   W (ret);
17238   return ret;
17239 }
17240
17241 static int
17242 api_ipfix_classify_stream_dump (vat_main_t * vam)
17243 {
17244   vl_api_ipfix_classify_stream_dump_t *mp;
17245   int ret;
17246
17247   /* Construct the API message */
17248   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
17249   mp->context = 0;
17250
17251   S (mp);
17252   W (ret);
17253   return ret;
17254   /* NOTREACHED */
17255   return 0;
17256 }
17257
17258 static void
17259   vl_api_ipfix_classify_stream_details_t_handler
17260   (vl_api_ipfix_classify_stream_details_t * mp)
17261 {
17262   vat_main_t *vam = &vat_main;
17263   print (vam->ofp, "domain_id %d, src_port %d",
17264          ntohl (mp->domain_id), ntohs (mp->src_port));
17265   vam->retval = 0;
17266   vam->result_ready = 1;
17267 }
17268
17269 static void
17270   vl_api_ipfix_classify_stream_details_t_handler_json
17271   (vl_api_ipfix_classify_stream_details_t * mp)
17272 {
17273   vat_main_t *vam = &vat_main;
17274   vat_json_node_t node;
17275
17276   vat_json_init_object (&node);
17277   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
17278   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
17279
17280   vat_json_print (vam->ofp, &node);
17281   vat_json_free (&node);
17282   vam->retval = 0;
17283   vam->result_ready = 1;
17284 }
17285
17286 static int
17287 api_ipfix_classify_table_dump (vat_main_t * vam)
17288 {
17289   vl_api_ipfix_classify_table_dump_t *mp;
17290   vl_api_control_ping_t *mp_ping;
17291   int ret;
17292
17293   if (!vam->json_output)
17294     {
17295       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
17296              "transport_protocol");
17297     }
17298
17299   /* Construct the API message */
17300   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
17301
17302   /* send it... */
17303   S (mp);
17304
17305   /* Use a control ping for synchronization */
17306   M (CONTROL_PING, mp_ping);
17307   S (mp_ping);
17308
17309   W (ret);
17310   return ret;
17311 }
17312
17313 static void
17314   vl_api_ipfix_classify_table_details_t_handler
17315   (vl_api_ipfix_classify_table_details_t * mp)
17316 {
17317   vat_main_t *vam = &vat_main;
17318   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
17319          mp->transport_protocol);
17320 }
17321
17322 static void
17323   vl_api_ipfix_classify_table_details_t_handler_json
17324   (vl_api_ipfix_classify_table_details_t * mp)
17325 {
17326   vat_json_node_t *node = NULL;
17327   vat_main_t *vam = &vat_main;
17328
17329   if (VAT_JSON_ARRAY != vam->json_tree.type)
17330     {
17331       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17332       vat_json_init_array (&vam->json_tree);
17333     }
17334
17335   node = vat_json_array_add (&vam->json_tree);
17336   vat_json_init_object (node);
17337
17338   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
17339   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
17340   vat_json_object_add_uint (node, "transport_protocol",
17341                             mp->transport_protocol);
17342 }
17343
17344 static int
17345 api_sw_interface_span_enable_disable (vat_main_t * vam)
17346 {
17347   unformat_input_t *i = vam->input;
17348   vl_api_sw_interface_span_enable_disable_t *mp;
17349   u32 src_sw_if_index = ~0;
17350   u32 dst_sw_if_index = ~0;
17351   u8 state = 3;
17352   int ret;
17353
17354   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17355     {
17356       if (unformat
17357           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
17358         ;
17359       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
17360         ;
17361       else
17362         if (unformat
17363             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
17364         ;
17365       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
17366         ;
17367       else if (unformat (i, "disable"))
17368         state = 0;
17369       else if (unformat (i, "rx"))
17370         state = 1;
17371       else if (unformat (i, "tx"))
17372         state = 2;
17373       else if (unformat (i, "both"))
17374         state = 3;
17375       else
17376         break;
17377     }
17378
17379   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
17380
17381   mp->sw_if_index_from = htonl (src_sw_if_index);
17382   mp->sw_if_index_to = htonl (dst_sw_if_index);
17383   mp->state = state;
17384
17385   S (mp);
17386   W (ret);
17387   return ret;
17388 }
17389
17390 static void
17391 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
17392                                             * mp)
17393 {
17394   vat_main_t *vam = &vat_main;
17395   u8 *sw_if_from_name = 0;
17396   u8 *sw_if_to_name = 0;
17397   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
17398   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
17399   char *states[] = { "none", "rx", "tx", "both" };
17400   hash_pair_t *p;
17401
17402   /* *INDENT-OFF* */
17403   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
17404   ({
17405     if ((u32) p->value[0] == sw_if_index_from)
17406       {
17407         sw_if_from_name = (u8 *)(p->key);
17408         if (sw_if_to_name)
17409           break;
17410       }
17411     if ((u32) p->value[0] == sw_if_index_to)
17412       {
17413         sw_if_to_name = (u8 *)(p->key);
17414         if (sw_if_from_name)
17415           break;
17416       }
17417   }));
17418   /* *INDENT-ON* */
17419   print (vam->ofp, "%20s => %20s (%s)",
17420          sw_if_from_name, sw_if_to_name, states[mp->state]);
17421 }
17422
17423 static void
17424   vl_api_sw_interface_span_details_t_handler_json
17425   (vl_api_sw_interface_span_details_t * mp)
17426 {
17427   vat_main_t *vam = &vat_main;
17428   vat_json_node_t *node = NULL;
17429   u8 *sw_if_from_name = 0;
17430   u8 *sw_if_to_name = 0;
17431   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
17432   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
17433   hash_pair_t *p;
17434
17435   /* *INDENT-OFF* */
17436   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
17437   ({
17438     if ((u32) p->value[0] == sw_if_index_from)
17439       {
17440         sw_if_from_name = (u8 *)(p->key);
17441         if (sw_if_to_name)
17442           break;
17443       }
17444     if ((u32) p->value[0] == sw_if_index_to)
17445       {
17446         sw_if_to_name = (u8 *)(p->key);
17447         if (sw_if_from_name)
17448           break;
17449       }
17450   }));
17451   /* *INDENT-ON* */
17452
17453   if (VAT_JSON_ARRAY != vam->json_tree.type)
17454     {
17455       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17456       vat_json_init_array (&vam->json_tree);
17457     }
17458   node = vat_json_array_add (&vam->json_tree);
17459
17460   vat_json_init_object (node);
17461   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
17462   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
17463   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
17464   if (0 != sw_if_to_name)
17465     {
17466       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
17467     }
17468   vat_json_object_add_uint (node, "state", mp->state);
17469 }
17470
17471 static int
17472 api_sw_interface_span_dump (vat_main_t * vam)
17473 {
17474   vl_api_sw_interface_span_dump_t *mp;
17475   vl_api_control_ping_t *mp_ping;
17476   int ret;
17477
17478   M (SW_INTERFACE_SPAN_DUMP, mp);
17479   S (mp);
17480
17481   /* Use a control ping for synchronization */
17482   M (CONTROL_PING, mp_ping);
17483   S (mp_ping);
17484
17485   W (ret);
17486   return ret;
17487 }
17488
17489 int
17490 api_pg_create_interface (vat_main_t * vam)
17491 {
17492   unformat_input_t *input = vam->input;
17493   vl_api_pg_create_interface_t *mp;
17494
17495   u32 if_id = ~0;
17496   int ret;
17497   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17498     {
17499       if (unformat (input, "if_id %d", &if_id))
17500         ;
17501       else
17502         break;
17503     }
17504   if (if_id == ~0)
17505     {
17506       errmsg ("missing pg interface index");
17507       return -99;
17508     }
17509
17510   /* Construct the API message */
17511   M (PG_CREATE_INTERFACE, mp);
17512   mp->context = 0;
17513   mp->interface_id = ntohl (if_id);
17514
17515   S (mp);
17516   W (ret);
17517   return ret;
17518 }
17519
17520 int
17521 api_pg_capture (vat_main_t * vam)
17522 {
17523   unformat_input_t *input = vam->input;
17524   vl_api_pg_capture_t *mp;
17525
17526   u32 if_id = ~0;
17527   u8 enable = 1;
17528   u32 count = 1;
17529   u8 pcap_file_set = 0;
17530   u8 *pcap_file = 0;
17531   int ret;
17532   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17533     {
17534       if (unformat (input, "if_id %d", &if_id))
17535         ;
17536       else if (unformat (input, "pcap %s", &pcap_file))
17537         pcap_file_set = 1;
17538       else if (unformat (input, "count %d", &count))
17539         ;
17540       else if (unformat (input, "disable"))
17541         enable = 0;
17542       else
17543         break;
17544     }
17545   if (if_id == ~0)
17546     {
17547       errmsg ("missing pg interface index");
17548       return -99;
17549     }
17550   if (pcap_file_set > 0)
17551     {
17552       if (vec_len (pcap_file) > 255)
17553         {
17554           errmsg ("pcap file name is too long");
17555           return -99;
17556         }
17557     }
17558
17559   u32 name_len = vec_len (pcap_file);
17560   /* Construct the API message */
17561   M (PG_CAPTURE, mp);
17562   mp->context = 0;
17563   mp->interface_id = ntohl (if_id);
17564   mp->is_enabled = enable;
17565   mp->count = ntohl (count);
17566   mp->pcap_name_length = ntohl (name_len);
17567   if (pcap_file_set != 0)
17568     {
17569       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
17570     }
17571   vec_free (pcap_file);
17572
17573   S (mp);
17574   W (ret);
17575   return ret;
17576 }
17577
17578 int
17579 api_pg_enable_disable (vat_main_t * vam)
17580 {
17581   unformat_input_t *input = vam->input;
17582   vl_api_pg_enable_disable_t *mp;
17583
17584   u8 enable = 1;
17585   u8 stream_name_set = 0;
17586   u8 *stream_name = 0;
17587   int ret;
17588   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17589     {
17590       if (unformat (input, "stream %s", &stream_name))
17591         stream_name_set = 1;
17592       else if (unformat (input, "disable"))
17593         enable = 0;
17594       else
17595         break;
17596     }
17597
17598   if (stream_name_set > 0)
17599     {
17600       if (vec_len (stream_name) > 255)
17601         {
17602           errmsg ("stream name too long");
17603           return -99;
17604         }
17605     }
17606
17607   u32 name_len = vec_len (stream_name);
17608   /* Construct the API message */
17609   M (PG_ENABLE_DISABLE, mp);
17610   mp->context = 0;
17611   mp->is_enabled = enable;
17612   if (stream_name_set != 0)
17613     {
17614       mp->stream_name_length = ntohl (name_len);
17615       clib_memcpy (mp->stream_name, stream_name, name_len);
17616     }
17617   vec_free (stream_name);
17618
17619   S (mp);
17620   W (ret);
17621   return ret;
17622 }
17623
17624 int
17625 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
17626 {
17627   unformat_input_t *input = vam->input;
17628   vl_api_ip_source_and_port_range_check_add_del_t *mp;
17629
17630   u16 *low_ports = 0;
17631   u16 *high_ports = 0;
17632   u16 this_low;
17633   u16 this_hi;
17634   ip4_address_t ip4_addr;
17635   ip6_address_t ip6_addr;
17636   u32 length;
17637   u32 tmp, tmp2;
17638   u8 prefix_set = 0;
17639   u32 vrf_id = ~0;
17640   u8 is_add = 1;
17641   u8 is_ipv6 = 0;
17642   int ret;
17643
17644   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17645     {
17646       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
17647         {
17648           prefix_set = 1;
17649         }
17650       else
17651         if (unformat
17652             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
17653         {
17654           prefix_set = 1;
17655           is_ipv6 = 1;
17656         }
17657       else if (unformat (input, "vrf %d", &vrf_id))
17658         ;
17659       else if (unformat (input, "del"))
17660         is_add = 0;
17661       else if (unformat (input, "port %d", &tmp))
17662         {
17663           if (tmp == 0 || tmp > 65535)
17664             {
17665               errmsg ("port %d out of range", tmp);
17666               return -99;
17667             }
17668           this_low = tmp;
17669           this_hi = this_low + 1;
17670           vec_add1 (low_ports, this_low);
17671           vec_add1 (high_ports, this_hi);
17672         }
17673       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
17674         {
17675           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
17676             {
17677               errmsg ("incorrect range parameters");
17678               return -99;
17679             }
17680           this_low = tmp;
17681           /* Note: in debug CLI +1 is added to high before
17682              passing to real fn that does "the work"
17683              (ip_source_and_port_range_check_add_del).
17684              This fn is a wrapper around the binary API fn a
17685              control plane will call, which expects this increment
17686              to have occurred. Hence letting the binary API control
17687              plane fn do the increment for consistency between VAT
17688              and other control planes.
17689            */
17690           this_hi = tmp2;
17691           vec_add1 (low_ports, this_low);
17692           vec_add1 (high_ports, this_hi);
17693         }
17694       else
17695         break;
17696     }
17697
17698   if (prefix_set == 0)
17699     {
17700       errmsg ("<address>/<mask> not specified");
17701       return -99;
17702     }
17703
17704   if (vrf_id == ~0)
17705     {
17706       errmsg ("VRF ID required, not specified");
17707       return -99;
17708     }
17709
17710   if (vrf_id == 0)
17711     {
17712       errmsg
17713         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17714       return -99;
17715     }
17716
17717   if (vec_len (low_ports) == 0)
17718     {
17719       errmsg ("At least one port or port range required");
17720       return -99;
17721     }
17722
17723   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
17724
17725   mp->is_add = is_add;
17726
17727   if (is_ipv6)
17728     {
17729       mp->is_ipv6 = 1;
17730       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
17731     }
17732   else
17733     {
17734       mp->is_ipv6 = 0;
17735       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
17736     }
17737
17738   mp->mask_length = length;
17739   mp->number_of_ranges = vec_len (low_ports);
17740
17741   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
17742   vec_free (low_ports);
17743
17744   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
17745   vec_free (high_ports);
17746
17747   mp->vrf_id = ntohl (vrf_id);
17748
17749   S (mp);
17750   W (ret);
17751   return ret;
17752 }
17753
17754 int
17755 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
17756 {
17757   unformat_input_t *input = vam->input;
17758   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
17759   u32 sw_if_index = ~0;
17760   int vrf_set = 0;
17761   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
17762   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
17763   u8 is_add = 1;
17764   int ret;
17765
17766   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17767     {
17768       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17769         ;
17770       else if (unformat (input, "sw_if_index %d", &sw_if_index))
17771         ;
17772       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
17773         vrf_set = 1;
17774       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
17775         vrf_set = 1;
17776       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
17777         vrf_set = 1;
17778       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
17779         vrf_set = 1;
17780       else if (unformat (input, "del"))
17781         is_add = 0;
17782       else
17783         break;
17784     }
17785
17786   if (sw_if_index == ~0)
17787     {
17788       errmsg ("Interface required but not specified");
17789       return -99;
17790     }
17791
17792   if (vrf_set == 0)
17793     {
17794       errmsg ("VRF ID required but not specified");
17795       return -99;
17796     }
17797
17798   if (tcp_out_vrf_id == 0
17799       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
17800     {
17801       errmsg
17802         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17803       return -99;
17804     }
17805
17806   /* Construct the API message */
17807   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
17808
17809   mp->sw_if_index = ntohl (sw_if_index);
17810   mp->is_add = is_add;
17811   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
17812   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
17813   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
17814   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
17815
17816   /* send it... */
17817   S (mp);
17818
17819   /* Wait for a reply... */
17820   W (ret);
17821   return ret;
17822 }
17823
17824 static int
17825 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
17826 {
17827   unformat_input_t *i = vam->input;
17828   vl_api_ipsec_gre_add_del_tunnel_t *mp;
17829   u32 local_sa_id = 0;
17830   u32 remote_sa_id = 0;
17831   ip4_address_t src_address;
17832   ip4_address_t dst_address;
17833   u8 is_add = 1;
17834   int ret;
17835
17836   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17837     {
17838       if (unformat (i, "local_sa %d", &local_sa_id))
17839         ;
17840       else if (unformat (i, "remote_sa %d", &remote_sa_id))
17841         ;
17842       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
17843         ;
17844       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
17845         ;
17846       else if (unformat (i, "del"))
17847         is_add = 0;
17848       else
17849         {
17850           clib_warning ("parse error '%U'", format_unformat_error, i);
17851           return -99;
17852         }
17853     }
17854
17855   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
17856
17857   mp->local_sa_id = ntohl (local_sa_id);
17858   mp->remote_sa_id = ntohl (remote_sa_id);
17859   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
17860   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
17861   mp->is_add = is_add;
17862
17863   S (mp);
17864   W (ret);
17865   return ret;
17866 }
17867
17868 static int
17869 api_punt (vat_main_t * vam)
17870 {
17871   unformat_input_t *i = vam->input;
17872   vl_api_punt_t *mp;
17873   u32 ipv = ~0;
17874   u32 protocol = ~0;
17875   u32 port = ~0;
17876   int is_add = 1;
17877   int ret;
17878
17879   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17880     {
17881       if (unformat (i, "ip %d", &ipv))
17882         ;
17883       else if (unformat (i, "protocol %d", &protocol))
17884         ;
17885       else if (unformat (i, "port %d", &port))
17886         ;
17887       else if (unformat (i, "del"))
17888         is_add = 0;
17889       else
17890         {
17891           clib_warning ("parse error '%U'", format_unformat_error, i);
17892           return -99;
17893         }
17894     }
17895
17896   M (PUNT, mp);
17897
17898   mp->is_add = (u8) is_add;
17899   mp->ipv = (u8) ipv;
17900   mp->l4_protocol = (u8) protocol;
17901   mp->l4_port = htons ((u16) port);
17902
17903   S (mp);
17904   W (ret);
17905   return ret;
17906 }
17907
17908 static void vl_api_ipsec_gre_tunnel_details_t_handler
17909   (vl_api_ipsec_gre_tunnel_details_t * mp)
17910 {
17911   vat_main_t *vam = &vat_main;
17912
17913   print (vam->ofp, "%11d%15U%15U%14d%14d",
17914          ntohl (mp->sw_if_index),
17915          format_ip4_address, &mp->src_address,
17916          format_ip4_address, &mp->dst_address,
17917          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
17918 }
17919
17920 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
17921   (vl_api_ipsec_gre_tunnel_details_t * mp)
17922 {
17923   vat_main_t *vam = &vat_main;
17924   vat_json_node_t *node = NULL;
17925   struct in_addr ip4;
17926
17927   if (VAT_JSON_ARRAY != vam->json_tree.type)
17928     {
17929       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17930       vat_json_init_array (&vam->json_tree);
17931     }
17932   node = vat_json_array_add (&vam->json_tree);
17933
17934   vat_json_init_object (node);
17935   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17936   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
17937   vat_json_object_add_ip4 (node, "src_address", ip4);
17938   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
17939   vat_json_object_add_ip4 (node, "dst_address", ip4);
17940   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
17941   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
17942 }
17943
17944 static int
17945 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
17946 {
17947   unformat_input_t *i = vam->input;
17948   vl_api_ipsec_gre_tunnel_dump_t *mp;
17949   vl_api_control_ping_t *mp_ping;
17950   u32 sw_if_index;
17951   u8 sw_if_index_set = 0;
17952   int ret;
17953
17954   /* Parse args required to build the message */
17955   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17956     {
17957       if (unformat (i, "sw_if_index %d", &sw_if_index))
17958         sw_if_index_set = 1;
17959       else
17960         break;
17961     }
17962
17963   if (sw_if_index_set == 0)
17964     {
17965       sw_if_index = ~0;
17966     }
17967
17968   if (!vam->json_output)
17969     {
17970       print (vam->ofp, "%11s%15s%15s%14s%14s",
17971              "sw_if_index", "src_address", "dst_address",
17972              "local_sa_id", "remote_sa_id");
17973     }
17974
17975   /* Get list of gre-tunnel interfaces */
17976   M (IPSEC_GRE_TUNNEL_DUMP, mp);
17977
17978   mp->sw_if_index = htonl (sw_if_index);
17979
17980   S (mp);
17981
17982   /* Use a control ping for synchronization */
17983   M (CONTROL_PING, mp_ping);
17984   S (mp_ping);
17985
17986   W (ret);
17987   return ret;
17988 }
17989
17990 static int
17991 api_delete_subif (vat_main_t * vam)
17992 {
17993   unformat_input_t *i = vam->input;
17994   vl_api_delete_subif_t *mp;
17995   u32 sw_if_index = ~0;
17996   int ret;
17997
17998   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17999     {
18000       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18001         ;
18002       if (unformat (i, "sw_if_index %d", &sw_if_index))
18003         ;
18004       else
18005         break;
18006     }
18007
18008   if (sw_if_index == ~0)
18009     {
18010       errmsg ("missing sw_if_index");
18011       return -99;
18012     }
18013
18014   /* Construct the API message */
18015   M (DELETE_SUBIF, mp);
18016   mp->sw_if_index = ntohl (sw_if_index);
18017
18018   S (mp);
18019   W (ret);
18020   return ret;
18021 }
18022
18023 #define foreach_pbb_vtr_op      \
18024 _("disable",  L2_VTR_DISABLED)  \
18025 _("pop",  L2_VTR_POP_2)         \
18026 _("push",  L2_VTR_PUSH_2)
18027
18028 static int
18029 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
18030 {
18031   unformat_input_t *i = vam->input;
18032   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
18033   u32 sw_if_index = ~0, vtr_op = ~0;
18034   u16 outer_tag = ~0;
18035   u8 dmac[6], smac[6];
18036   u8 dmac_set = 0, smac_set = 0;
18037   u16 vlanid = 0;
18038   u32 sid = ~0;
18039   u32 tmp;
18040   int ret;
18041
18042   /* Shut up coverity */
18043   memset (dmac, 0, sizeof (dmac));
18044   memset (smac, 0, sizeof (smac));
18045
18046   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18047     {
18048       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18049         ;
18050       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18051         ;
18052       else if (unformat (i, "vtr_op %d", &vtr_op))
18053         ;
18054 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
18055       foreach_pbb_vtr_op
18056 #undef _
18057         else if (unformat (i, "translate_pbb_stag"))
18058         {
18059           if (unformat (i, "%d", &tmp))
18060             {
18061               vtr_op = L2_VTR_TRANSLATE_2_1;
18062               outer_tag = tmp;
18063             }
18064           else
18065             {
18066               errmsg
18067                 ("translate_pbb_stag operation requires outer tag definition");
18068               return -99;
18069             }
18070         }
18071       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
18072         dmac_set++;
18073       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
18074         smac_set++;
18075       else if (unformat (i, "sid %d", &sid))
18076         ;
18077       else if (unformat (i, "vlanid %d", &tmp))
18078         vlanid = tmp;
18079       else
18080         {
18081           clib_warning ("parse error '%U'", format_unformat_error, i);
18082           return -99;
18083         }
18084     }
18085
18086   if ((sw_if_index == ~0) || (vtr_op == ~0))
18087     {
18088       errmsg ("missing sw_if_index or vtr operation");
18089       return -99;
18090     }
18091   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
18092       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
18093     {
18094       errmsg
18095         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
18096       return -99;
18097     }
18098
18099   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
18100   mp->sw_if_index = ntohl (sw_if_index);
18101   mp->vtr_op = ntohl (vtr_op);
18102   mp->outer_tag = ntohs (outer_tag);
18103   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
18104   clib_memcpy (mp->b_smac, smac, sizeof (smac));
18105   mp->b_vlanid = ntohs (vlanid);
18106   mp->i_sid = ntohl (sid);
18107
18108   S (mp);
18109   W (ret);
18110   return ret;
18111 }
18112
18113 static int
18114 api_flow_classify_set_interface (vat_main_t * vam)
18115 {
18116   unformat_input_t *i = vam->input;
18117   vl_api_flow_classify_set_interface_t *mp;
18118   u32 sw_if_index;
18119   int sw_if_index_set;
18120   u32 ip4_table_index = ~0;
18121   u32 ip6_table_index = ~0;
18122   u8 is_add = 1;
18123   int ret;
18124
18125   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18126     {
18127       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18128         sw_if_index_set = 1;
18129       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18130         sw_if_index_set = 1;
18131       else if (unformat (i, "del"))
18132         is_add = 0;
18133       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18134         ;
18135       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18136         ;
18137       else
18138         {
18139           clib_warning ("parse error '%U'", format_unformat_error, i);
18140           return -99;
18141         }
18142     }
18143
18144   if (sw_if_index_set == 0)
18145     {
18146       errmsg ("missing interface name or sw_if_index");
18147       return -99;
18148     }
18149
18150   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
18151
18152   mp->sw_if_index = ntohl (sw_if_index);
18153   mp->ip4_table_index = ntohl (ip4_table_index);
18154   mp->ip6_table_index = ntohl (ip6_table_index);
18155   mp->is_add = is_add;
18156
18157   S (mp);
18158   W (ret);
18159   return ret;
18160 }
18161
18162 static int
18163 api_flow_classify_dump (vat_main_t * vam)
18164 {
18165   unformat_input_t *i = vam->input;
18166   vl_api_flow_classify_dump_t *mp;
18167   vl_api_control_ping_t *mp_ping;
18168   u8 type = FLOW_CLASSIFY_N_TABLES;
18169   int ret;
18170
18171   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
18172     ;
18173   else
18174     {
18175       errmsg ("classify table type must be specified");
18176       return -99;
18177     }
18178
18179   if (!vam->json_output)
18180     {
18181       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18182     }
18183
18184   M (FLOW_CLASSIFY_DUMP, mp);
18185   mp->type = type;
18186   /* send it... */
18187   S (mp);
18188
18189   /* Use a control ping for synchronization */
18190   M (CONTROL_PING, mp_ping);
18191   S (mp_ping);
18192
18193   /* Wait for a reply... */
18194   W (ret);
18195   return ret;
18196 }
18197
18198 static int
18199 api_feature_enable_disable (vat_main_t * vam)
18200 {
18201   unformat_input_t *i = vam->input;
18202   vl_api_feature_enable_disable_t *mp;
18203   u8 *arc_name = 0;
18204   u8 *feature_name = 0;
18205   u32 sw_if_index = ~0;
18206   u8 enable = 1;
18207   int ret;
18208
18209   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18210     {
18211       if (unformat (i, "arc_name %s", &arc_name))
18212         ;
18213       else if (unformat (i, "feature_name %s", &feature_name))
18214         ;
18215       else
18216         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18217         ;
18218       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18219         ;
18220       else if (unformat (i, "disable"))
18221         enable = 0;
18222       else
18223         break;
18224     }
18225
18226   if (arc_name == 0)
18227     {
18228       errmsg ("missing arc name");
18229       return -99;
18230     }
18231   if (vec_len (arc_name) > 63)
18232     {
18233       errmsg ("arc name too long");
18234     }
18235
18236   if (feature_name == 0)
18237     {
18238       errmsg ("missing feature name");
18239       return -99;
18240     }
18241   if (vec_len (feature_name) > 63)
18242     {
18243       errmsg ("feature name too long");
18244     }
18245
18246   if (sw_if_index == ~0)
18247     {
18248       errmsg ("missing interface name or sw_if_index");
18249       return -99;
18250     }
18251
18252   /* Construct the API message */
18253   M (FEATURE_ENABLE_DISABLE, mp);
18254   mp->sw_if_index = ntohl (sw_if_index);
18255   mp->enable = enable;
18256   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
18257   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
18258   vec_free (arc_name);
18259   vec_free (feature_name);
18260
18261   S (mp);
18262   W (ret);
18263   return ret;
18264 }
18265
18266 static int
18267 api_sw_interface_tag_add_del (vat_main_t * vam)
18268 {
18269   unformat_input_t *i = vam->input;
18270   vl_api_sw_interface_tag_add_del_t *mp;
18271   u32 sw_if_index = ~0;
18272   u8 *tag = 0;
18273   u8 enable = 1;
18274   int ret;
18275
18276   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18277     {
18278       if (unformat (i, "tag %s", &tag))
18279         ;
18280       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18281         ;
18282       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18283         ;
18284       else if (unformat (i, "del"))
18285         enable = 0;
18286       else
18287         break;
18288     }
18289
18290   if (sw_if_index == ~0)
18291     {
18292       errmsg ("missing interface name or sw_if_index");
18293       return -99;
18294     }
18295
18296   if (enable && (tag == 0))
18297     {
18298       errmsg ("no tag specified");
18299       return -99;
18300     }
18301
18302   /* Construct the API message */
18303   M (SW_INTERFACE_TAG_ADD_DEL, mp);
18304   mp->sw_if_index = ntohl (sw_if_index);
18305   mp->is_add = enable;
18306   if (enable)
18307     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
18308   vec_free (tag);
18309
18310   S (mp);
18311   W (ret);
18312   return ret;
18313 }
18314
18315 static void vl_api_l2_xconnect_details_t_handler
18316   (vl_api_l2_xconnect_details_t * mp)
18317 {
18318   vat_main_t *vam = &vat_main;
18319
18320   print (vam->ofp, "%15d%15d",
18321          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
18322 }
18323
18324 static void vl_api_l2_xconnect_details_t_handler_json
18325   (vl_api_l2_xconnect_details_t * mp)
18326 {
18327   vat_main_t *vam = &vat_main;
18328   vat_json_node_t *node = NULL;
18329
18330   if (VAT_JSON_ARRAY != vam->json_tree.type)
18331     {
18332       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18333       vat_json_init_array (&vam->json_tree);
18334     }
18335   node = vat_json_array_add (&vam->json_tree);
18336
18337   vat_json_init_object (node);
18338   vat_json_object_add_uint (node, "rx_sw_if_index",
18339                             ntohl (mp->rx_sw_if_index));
18340   vat_json_object_add_uint (node, "tx_sw_if_index",
18341                             ntohl (mp->tx_sw_if_index));
18342 }
18343
18344 static int
18345 api_l2_xconnect_dump (vat_main_t * vam)
18346 {
18347   vl_api_l2_xconnect_dump_t *mp;
18348   vl_api_control_ping_t *mp_ping;
18349   int ret;
18350
18351   if (!vam->json_output)
18352     {
18353       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
18354     }
18355
18356   M (L2_XCONNECT_DUMP, mp);
18357
18358   S (mp);
18359
18360   /* Use a control ping for synchronization */
18361   M (CONTROL_PING, mp_ping);
18362   S (mp_ping);
18363
18364   W (ret);
18365   return ret;
18366 }
18367
18368 static int
18369 api_sw_interface_set_mtu (vat_main_t * vam)
18370 {
18371   unformat_input_t *i = vam->input;
18372   vl_api_sw_interface_set_mtu_t *mp;
18373   u32 sw_if_index = ~0;
18374   u32 mtu = 0;
18375   int ret;
18376
18377   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18378     {
18379       if (unformat (i, "mtu %d", &mtu))
18380         ;
18381       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18382         ;
18383       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18384         ;
18385       else
18386         break;
18387     }
18388
18389   if (sw_if_index == ~0)
18390     {
18391       errmsg ("missing interface name or sw_if_index");
18392       return -99;
18393     }
18394
18395   if (mtu == 0)
18396     {
18397       errmsg ("no mtu specified");
18398       return -99;
18399     }
18400
18401   /* Construct the API message */
18402   M (SW_INTERFACE_SET_MTU, mp);
18403   mp->sw_if_index = ntohl (sw_if_index);
18404   mp->mtu = ntohs ((u16) mtu);
18405
18406   S (mp);
18407   W (ret);
18408   return ret;
18409 }
18410
18411
18412 static int
18413 q_or_quit (vat_main_t * vam)
18414 {
18415 #if VPP_API_TEST_BUILTIN == 0
18416   longjmp (vam->jump_buf, 1);
18417 #endif
18418   return 0;                     /* not so much */
18419 }
18420
18421 static int
18422 q (vat_main_t * vam)
18423 {
18424   return q_or_quit (vam);
18425 }
18426
18427 static int
18428 quit (vat_main_t * vam)
18429 {
18430   return q_or_quit (vam);
18431 }
18432
18433 static int
18434 comment (vat_main_t * vam)
18435 {
18436   return 0;
18437 }
18438
18439 static int
18440 cmd_cmp (void *a1, void *a2)
18441 {
18442   u8 **c1 = a1;
18443   u8 **c2 = a2;
18444
18445   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
18446 }
18447
18448 static int
18449 help (vat_main_t * vam)
18450 {
18451   u8 **cmds = 0;
18452   u8 *name = 0;
18453   hash_pair_t *p;
18454   unformat_input_t *i = vam->input;
18455   int j;
18456
18457   if (unformat (i, "%s", &name))
18458     {
18459       uword *hs;
18460
18461       vec_add1 (name, 0);
18462
18463       hs = hash_get_mem (vam->help_by_name, name);
18464       if (hs)
18465         print (vam->ofp, "usage: %s %s", name, hs[0]);
18466       else
18467         print (vam->ofp, "No such msg / command '%s'", name);
18468       vec_free (name);
18469       return 0;
18470     }
18471
18472   print (vam->ofp, "Help is available for the following:");
18473
18474     /* *INDENT-OFF* */
18475     hash_foreach_pair (p, vam->function_by_name,
18476     ({
18477       vec_add1 (cmds, (u8 *)(p->key));
18478     }));
18479     /* *INDENT-ON* */
18480
18481   vec_sort_with_function (cmds, cmd_cmp);
18482
18483   for (j = 0; j < vec_len (cmds); j++)
18484     print (vam->ofp, "%s", cmds[j]);
18485
18486   vec_free (cmds);
18487   return 0;
18488 }
18489
18490 static int
18491 set (vat_main_t * vam)
18492 {
18493   u8 *name = 0, *value = 0;
18494   unformat_input_t *i = vam->input;
18495
18496   if (unformat (i, "%s", &name))
18497     {
18498       /* The input buffer is a vector, not a string. */
18499       value = vec_dup (i->buffer);
18500       vec_delete (value, i->index, 0);
18501       /* Almost certainly has a trailing newline */
18502       if (value[vec_len (value) - 1] == '\n')
18503         value[vec_len (value) - 1] = 0;
18504       /* Make sure it's a proper string, one way or the other */
18505       vec_add1 (value, 0);
18506       (void) clib_macro_set_value (&vam->macro_main,
18507                                    (char *) name, (char *) value);
18508     }
18509   else
18510     errmsg ("usage: set <name> <value>");
18511
18512   vec_free (name);
18513   vec_free (value);
18514   return 0;
18515 }
18516
18517 static int
18518 unset (vat_main_t * vam)
18519 {
18520   u8 *name = 0;
18521
18522   if (unformat (vam->input, "%s", &name))
18523     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
18524       errmsg ("unset: %s wasn't set", name);
18525   vec_free (name);
18526   return 0;
18527 }
18528
18529 typedef struct
18530 {
18531   u8 *name;
18532   u8 *value;
18533 } macro_sort_t;
18534
18535
18536 static int
18537 macro_sort_cmp (void *a1, void *a2)
18538 {
18539   macro_sort_t *s1 = a1;
18540   macro_sort_t *s2 = a2;
18541
18542   return strcmp ((char *) (s1->name), (char *) (s2->name));
18543 }
18544
18545 static int
18546 dump_macro_table (vat_main_t * vam)
18547 {
18548   macro_sort_t *sort_me = 0, *sm;
18549   int i;
18550   hash_pair_t *p;
18551
18552     /* *INDENT-OFF* */
18553     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
18554     ({
18555       vec_add2 (sort_me, sm, 1);
18556       sm->name = (u8 *)(p->key);
18557       sm->value = (u8 *) (p->value[0]);
18558     }));
18559     /* *INDENT-ON* */
18560
18561   vec_sort_with_function (sort_me, macro_sort_cmp);
18562
18563   if (vec_len (sort_me))
18564     print (vam->ofp, "%-15s%s", "Name", "Value");
18565   else
18566     print (vam->ofp, "The macro table is empty...");
18567
18568   for (i = 0; i < vec_len (sort_me); i++)
18569     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
18570   return 0;
18571 }
18572
18573 static int
18574 dump_node_table (vat_main_t * vam)
18575 {
18576   int i, j;
18577   vlib_node_t *node, *next_node;
18578
18579   if (vec_len (vam->graph_nodes) == 0)
18580     {
18581       print (vam->ofp, "Node table empty, issue get_node_graph...");
18582       return 0;
18583     }
18584
18585   for (i = 0; i < vec_len (vam->graph_nodes); i++)
18586     {
18587       node = vam->graph_nodes[i];
18588       print (vam->ofp, "[%d] %s", i, node->name);
18589       for (j = 0; j < vec_len (node->next_nodes); j++)
18590         {
18591           if (node->next_nodes[j] != ~0)
18592             {
18593               next_node = vam->graph_nodes[node->next_nodes[j]];
18594               print (vam->ofp, "  [%d] %s", j, next_node->name);
18595             }
18596         }
18597     }
18598   return 0;
18599 }
18600
18601 static int
18602 value_sort_cmp (void *a1, void *a2)
18603 {
18604   name_sort_t *n1 = a1;
18605   name_sort_t *n2 = a2;
18606
18607   if (n1->value < n2->value)
18608     return -1;
18609   if (n1->value > n2->value)
18610     return 1;
18611   return 0;
18612 }
18613
18614
18615 static int
18616 dump_msg_api_table (vat_main_t * vam)
18617 {
18618   api_main_t *am = &api_main;
18619   name_sort_t *nses = 0, *ns;
18620   hash_pair_t *hp;
18621   int i;
18622
18623   /* *INDENT-OFF* */
18624   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
18625   ({
18626     vec_add2 (nses, ns, 1);
18627     ns->name = (u8 *)(hp->key);
18628     ns->value = (u32) hp->value[0];
18629   }));
18630   /* *INDENT-ON* */
18631
18632   vec_sort_with_function (nses, value_sort_cmp);
18633
18634   for (i = 0; i < vec_len (nses); i++)
18635     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
18636   vec_free (nses);
18637   return 0;
18638 }
18639
18640 static int
18641 get_msg_id (vat_main_t * vam)
18642 {
18643   u8 *name_and_crc;
18644   u32 message_index;
18645
18646   if (unformat (vam->input, "%s", &name_and_crc))
18647     {
18648       message_index = vl_api_get_msg_index (name_and_crc);
18649       if (message_index == ~0)
18650         {
18651           print (vam->ofp, " '%s' not found", name_and_crc);
18652           return 0;
18653         }
18654       print (vam->ofp, " '%s' has message index %d",
18655              name_and_crc, message_index);
18656       return 0;
18657     }
18658   errmsg ("name_and_crc required...");
18659   return 0;
18660 }
18661
18662 static int
18663 search_node_table (vat_main_t * vam)
18664 {
18665   unformat_input_t *line_input = vam->input;
18666   u8 *node_to_find;
18667   int j;
18668   vlib_node_t *node, *next_node;
18669   uword *p;
18670
18671   if (vam->graph_node_index_by_name == 0)
18672     {
18673       print (vam->ofp, "Node table empty, issue get_node_graph...");
18674       return 0;
18675     }
18676
18677   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
18678     {
18679       if (unformat (line_input, "%s", &node_to_find))
18680         {
18681           vec_add1 (node_to_find, 0);
18682           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
18683           if (p == 0)
18684             {
18685               print (vam->ofp, "%s not found...", node_to_find);
18686               goto out;
18687             }
18688           node = vam->graph_nodes[p[0]];
18689           print (vam->ofp, "[%d] %s", p[0], node->name);
18690           for (j = 0; j < vec_len (node->next_nodes); j++)
18691             {
18692               if (node->next_nodes[j] != ~0)
18693                 {
18694                   next_node = vam->graph_nodes[node->next_nodes[j]];
18695                   print (vam->ofp, "  [%d] %s", j, next_node->name);
18696                 }
18697             }
18698         }
18699
18700       else
18701         {
18702           clib_warning ("parse error '%U'", format_unformat_error,
18703                         line_input);
18704           return -99;
18705         }
18706
18707     out:
18708       vec_free (node_to_find);
18709
18710     }
18711
18712   return 0;
18713 }
18714
18715
18716 static int
18717 script (vat_main_t * vam)
18718 {
18719 #if (VPP_API_TEST_BUILTIN==0)
18720   u8 *s = 0;
18721   char *save_current_file;
18722   unformat_input_t save_input;
18723   jmp_buf save_jump_buf;
18724   u32 save_line_number;
18725
18726   FILE *new_fp, *save_ifp;
18727
18728   if (unformat (vam->input, "%s", &s))
18729     {
18730       new_fp = fopen ((char *) s, "r");
18731       if (new_fp == 0)
18732         {
18733           errmsg ("Couldn't open script file %s", s);
18734           vec_free (s);
18735           return -99;
18736         }
18737     }
18738   else
18739     {
18740       errmsg ("Missing script name");
18741       return -99;
18742     }
18743
18744   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
18745   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
18746   save_ifp = vam->ifp;
18747   save_line_number = vam->input_line_number;
18748   save_current_file = (char *) vam->current_file;
18749
18750   vam->input_line_number = 0;
18751   vam->ifp = new_fp;
18752   vam->current_file = s;
18753   do_one_file (vam);
18754
18755   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
18756   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
18757   vam->ifp = save_ifp;
18758   vam->input_line_number = save_line_number;
18759   vam->current_file = (u8 *) save_current_file;
18760   vec_free (s);
18761
18762   return 0;
18763 #else
18764   clib_warning ("use the exec command...");
18765   return -99;
18766 #endif
18767 }
18768
18769 static int
18770 echo (vat_main_t * vam)
18771 {
18772   print (vam->ofp, "%v", vam->input->buffer);
18773   return 0;
18774 }
18775
18776 /* List of API message constructors, CLI names map to api_xxx */
18777 #define foreach_vpe_api_msg                                             \
18778 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
18779 _(sw_interface_dump,"")                                                 \
18780 _(sw_interface_set_flags,                                               \
18781   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
18782 _(sw_interface_add_del_address,                                         \
18783   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
18784 _(sw_interface_set_table,                                               \
18785   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
18786 _(sw_interface_set_mpls_enable,                                         \
18787   "<intfc> | sw_if_index [disable | dis]")                              \
18788 _(sw_interface_set_vpath,                                               \
18789   "<intfc> | sw_if_index <id> enable | disable")                        \
18790 _(sw_interface_set_vxlan_bypass,                                        \
18791   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
18792 _(sw_interface_set_l2_xconnect,                                         \
18793   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18794   "enable | disable")                                                   \
18795 _(sw_interface_set_l2_bridge,                                           \
18796   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
18797   "[shg <split-horizon-group>] [bvi]\n"                                 \
18798   "enable | disable")                                                   \
18799 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
18800 _(bridge_domain_add_del,                                                \
18801   "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") \
18802 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
18803 _(l2fib_add_del,                                                        \
18804   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
18805 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
18806 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
18807 _(l2_flags,                                                             \
18808   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
18809 _(bridge_flags,                                                         \
18810   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
18811 _(tap_connect,                                                          \
18812   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
18813 _(tap_modify,                                                           \
18814   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
18815 _(tap_delete,                                                           \
18816   "<vpp-if-name> | sw_if_index <id>")                                   \
18817 _(sw_interface_tap_dump, "")                                            \
18818 _(ip_add_del_route,                                                     \
18819   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
18820   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
18821   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
18822   "[multipath] [count <n>]")                                            \
18823 _(ip_mroute_add_del,                                                    \
18824   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
18825   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
18826 _(mpls_route_add_del,                                                   \
18827   "<label> <eos> via <addr> [table-id <n>]\n"                           \
18828   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
18829   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
18830   "[multipath] [count <n>]")                                            \
18831 _(mpls_ip_bind_unbind,                                                  \
18832   "<label> <addr/len>")                                                 \
18833 _(mpls_tunnel_add_del,                                                  \
18834   " via <addr> [table-id <n>]\n"                                        \
18835   "sw_if_index <id>] [l2]  [del]")                                      \
18836 _(proxy_arp_add_del,                                                    \
18837   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
18838 _(proxy_arp_intfc_enable_disable,                                       \
18839   "<intfc> | sw_if_index <id> enable | disable")                        \
18840 _(sw_interface_set_unnumbered,                                          \
18841   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
18842 _(ip_neighbor_add_del,                                                  \
18843   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
18844   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
18845 _(reset_vrf, "vrf <id> [ipv6]")                                         \
18846 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
18847 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
18848   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
18849   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
18850   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
18851 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
18852 _(reset_fib, "vrf <n> [ipv6]")                                          \
18853 _(dhcp_proxy_config,                                                    \
18854   "svr <v46-address> src <v46-address>\n"                               \
18855    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
18856 _(dhcp_proxy_set_vss,                                                   \
18857   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
18858 _(dhcp_proxy_dump, "ip6")                                               \
18859 _(dhcp_client_config,                                                   \
18860   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
18861 _(set_ip_flow_hash,                                                     \
18862   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
18863 _(sw_interface_ip6_enable_disable,                                      \
18864   "<intfc> | sw_if_index <id> enable | disable")                        \
18865 _(sw_interface_ip6_set_link_local_address,                              \
18866   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
18867 _(ip6nd_proxy_add_del,                                                  \
18868   "<intfc> | sw_if_index <id> <ip6-address>")                           \
18869 _(ip6nd_proxy_dump, "")                                                 \
18870 _(sw_interface_ip6nd_ra_prefix,                                         \
18871   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
18872   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
18873   "[nolink] [isno]")                                                    \
18874 _(sw_interface_ip6nd_ra_config,                                         \
18875   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
18876   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
18877   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
18878 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
18879 _(l2_patch_add_del,                                                     \
18880   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18881   "enable | disable")                                                   \
18882 _(sr_localsid_add_del,                                                  \
18883   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
18884   "fib-table <num> (end.psp) sw_if_index <num>")                        \
18885 _(classify_add_del_table,                                               \
18886   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
18887   " [del] [del-chain] mask <mask-value>\n"                              \
18888   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
18889   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
18890 _(classify_add_del_session,                                             \
18891   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
18892   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
18893   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
18894   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
18895 _(classify_set_interface_ip_table,                                      \
18896   "<intfc> | sw_if_index <nn> table <nn>")                              \
18897 _(classify_set_interface_l2_tables,                                     \
18898   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18899   "  [other-table <nn>]")                                               \
18900 _(get_node_index, "node <node-name")                                    \
18901 _(add_node_next, "node <node-name> next <next-node-name>")              \
18902 _(l2tpv3_create_tunnel,                                                 \
18903   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
18904   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
18905   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
18906 _(l2tpv3_set_tunnel_cookies,                                            \
18907   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
18908   "[new_remote_cookie <nn>]\n")                                         \
18909 _(l2tpv3_interface_enable_disable,                                      \
18910   "<intfc> | sw_if_index <nn> enable | disable")                        \
18911 _(l2tpv3_set_lookup_key,                                                \
18912   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
18913 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
18914 _(vxlan_add_del_tunnel,                                                 \
18915   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
18916   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
18917   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
18918 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
18919 _(gre_add_del_tunnel,                                                   \
18920   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
18921 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
18922 _(l2_fib_clear_table, "")                                               \
18923 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
18924 _(l2_interface_vlan_tag_rewrite,                                        \
18925   "<intfc> | sw_if_index <nn> \n"                                       \
18926   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
18927   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
18928 _(create_vhost_user_if,                                                 \
18929         "socket <filename> [server] [renumber <dev_instance>] "         \
18930         "[mac <mac_address>] "                                          \
18931         "[mode <interrupt | polling>]")                                 \
18932 _(modify_vhost_user_if,                                                 \
18933         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
18934         "[server] [renumber <dev_instance>] "                           \
18935         "[mode <interrupt | polling>]")                                 \
18936 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
18937 _(sw_interface_vhost_user_dump, "")                                     \
18938 _(show_version, "")                                                     \
18939 _(vxlan_gpe_add_del_tunnel,                                             \
18940   "local <addr> remote <addr> vni <nn>\n"                               \
18941     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
18942   "[next-ethernet] [next-nsh]\n")                                       \
18943 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
18944 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
18945 _(interface_name_renumber,                                              \
18946   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
18947 _(input_acl_set_interface,                                              \
18948   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18949   "  [l2-table <nn>] [del]")                                            \
18950 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
18951 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
18952 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
18953 _(ip_dump, "ipv4 | ipv6")                                               \
18954 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
18955 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
18956   "  spid_id <n> ")                                                     \
18957 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
18958   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
18959   "  integ_alg <alg> integ_key <hex>")                                  \
18960 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
18961   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
18962   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
18963   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
18964 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
18965 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
18966   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
18967   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
18968   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
18969 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
18970 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
18971   "(auth_data 0x<data> | auth_data <data>)")                            \
18972 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
18973   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
18974 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
18975   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
18976   "(local|remote)")                                                     \
18977 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
18978 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
18979 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18980 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18981 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
18982 _(ikev2_initiate_sa_init, "<profile_name>")                             \
18983 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
18984 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
18985 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
18986 _(delete_loopback,"sw_if_index <nn>")                                   \
18987 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
18988 _(map_add_domain,                                                       \
18989   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
18990   "ip6-src <ip6addr> "                                                  \
18991   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
18992 _(map_del_domain, "index <n>")                                          \
18993 _(map_add_del_rule,                                                     \
18994   "index <n> psid <n> dst <ip6addr> [del]")                             \
18995 _(map_domain_dump, "")                                                  \
18996 _(map_rule_dump, "index <map-domain>")                                  \
18997 _(want_interface_events,  "enable|disable")                             \
18998 _(want_stats,"enable|disable")                                          \
18999 _(get_first_msg_id, "client <name>")                                    \
19000 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
19001 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
19002   "fib-id <nn> [ip4][ip6][default]")                                    \
19003 _(get_node_graph, " ")                                                  \
19004 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
19005 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
19006 _(ioam_disable, "")                                                     \
19007 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
19008                             " sw_if_index <sw_if_index> p <priority> "  \
19009                             "w <weight>] [del]")                        \
19010 _(one_add_del_locator, "locator-set <locator_name> "                    \
19011                         "iface <intf> | sw_if_index <sw_if_index> "     \
19012                         "p <priority> w <weight> [del]")                \
19013 _(one_add_del_local_eid,"vni <vni> eid "                                \
19014                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
19015                          "locator-set <locator_name> [del]"             \
19016                          "[key-id sha1|sha256 secret-key <secret-key>]")\
19017 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
19018 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
19019 _(one_enable_disable, "enable|disable")                                 \
19020 _(one_map_register_enable_disable, "enable|disable")                    \
19021 _(one_rloc_probe_enable_disable, "enable|disable")                      \
19022 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
19023                                "[seid <seid>] "                         \
19024                                "rloc <locator> p <prio> "               \
19025                                "w <weight> [rloc <loc> ... ] "          \
19026                                "action <action> [del-all]")             \
19027 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
19028                           "<local-eid>")                                \
19029 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
19030 _(one_use_petr, "ip-address> | disable")                                \
19031 _(one_map_request_mode, "src-dst|dst-only")                             \
19032 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
19033 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
19034 _(one_locator_set_dump, "[local | remote]")                             \
19035 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
19036 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
19037                        "[local] | [remote]")                            \
19038 _(one_stats_enable_disable, "enable|disalbe")                           \
19039 _(show_one_stats_enable_disable, "")                                    \
19040 _(one_eid_table_vni_dump, "")                                           \
19041 _(one_eid_table_map_dump, "l2|l3")                                      \
19042 _(one_map_resolver_dump, "")                                            \
19043 _(one_map_server_dump, "")                                              \
19044 _(one_adjacencies_get, "vni <vni>")                                     \
19045 _(show_one_rloc_probe_state, "")                                        \
19046 _(show_one_map_register_state, "")                                      \
19047 _(show_one_status, "")                                                  \
19048 _(one_stats_dump, "")                                                   \
19049 _(one_stats_flush, "")                                                  \
19050 _(one_get_map_request_itr_rlocs, "")                                    \
19051 _(show_one_pitr, "")                                                    \
19052 _(show_one_use_petr, "")                                                \
19053 _(show_one_map_request_mode, "")                                        \
19054 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
19055                             " sw_if_index <sw_if_index> p <priority> "  \
19056                             "w <weight>] [del]")                        \
19057 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
19058                         "iface <intf> | sw_if_index <sw_if_index> "     \
19059                         "p <priority> w <weight> [del]")                \
19060 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
19061                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
19062                          "locator-set <locator_name> [del]"             \
19063                          "[key-id sha1|sha256 secret-key <secret-key>]") \
19064 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
19065 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
19066 _(lisp_enable_disable, "enable|disable")                                \
19067 _(lisp_map_register_enable_disable, "enable|disable")                   \
19068 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
19069 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
19070                                "[seid <seid>] "                         \
19071                                "rloc <locator> p <prio> "               \
19072                                "w <weight> [rloc <loc> ... ] "          \
19073                                "action <action> [del-all]")             \
19074 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
19075                           "<local-eid>")                                \
19076 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
19077 _(lisp_use_petr, "<ip-address> | disable")                              \
19078 _(lisp_map_request_mode, "src-dst|dst-only")                            \
19079 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
19080 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
19081 _(lisp_locator_set_dump, "[local | remote]")                            \
19082 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
19083 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
19084                        "[local] | [remote]")                            \
19085 _(lisp_eid_table_vni_dump, "")                                          \
19086 _(lisp_eid_table_map_dump, "l2|l3")                                     \
19087 _(lisp_map_resolver_dump, "")                                           \
19088 _(lisp_map_server_dump, "")                                             \
19089 _(lisp_adjacencies_get, "vni <vni>")                                    \
19090 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
19091 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
19092 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
19093 _(gpe_get_encap_mode, "")                                               \
19094 _(lisp_gpe_add_del_iface, "up|down")                                    \
19095 _(lisp_gpe_enable_disable, "enable|disable")                            \
19096 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
19097   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
19098 _(show_lisp_rloc_probe_state, "")                                       \
19099 _(show_lisp_map_register_state, "")                                     \
19100 _(show_lisp_status, "")                                                 \
19101 _(lisp_get_map_request_itr_rlocs, "")                                   \
19102 _(show_lisp_pitr, "")                                                   \
19103 _(show_lisp_use_petr, "")                                               \
19104 _(show_lisp_map_request_mode, "")                                       \
19105 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
19106 _(af_packet_delete, "name <host interface name>")                       \
19107 _(policer_add_del, "name <policer name> <params> [del]")                \
19108 _(policer_dump, "[name <policer name>]")                                \
19109 _(policer_classify_set_interface,                                       \
19110   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
19111   "  [l2-table <nn>] [del]")                                            \
19112 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
19113 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
19114     "[master|slave]")                                                   \
19115 _(netmap_delete, "name <interface name>")                               \
19116 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
19117 _(mpls_fib_dump, "")                                                    \
19118 _(classify_table_ids, "")                                               \
19119 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
19120 _(classify_table_info, "table_id <nn>")                                 \
19121 _(classify_session_dump, "table_id <nn>")                               \
19122 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
19123     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
19124     "[template_interval <nn>] [udp_checksum]")                          \
19125 _(ipfix_exporter_dump, "")                                              \
19126 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
19127 _(ipfix_classify_stream_dump, "")                                       \
19128 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
19129 _(ipfix_classify_table_dump, "")                                        \
19130 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
19131 _(sw_interface_span_dump, "")                                           \
19132 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
19133 _(pg_create_interface, "if_id <nn>")                                    \
19134 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
19135 _(pg_enable_disable, "[stream <id>] disable")                           \
19136 _(ip_source_and_port_range_check_add_del,                               \
19137   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
19138 _(ip_source_and_port_range_check_interface_add_del,                     \
19139   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
19140   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
19141 _(ipsec_gre_add_del_tunnel,                                             \
19142   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
19143 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
19144 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
19145 _(l2_interface_pbb_tag_rewrite,                                         \
19146   "<intfc> | sw_if_index <nn> \n"                                       \
19147   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
19148   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
19149 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
19150 _(flow_classify_set_interface,                                          \
19151   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
19152 _(flow_classify_dump, "type [ip4|ip6]")                                 \
19153 _(ip_fib_dump, "")                                                      \
19154 _(ip_mfib_dump, "")                                                     \
19155 _(ip6_fib_dump, "")                                                     \
19156 _(ip6_mfib_dump, "")                                                    \
19157 _(feature_enable_disable, "arc_name <arc_name> "                        \
19158   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
19159 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
19160 "[disable]")                                                            \
19161 _(l2_xconnect_dump, "")                                                 \
19162 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
19163 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
19164 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
19165
19166 /* List of command functions, CLI names map directly to functions */
19167 #define foreach_cli_function                                    \
19168 _(comment, "usage: comment <ignore-rest-of-line>")              \
19169 _(dump_interface_table, "usage: dump_interface_table")          \
19170 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
19171 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
19172 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
19173 _(dump_stats_table, "usage: dump_stats_table")                  \
19174 _(dump_macro_table, "usage: dump_macro_table ")                 \
19175 _(dump_node_table, "usage: dump_node_table")                    \
19176 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
19177 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
19178 _(echo, "usage: echo <message>")                                \
19179 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
19180 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
19181 _(help, "usage: help")                                          \
19182 _(q, "usage: quit")                                             \
19183 _(quit, "usage: quit")                                          \
19184 _(search_node_table, "usage: search_node_table <name>...")      \
19185 _(set, "usage: set <variable-name> <value>")                    \
19186 _(script, "usage: script <file-name>")                          \
19187 _(unset, "usage: unset <variable-name>")
19188
19189 #define _(N,n)                                  \
19190     static void vl_api_##n##_t_handler_uni      \
19191     (vl_api_##n##_t * mp)                       \
19192     {                                           \
19193         vat_main_t * vam = &vat_main;           \
19194         if (vam->json_output) {                 \
19195             vl_api_##n##_t_handler_json(mp);    \
19196         } else {                                \
19197             vl_api_##n##_t_handler(mp);         \
19198         }                                       \
19199     }
19200 foreach_vpe_api_reply_msg;
19201 #if VPP_API_TEST_BUILTIN == 0
19202 foreach_standalone_reply_msg;
19203 #endif
19204 #undef _
19205
19206 void
19207 vat_api_hookup (vat_main_t * vam)
19208 {
19209 #define _(N,n)                                                  \
19210     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
19211                            vl_api_##n##_t_handler_uni,          \
19212                            vl_noop_handler,                     \
19213                            vl_api_##n##_t_endian,               \
19214                            vl_api_##n##_t_print,                \
19215                            sizeof(vl_api_##n##_t), 1);
19216   foreach_vpe_api_reply_msg;
19217 #if VPP_API_TEST_BUILTIN == 0
19218   foreach_standalone_reply_msg;
19219 #endif
19220 #undef _
19221
19222 #if (VPP_API_TEST_BUILTIN==0)
19223   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
19224
19225   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
19226
19227   vam->function_by_name = hash_create_string (0, sizeof (uword));
19228
19229   vam->help_by_name = hash_create_string (0, sizeof (uword));
19230 #endif
19231
19232   /* API messages we can send */
19233 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
19234   foreach_vpe_api_msg;
19235 #undef _
19236
19237   /* Help strings */
19238 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
19239   foreach_vpe_api_msg;
19240 #undef _
19241
19242   /* CLI functions */
19243 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
19244   foreach_cli_function;
19245 #undef _
19246
19247   /* Help strings */
19248 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
19249   foreach_cli_function;
19250 #undef _
19251 }
19252
19253 #if VPP_API_TEST_BUILTIN
19254 static clib_error_t *
19255 vat_api_hookup_shim (vlib_main_t * vm)
19256 {
19257   vat_api_hookup (&vat_main);
19258   return 0;
19259 }
19260
19261 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
19262 #endif
19263
19264 /*
19265  * fd.io coding-style-patch-verification: ON
19266  *
19267  * Local Variables:
19268  * eval: (c-set-style "gnu")
19269  * End:
19270  */