Fix vnet_interface_counters API definition
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/l2/l2_input.h>
26 #include <vnet/l2tp/l2tp.h>
27 #include <vnet/vxlan/vxlan.h>
28 #include <vnet/gre/gre.h>
29 #include <vnet/vxlan-gpe/vxlan_gpe.h>
30 #include <vnet/lisp-gpe/lisp_gpe.h>
31
32 #include <vpp/api/vpe_msg_enum.h>
33 #include <vnet/l2/l2_classify.h>
34 #include <vnet/l2/l2_vtr.h>
35 #include <vnet/classify/input_acl.h>
36 #include <vnet/classify/policer_classify.h>
37 #include <vnet/classify/flow_classify.h>
38 #include <vnet/mpls/mpls.h>
39 #include <vnet/ipsec/ipsec.h>
40 #include <vnet/ipsec/ikev2.h>
41 #include <inttypes.h>
42 #include <vnet/map/map.h>
43 #include <vnet/cop/cop.h>
44 #include <vnet/ip/ip6_hop_by_hop.h>
45 #include <vnet/ip/ip_source_and_port_range_check.h>
46 #include <vnet/policer/xlate.h>
47 #include <vnet/span/span.h>
48 #include <vnet/policer/policer.h>
49 #include <vnet/policer/police.h>
50 #include <vnet/mfib/mfib_types.h>
51
52 #include "vat/json_format.h"
53
54 #include <inttypes.h>
55 #include <sys/stat.h>
56
57 #define vl_typedefs             /* define message structures */
58 #include <vpp/api/vpe_all_api_h.h>
59 #undef vl_typedefs
60
61 /* declare message handlers for each api */
62
63 #define vl_endianfun            /* define message structures */
64 #include <vpp/api/vpe_all_api_h.h>
65 #undef vl_endianfun
66
67 /* instantiate all the print functions we know about */
68 #define vl_print(handle, ...)
69 #define vl_printfun
70 #include <vpp/api/vpe_all_api_h.h>
71 #undef vl_printfun
72
73 #define __plugin_msg_base 0
74 #include <vlibapi/vat_helper_macros.h>
75
76 f64
77 vat_time_now (vat_main_t * vam)
78 {
79 #if VPP_API_TEST_BUILTIN
80   return vlib_time_now (vam->vlib_main);
81 #else
82   return clib_time_now (&vam->clib_time);
83 #endif
84 }
85
86 void
87 errmsg (char *fmt, ...)
88 {
89   vat_main_t *vam = &vat_main;
90   va_list va;
91   u8 *s;
92
93   va_start (va, fmt);
94   s = va_format (0, fmt, &va);
95   va_end (va);
96
97   vec_add1 (s, 0);
98
99 #if VPP_API_TEST_BUILTIN
100   vlib_cli_output (vam->vlib_main, (char *) s);
101 #else
102   {
103     if (vam->ifp != stdin)
104       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
105                vam->input_line_number);
106     fformat (vam->ofp, (char *) s);
107     fflush (vam->ofp);
108   }
109 #endif
110
111   vec_free (s);
112 }
113
114 #if VPP_API_TEST_BUILTIN == 0
115 static uword
116 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
117 {
118   vat_main_t *vam = va_arg (*args, vat_main_t *);
119   u32 *result = va_arg (*args, u32 *);
120   u8 *if_name;
121   uword *p;
122
123   if (!unformat (input, "%s", &if_name))
124     return 0;
125
126   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
127   if (p == 0)
128     return 0;
129   *result = p[0];
130   return 1;
131 }
132
133 /* Parse an IP4 address %d.%d.%d.%d. */
134 uword
135 unformat_ip4_address (unformat_input_t * input, va_list * args)
136 {
137   u8 *result = va_arg (*args, u8 *);
138   unsigned a[4];
139
140   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
141     return 0;
142
143   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
144     return 0;
145
146   result[0] = a[0];
147   result[1] = a[1];
148   result[2] = a[2];
149   result[3] = a[3];
150
151   return 1;
152 }
153
154 uword
155 unformat_ethernet_address (unformat_input_t * input, va_list * args)
156 {
157   u8 *result = va_arg (*args, u8 *);
158   u32 i, a[6];
159
160   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
161                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
162     return 0;
163
164   /* Check range. */
165   for (i = 0; i < 6; i++)
166     if (a[i] >= (1 << 8))
167       return 0;
168
169   for (i = 0; i < 6; i++)
170     result[i] = a[i];
171
172   return 1;
173 }
174
175 /* Returns ethernet type as an int in host byte order. */
176 uword
177 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
178                                         va_list * args)
179 {
180   u16 *result = va_arg (*args, u16 *);
181   int type;
182
183   /* Numeric type. */
184   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
185     {
186       if (type >= (1 << 16))
187         return 0;
188       *result = type;
189       return 1;
190     }
191   return 0;
192 }
193
194 /* Parse an IP6 address. */
195 uword
196 unformat_ip6_address (unformat_input_t * input, va_list * args)
197 {
198   ip6_address_t *result = va_arg (*args, ip6_address_t *);
199   u16 hex_quads[8];
200   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
201   uword c, n_colon, double_colon_index;
202
203   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
204   double_colon_index = ARRAY_LEN (hex_quads);
205   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
206     {
207       hex_digit = 16;
208       if (c >= '0' && c <= '9')
209         hex_digit = c - '0';
210       else if (c >= 'a' && c <= 'f')
211         hex_digit = c + 10 - 'a';
212       else if (c >= 'A' && c <= 'F')
213         hex_digit = c + 10 - 'A';
214       else if (c == ':' && n_colon < 2)
215         n_colon++;
216       else
217         {
218           unformat_put_input (input);
219           break;
220         }
221
222       /* Too many hex quads. */
223       if (n_hex_quads >= ARRAY_LEN (hex_quads))
224         return 0;
225
226       if (hex_digit < 16)
227         {
228           hex_quad = (hex_quad << 4) | hex_digit;
229
230           /* Hex quad must fit in 16 bits. */
231           if (n_hex_digits >= 4)
232             return 0;
233
234           n_colon = 0;
235           n_hex_digits++;
236         }
237
238       /* Save position of :: */
239       if (n_colon == 2)
240         {
241           /* More than one :: ? */
242           if (double_colon_index < ARRAY_LEN (hex_quads))
243             return 0;
244           double_colon_index = n_hex_quads;
245         }
246
247       if (n_colon > 0 && n_hex_digits > 0)
248         {
249           hex_quads[n_hex_quads++] = hex_quad;
250           hex_quad = 0;
251           n_hex_digits = 0;
252         }
253     }
254
255   if (n_hex_digits > 0)
256     hex_quads[n_hex_quads++] = hex_quad;
257
258   {
259     word i;
260
261     /* Expand :: to appropriate number of zero hex quads. */
262     if (double_colon_index < ARRAY_LEN (hex_quads))
263       {
264         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
265
266         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
267           hex_quads[n_zero + i] = hex_quads[i];
268
269         for (i = 0; i < n_zero; i++)
270           hex_quads[double_colon_index + i] = 0;
271
272         n_hex_quads = ARRAY_LEN (hex_quads);
273       }
274
275     /* Too few hex quads given. */
276     if (n_hex_quads < ARRAY_LEN (hex_quads))
277       return 0;
278
279     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
280       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
281
282     return 1;
283   }
284 }
285
286 uword
287 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
288 {
289   u32 *r = va_arg (*args, u32 *);
290
291   if (0);
292 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
293   foreach_ipsec_policy_action
294 #undef _
295     else
296     return 0;
297   return 1;
298 }
299
300 uword
301 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
302 {
303   u32 *r = va_arg (*args, u32 *);
304
305   if (0);
306 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
307   foreach_ipsec_crypto_alg
308 #undef _
309     else
310     return 0;
311   return 1;
312 }
313
314 u8 *
315 format_ipsec_crypto_alg (u8 * s, va_list * args)
316 {
317   u32 i = va_arg (*args, u32);
318   u8 *t = 0;
319
320   switch (i)
321     {
322 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
323       foreach_ipsec_crypto_alg
324 #undef _
325     default:
326       return format (s, "unknown");
327     }
328   return format (s, "%s", t);
329 }
330
331 uword
332 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
333 {
334   u32 *r = va_arg (*args, u32 *);
335
336   if (0);
337 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
338   foreach_ipsec_integ_alg
339 #undef _
340     else
341     return 0;
342   return 1;
343 }
344
345 u8 *
346 format_ipsec_integ_alg (u8 * s, va_list * args)
347 {
348   u32 i = va_arg (*args, u32);
349   u8 *t = 0;
350
351   switch (i)
352     {
353 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
354       foreach_ipsec_integ_alg
355 #undef _
356     default:
357       return format (s, "unknown");
358     }
359   return format (s, "%s", t);
360 }
361
362 uword
363 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
364 {
365   u32 *r = va_arg (*args, u32 *);
366
367   if (0);
368 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
369   foreach_ikev2_auth_method
370 #undef _
371     else
372     return 0;
373   return 1;
374 }
375
376 uword
377 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
378 {
379   u32 *r = va_arg (*args, u32 *);
380
381   if (0);
382 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
383   foreach_ikev2_id_type
384 #undef _
385     else
386     return 0;
387   return 1;
388 }
389 #else /* VPP_API_TEST_BUILTIN == 1 */
390 static uword
391 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
392 {
393   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
394   vnet_main_t *vnm = vnet_get_main ();
395   u32 *result = va_arg (*args, u32 *);
396   u32 sw_if_index;
397
398   if (!unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
399     return 0;
400
401   *result = sw_if_index;
402   return 1;
403 }
404 #endif /* VPP_API_TEST_BUILTIN */
405
406 #define VHOST_USER_POLLING_MODE   0
407 #define VHOST_USER_INTERRUPT_MODE 1
408 #define VHOST_USER_ADAPTIVE_MODE  2
409
410 static u8 *
411 api_format_vhost_user_operation_mode (u8 * s, va_list * va)
412 {
413   int operation_mode = va_arg (*va, int);
414
415   switch (operation_mode)
416     {
417     case VHOST_USER_POLLING_MODE:
418       s = format (s, "%-9s", "polling");
419       break;
420     case VHOST_USER_INTERRUPT_MODE:
421       s = format (s, "%-9s", "interrupt");
422       break;
423     default:
424       s = format (s, "%-9s", "invalid");
425     }
426   return s;
427 }
428
429 static uword
430 api_unformat_vhost_user_operation_mode (unformat_input_t * input,
431                                         va_list * args)
432 {
433   u8 *operation_mode = va_arg (*args, u8 *);
434   uword rc = 1;
435
436   if (unformat (input, "interrupt"))
437     *operation_mode = VHOST_USER_INTERRUPT_MODE;
438   else if (unformat (input, "polling"))
439     *operation_mode = VHOST_USER_POLLING_MODE;
440   else
441     rc = 0;
442
443   return rc;
444 }
445
446 static uword
447 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
448 {
449   u8 *r = va_arg (*args, u8 *);
450
451   if (unformat (input, "kbps"))
452     *r = SSE2_QOS_RATE_KBPS;
453   else if (unformat (input, "pps"))
454     *r = SSE2_QOS_RATE_PPS;
455   else
456     return 0;
457   return 1;
458 }
459
460 static uword
461 unformat_policer_round_type (unformat_input_t * input, va_list * args)
462 {
463   u8 *r = va_arg (*args, u8 *);
464
465   if (unformat (input, "closest"))
466     *r = SSE2_QOS_ROUND_TO_CLOSEST;
467   else if (unformat (input, "up"))
468     *r = SSE2_QOS_ROUND_TO_UP;
469   else if (unformat (input, "down"))
470     *r = SSE2_QOS_ROUND_TO_DOWN;
471   else
472     return 0;
473   return 1;
474 }
475
476 static uword
477 unformat_policer_type (unformat_input_t * input, va_list * args)
478 {
479   u8 *r = va_arg (*args, u8 *);
480
481   if (unformat (input, "1r2c"))
482     *r = SSE2_QOS_POLICER_TYPE_1R2C;
483   else if (unformat (input, "1r3c"))
484     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
485   else if (unformat (input, "2r3c-2698"))
486     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
487   else if (unformat (input, "2r3c-4115"))
488     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
489   else if (unformat (input, "2r3c-mef5cf1"))
490     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
491   else
492     return 0;
493   return 1;
494 }
495
496 static uword
497 unformat_dscp (unformat_input_t * input, va_list * va)
498 {
499   u8 *r = va_arg (*va, u8 *);
500
501   if (0);
502 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
503   foreach_vnet_dscp
504 #undef _
505     else
506     return 0;
507   return 1;
508 }
509
510 static uword
511 unformat_policer_action_type (unformat_input_t * input, va_list * va)
512 {
513   sse2_qos_pol_action_params_st *a
514     = va_arg (*va, sse2_qos_pol_action_params_st *);
515
516   if (unformat (input, "drop"))
517     a->action_type = SSE2_QOS_ACTION_DROP;
518   else if (unformat (input, "transmit"))
519     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
520   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
521     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
522   else
523     return 0;
524   return 1;
525 }
526
527 static uword
528 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
529 {
530   u32 *r = va_arg (*va, u32 *);
531   u32 tid;
532
533   if (unformat (input, "ip4"))
534     tid = POLICER_CLASSIFY_TABLE_IP4;
535   else if (unformat (input, "ip6"))
536     tid = POLICER_CLASSIFY_TABLE_IP6;
537   else if (unformat (input, "l2"))
538     tid = POLICER_CLASSIFY_TABLE_L2;
539   else
540     return 0;
541
542   *r = tid;
543   return 1;
544 }
545
546 static uword
547 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
548 {
549   u32 *r = va_arg (*va, u32 *);
550   u32 tid;
551
552   if (unformat (input, "ip4"))
553     tid = FLOW_CLASSIFY_TABLE_IP4;
554   else if (unformat (input, "ip6"))
555     tid = FLOW_CLASSIFY_TABLE_IP6;
556   else
557     return 0;
558
559   *r = tid;
560   return 1;
561 }
562
563 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
564 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
565 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
566 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
567
568 #if (VPP_API_TEST_BUILTIN==0)
569 uword
570 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
571 {
572   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
573   mfib_itf_attribute_t attr;
574
575   old = *iflags;
576   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
577   {
578     if (unformat (input, mfib_itf_flag_long_names[attr]))
579       *iflags |= (1 << attr);
580   }
581   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
582   {
583     if (unformat (input, mfib_itf_flag_names[attr]))
584       *iflags |= (1 << attr);
585   }
586
587   return (old == *iflags ? 0 : 1);
588 }
589
590 uword
591 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
592 {
593   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
594   mfib_entry_attribute_t attr;
595
596   old = *eflags;
597   FOR_EACH_MFIB_ATTRIBUTE (attr)
598   {
599     if (unformat (input, mfib_flag_long_names[attr]))
600       *eflags |= (1 << attr);
601   }
602   FOR_EACH_MFIB_ATTRIBUTE (attr)
603   {
604     if (unformat (input, mfib_flag_names[attr]))
605       *eflags |= (1 << attr);
606   }
607
608   return (old == *eflags ? 0 : 1);
609 }
610
611 u8 *
612 format_ip4_address (u8 * s, va_list * args)
613 {
614   u8 *a = va_arg (*args, u8 *);
615   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
616 }
617
618 u8 *
619 format_ip6_address (u8 * s, va_list * args)
620 {
621   ip6_address_t *a = va_arg (*args, ip6_address_t *);
622   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
623
624   i_max_n_zero = ARRAY_LEN (a->as_u16);
625   max_n_zeros = 0;
626   i_first_zero = i_max_n_zero;
627   n_zeros = 0;
628   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
629     {
630       u32 is_zero = a->as_u16[i] == 0;
631       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
632         {
633           i_first_zero = i;
634           n_zeros = 0;
635         }
636       n_zeros += is_zero;
637       if ((!is_zero && n_zeros > max_n_zeros)
638           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
639         {
640           i_max_n_zero = i_first_zero;
641           max_n_zeros = n_zeros;
642           i_first_zero = ARRAY_LEN (a->as_u16);
643           n_zeros = 0;
644         }
645     }
646
647   last_double_colon = 0;
648   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
649     {
650       if (i == i_max_n_zero && max_n_zeros > 1)
651         {
652           s = format (s, "::");
653           i += max_n_zeros - 1;
654           last_double_colon = 1;
655         }
656       else
657         {
658           s = format (s, "%s%x",
659                       (last_double_colon || i == 0) ? "" : ":",
660                       clib_net_to_host_u16 (a->as_u16[i]));
661           last_double_colon = 0;
662         }
663     }
664
665   return s;
666 }
667
668 /* Format an IP46 address. */
669 u8 *
670 format_ip46_address (u8 * s, va_list * args)
671 {
672   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
673   ip46_type_t type = va_arg (*args, ip46_type_t);
674   int is_ip4 = 1;
675
676   switch (type)
677     {
678     case IP46_TYPE_ANY:
679       is_ip4 = ip46_address_is_ip4 (ip46);
680       break;
681     case IP46_TYPE_IP4:
682       is_ip4 = 1;
683       break;
684     case IP46_TYPE_IP6:
685       is_ip4 = 0;
686       break;
687     }
688
689   return is_ip4 ?
690     format (s, "%U", format_ip4_address, &ip46->ip4) :
691     format (s, "%U", format_ip6_address, &ip46->ip6);
692 }
693
694 u8 *
695 format_ethernet_address (u8 * s, va_list * args)
696 {
697   u8 *a = va_arg (*args, u8 *);
698
699   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
700                  a[0], a[1], a[2], a[3], a[4], a[5]);
701 }
702 #endif
703
704 static void
705 increment_v4_address (ip4_address_t * a)
706 {
707   u32 v;
708
709   v = ntohl (a->as_u32) + 1;
710   a->as_u32 = ntohl (v);
711 }
712
713 static void
714 increment_v6_address (ip6_address_t * a)
715 {
716   u64 v0, v1;
717
718   v0 = clib_net_to_host_u64 (a->as_u64[0]);
719   v1 = clib_net_to_host_u64 (a->as_u64[1]);
720
721   v1 += 1;
722   if (v1 == 0)
723     v0 += 1;
724   a->as_u64[0] = clib_net_to_host_u64 (v0);
725   a->as_u64[1] = clib_net_to_host_u64 (v1);
726 }
727
728 static void
729 increment_mac_address (u64 * mac)
730 {
731   u64 tmp = *mac;
732
733   tmp = clib_net_to_host_u64 (tmp);
734   tmp += 1 << 16;               /* skip unused (least significant) octets */
735   tmp = clib_host_to_net_u64 (tmp);
736   *mac = tmp;
737 }
738
739 static void vl_api_create_loopback_reply_t_handler
740   (vl_api_create_loopback_reply_t * mp)
741 {
742   vat_main_t *vam = &vat_main;
743   i32 retval = ntohl (mp->retval);
744
745   vam->retval = retval;
746   vam->regenerate_interface_table = 1;
747   vam->sw_if_index = ntohl (mp->sw_if_index);
748   vam->result_ready = 1;
749 }
750
751 static void vl_api_create_loopback_reply_t_handler_json
752   (vl_api_create_loopback_reply_t * mp)
753 {
754   vat_main_t *vam = &vat_main;
755   vat_json_node_t node;
756
757   vat_json_init_object (&node);
758   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
759   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
760
761   vat_json_print (vam->ofp, &node);
762   vat_json_free (&node);
763   vam->retval = ntohl (mp->retval);
764   vam->result_ready = 1;
765 }
766
767 static void vl_api_create_loopback_instance_reply_t_handler
768   (vl_api_create_loopback_instance_reply_t * mp)
769 {
770   vat_main_t *vam = &vat_main;
771   i32 retval = ntohl (mp->retval);
772
773   vam->retval = retval;
774   vam->regenerate_interface_table = 1;
775   vam->sw_if_index = ntohl (mp->sw_if_index);
776   vam->result_ready = 1;
777 }
778
779 static void vl_api_create_loopback_instance_reply_t_handler_json
780   (vl_api_create_loopback_instance_reply_t * mp)
781 {
782   vat_main_t *vam = &vat_main;
783   vat_json_node_t node;
784
785   vat_json_init_object (&node);
786   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
787   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
788
789   vat_json_print (vam->ofp, &node);
790   vat_json_free (&node);
791   vam->retval = ntohl (mp->retval);
792   vam->result_ready = 1;
793 }
794
795 static void vl_api_af_packet_create_reply_t_handler
796   (vl_api_af_packet_create_reply_t * mp)
797 {
798   vat_main_t *vam = &vat_main;
799   i32 retval = ntohl (mp->retval);
800
801   vam->retval = retval;
802   vam->regenerate_interface_table = 1;
803   vam->sw_if_index = ntohl (mp->sw_if_index);
804   vam->result_ready = 1;
805 }
806
807 static void vl_api_af_packet_create_reply_t_handler_json
808   (vl_api_af_packet_create_reply_t * mp)
809 {
810   vat_main_t *vam = &vat_main;
811   vat_json_node_t node;
812
813   vat_json_init_object (&node);
814   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
815   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
816
817   vat_json_print (vam->ofp, &node);
818   vat_json_free (&node);
819
820   vam->retval = ntohl (mp->retval);
821   vam->result_ready = 1;
822 }
823
824 static void vl_api_create_vlan_subif_reply_t_handler
825   (vl_api_create_vlan_subif_reply_t * mp)
826 {
827   vat_main_t *vam = &vat_main;
828   i32 retval = ntohl (mp->retval);
829
830   vam->retval = retval;
831   vam->regenerate_interface_table = 1;
832   vam->sw_if_index = ntohl (mp->sw_if_index);
833   vam->result_ready = 1;
834 }
835
836 static void vl_api_create_vlan_subif_reply_t_handler_json
837   (vl_api_create_vlan_subif_reply_t * mp)
838 {
839   vat_main_t *vam = &vat_main;
840   vat_json_node_t node;
841
842   vat_json_init_object (&node);
843   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
844   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
845
846   vat_json_print (vam->ofp, &node);
847   vat_json_free (&node);
848
849   vam->retval = ntohl (mp->retval);
850   vam->result_ready = 1;
851 }
852
853 static void vl_api_create_subif_reply_t_handler
854   (vl_api_create_subif_reply_t * mp)
855 {
856   vat_main_t *vam = &vat_main;
857   i32 retval = ntohl (mp->retval);
858
859   vam->retval = retval;
860   vam->regenerate_interface_table = 1;
861   vam->sw_if_index = ntohl (mp->sw_if_index);
862   vam->result_ready = 1;
863 }
864
865 static void vl_api_create_subif_reply_t_handler_json
866   (vl_api_create_subif_reply_t * mp)
867 {
868   vat_main_t *vam = &vat_main;
869   vat_json_node_t node;
870
871   vat_json_init_object (&node);
872   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
873   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
874
875   vat_json_print (vam->ofp, &node);
876   vat_json_free (&node);
877
878   vam->retval = ntohl (mp->retval);
879   vam->result_ready = 1;
880 }
881
882 static void vl_api_interface_name_renumber_reply_t_handler
883   (vl_api_interface_name_renumber_reply_t * mp)
884 {
885   vat_main_t *vam = &vat_main;
886   i32 retval = ntohl (mp->retval);
887
888   vam->retval = retval;
889   vam->regenerate_interface_table = 1;
890   vam->result_ready = 1;
891 }
892
893 static void vl_api_interface_name_renumber_reply_t_handler_json
894   (vl_api_interface_name_renumber_reply_t * mp)
895 {
896   vat_main_t *vam = &vat_main;
897   vat_json_node_t node;
898
899   vat_json_init_object (&node);
900   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
901
902   vat_json_print (vam->ofp, &node);
903   vat_json_free (&node);
904
905   vam->retval = ntohl (mp->retval);
906   vam->result_ready = 1;
907 }
908
909 /*
910  * Special-case: build the interface table, maintain
911  * the next loopback sw_if_index vbl.
912  */
913 static void vl_api_sw_interface_details_t_handler
914   (vl_api_sw_interface_details_t * mp)
915 {
916   vat_main_t *vam = &vat_main;
917   u8 *s = format (0, "%s%c", mp->interface_name, 0);
918
919   hash_set_mem (vam->sw_if_index_by_interface_name, s,
920                 ntohl (mp->sw_if_index));
921
922   /* In sub interface case, fill the sub interface table entry */
923   if (mp->sw_if_index != mp->sup_sw_if_index)
924     {
925       sw_interface_subif_t *sub = NULL;
926
927       vec_add2 (vam->sw_if_subif_table, sub, 1);
928
929       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
930       strncpy ((char *) sub->interface_name, (char *) s,
931                vec_len (sub->interface_name));
932       sub->sw_if_index = ntohl (mp->sw_if_index);
933       sub->sub_id = ntohl (mp->sub_id);
934
935       sub->sub_dot1ad = mp->sub_dot1ad;
936       sub->sub_number_of_tags = mp->sub_number_of_tags;
937       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
938       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
939       sub->sub_exact_match = mp->sub_exact_match;
940       sub->sub_default = mp->sub_default;
941       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
942       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
943
944       /* vlan tag rewrite */
945       sub->vtr_op = ntohl (mp->vtr_op);
946       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
947       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
948       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
949     }
950 }
951
952 static void vl_api_sw_interface_details_t_handler_json
953   (vl_api_sw_interface_details_t * mp)
954 {
955   vat_main_t *vam = &vat_main;
956   vat_json_node_t *node = NULL;
957
958   if (VAT_JSON_ARRAY != vam->json_tree.type)
959     {
960       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
961       vat_json_init_array (&vam->json_tree);
962     }
963   node = vat_json_array_add (&vam->json_tree);
964
965   vat_json_init_object (node);
966   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
967   vat_json_object_add_uint (node, "sup_sw_if_index",
968                             ntohl (mp->sup_sw_if_index));
969   vat_json_object_add_uint (node, "l2_address_length",
970                             ntohl (mp->l2_address_length));
971   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
972                              sizeof (mp->l2_address));
973   vat_json_object_add_string_copy (node, "interface_name",
974                                    mp->interface_name);
975   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
976   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
977   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
978   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
979   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
980   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
981   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
982   vat_json_object_add_uint (node, "sub_number_of_tags",
983                             mp->sub_number_of_tags);
984   vat_json_object_add_uint (node, "sub_outer_vlan_id",
985                             ntohs (mp->sub_outer_vlan_id));
986   vat_json_object_add_uint (node, "sub_inner_vlan_id",
987                             ntohs (mp->sub_inner_vlan_id));
988   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
989   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
990   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
991                             mp->sub_outer_vlan_id_any);
992   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
993                             mp->sub_inner_vlan_id_any);
994   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
995   vat_json_object_add_uint (node, "vtr_push_dot1q",
996                             ntohl (mp->vtr_push_dot1q));
997   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
998   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
999   if (mp->sub_dot1ah)
1000     {
1001       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1002                                        format (0, "%U",
1003                                                format_ethernet_address,
1004                                                &mp->b_dmac));
1005       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1006                                        format (0, "%U",
1007                                                format_ethernet_address,
1008                                                &mp->b_smac));
1009       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1010       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1011     }
1012 }
1013
1014 #if VPP_API_TEST_BUILTIN == 0
1015 static void vl_api_sw_interface_set_flags_t_handler
1016   (vl_api_sw_interface_set_flags_t * mp)
1017 {
1018   vat_main_t *vam = &vat_main;
1019   if (vam->interface_event_display)
1020     errmsg ("interface flags: sw_if_index %d %s %s",
1021             ntohl (mp->sw_if_index),
1022             mp->admin_up_down ? "admin-up" : "admin-down",
1023             mp->link_up_down ? "link-up" : "link-down");
1024 }
1025 #endif
1026
1027 static void vl_api_sw_interface_set_flags_t_handler_json
1028   (vl_api_sw_interface_set_flags_t * mp)
1029 {
1030   /* JSON output not supported */
1031 }
1032
1033 static void
1034 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1035 {
1036   vat_main_t *vam = &vat_main;
1037   i32 retval = ntohl (mp->retval);
1038
1039   vam->retval = retval;
1040   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1041   vam->result_ready = 1;
1042 }
1043
1044 static void
1045 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1046 {
1047   vat_main_t *vam = &vat_main;
1048   vat_json_node_t node;
1049   api_main_t *am = &api_main;
1050   void *oldheap;
1051   u8 *reply;
1052
1053   vat_json_init_object (&node);
1054   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1055   vat_json_object_add_uint (&node, "reply_in_shmem",
1056                             ntohl (mp->reply_in_shmem));
1057   /* Toss the shared-memory original... */
1058   pthread_mutex_lock (&am->vlib_rp->mutex);
1059   oldheap = svm_push_data_heap (am->vlib_rp);
1060
1061   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1062   vec_free (reply);
1063
1064   svm_pop_heap (oldheap);
1065   pthread_mutex_unlock (&am->vlib_rp->mutex);
1066
1067   vat_json_print (vam->ofp, &node);
1068   vat_json_free (&node);
1069
1070   vam->retval = ntohl (mp->retval);
1071   vam->result_ready = 1;
1072 }
1073
1074 static void
1075 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1076 {
1077   vat_main_t *vam = &vat_main;
1078   i32 retval = ntohl (mp->retval);
1079
1080   vam->retval = retval;
1081   vam->cmd_reply = mp->reply;
1082   vam->result_ready = 1;
1083 }
1084
1085 static void
1086 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1087 {
1088   vat_main_t *vam = &vat_main;
1089   vat_json_node_t node;
1090
1091   vat_json_init_object (&node);
1092   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1093   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1094
1095   vat_json_print (vam->ofp, &node);
1096   vat_json_free (&node);
1097
1098   vam->retval = ntohl (mp->retval);
1099   vam->result_ready = 1;
1100 }
1101
1102 static void vl_api_classify_add_del_table_reply_t_handler
1103   (vl_api_classify_add_del_table_reply_t * mp)
1104 {
1105   vat_main_t *vam = &vat_main;
1106   i32 retval = ntohl (mp->retval);
1107   if (vam->async_mode)
1108     {
1109       vam->async_errors += (retval < 0);
1110     }
1111   else
1112     {
1113       vam->retval = retval;
1114       if (retval == 0 &&
1115           ((mp->new_table_index != 0xFFFFFFFF) ||
1116            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1117            (mp->match_n_vectors != 0xFFFFFFFF)))
1118         /*
1119          * Note: this is just barely thread-safe, depends on
1120          * the main thread spinning waiting for an answer...
1121          */
1122         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1123                 ntohl (mp->new_table_index),
1124                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1125       vam->result_ready = 1;
1126     }
1127 }
1128
1129 static void vl_api_classify_add_del_table_reply_t_handler_json
1130   (vl_api_classify_add_del_table_reply_t * mp)
1131 {
1132   vat_main_t *vam = &vat_main;
1133   vat_json_node_t node;
1134
1135   vat_json_init_object (&node);
1136   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1137   vat_json_object_add_uint (&node, "new_table_index",
1138                             ntohl (mp->new_table_index));
1139   vat_json_object_add_uint (&node, "skip_n_vectors",
1140                             ntohl (mp->skip_n_vectors));
1141   vat_json_object_add_uint (&node, "match_n_vectors",
1142                             ntohl (mp->match_n_vectors));
1143
1144   vat_json_print (vam->ofp, &node);
1145   vat_json_free (&node);
1146
1147   vam->retval = ntohl (mp->retval);
1148   vam->result_ready = 1;
1149 }
1150
1151 static void vl_api_get_node_index_reply_t_handler
1152   (vl_api_get_node_index_reply_t * mp)
1153 {
1154   vat_main_t *vam = &vat_main;
1155   i32 retval = ntohl (mp->retval);
1156   if (vam->async_mode)
1157     {
1158       vam->async_errors += (retval < 0);
1159     }
1160   else
1161     {
1162       vam->retval = retval;
1163       if (retval == 0)
1164         errmsg ("node index %d", ntohl (mp->node_index));
1165       vam->result_ready = 1;
1166     }
1167 }
1168
1169 static void vl_api_get_node_index_reply_t_handler_json
1170   (vl_api_get_node_index_reply_t * mp)
1171 {
1172   vat_main_t *vam = &vat_main;
1173   vat_json_node_t node;
1174
1175   vat_json_init_object (&node);
1176   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1177   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1178
1179   vat_json_print (vam->ofp, &node);
1180   vat_json_free (&node);
1181
1182   vam->retval = ntohl (mp->retval);
1183   vam->result_ready = 1;
1184 }
1185
1186 static void vl_api_get_next_index_reply_t_handler
1187   (vl_api_get_next_index_reply_t * mp)
1188 {
1189   vat_main_t *vam = &vat_main;
1190   i32 retval = ntohl (mp->retval);
1191   if (vam->async_mode)
1192     {
1193       vam->async_errors += (retval < 0);
1194     }
1195   else
1196     {
1197       vam->retval = retval;
1198       if (retval == 0)
1199         errmsg ("next node index %d", ntohl (mp->next_index));
1200       vam->result_ready = 1;
1201     }
1202 }
1203
1204 static void vl_api_get_next_index_reply_t_handler_json
1205   (vl_api_get_next_index_reply_t * mp)
1206 {
1207   vat_main_t *vam = &vat_main;
1208   vat_json_node_t node;
1209
1210   vat_json_init_object (&node);
1211   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1212   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1213
1214   vat_json_print (vam->ofp, &node);
1215   vat_json_free (&node);
1216
1217   vam->retval = ntohl (mp->retval);
1218   vam->result_ready = 1;
1219 }
1220
1221 static void vl_api_add_node_next_reply_t_handler
1222   (vl_api_add_node_next_reply_t * mp)
1223 {
1224   vat_main_t *vam = &vat_main;
1225   i32 retval = ntohl (mp->retval);
1226   if (vam->async_mode)
1227     {
1228       vam->async_errors += (retval < 0);
1229     }
1230   else
1231     {
1232       vam->retval = retval;
1233       if (retval == 0)
1234         errmsg ("next index %d", ntohl (mp->next_index));
1235       vam->result_ready = 1;
1236     }
1237 }
1238
1239 static void vl_api_add_node_next_reply_t_handler_json
1240   (vl_api_add_node_next_reply_t * mp)
1241 {
1242   vat_main_t *vam = &vat_main;
1243   vat_json_node_t node;
1244
1245   vat_json_init_object (&node);
1246   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1247   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1248
1249   vat_json_print (vam->ofp, &node);
1250   vat_json_free (&node);
1251
1252   vam->retval = ntohl (mp->retval);
1253   vam->result_ready = 1;
1254 }
1255
1256 static void vl_api_show_version_reply_t_handler
1257   (vl_api_show_version_reply_t * mp)
1258 {
1259   vat_main_t *vam = &vat_main;
1260   i32 retval = ntohl (mp->retval);
1261
1262   if (retval >= 0)
1263     {
1264       errmsg ("        program: %s", mp->program);
1265       errmsg ("        version: %s", mp->version);
1266       errmsg ("     build date: %s", mp->build_date);
1267       errmsg ("build directory: %s", mp->build_directory);
1268     }
1269   vam->retval = retval;
1270   vam->result_ready = 1;
1271 }
1272
1273 static void vl_api_show_version_reply_t_handler_json
1274   (vl_api_show_version_reply_t * mp)
1275 {
1276   vat_main_t *vam = &vat_main;
1277   vat_json_node_t node;
1278
1279   vat_json_init_object (&node);
1280   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1281   vat_json_object_add_string_copy (&node, "program", mp->program);
1282   vat_json_object_add_string_copy (&node, "version", mp->version);
1283   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1284   vat_json_object_add_string_copy (&node, "build_directory",
1285                                    mp->build_directory);
1286
1287   vat_json_print (vam->ofp, &node);
1288   vat_json_free (&node);
1289
1290   vam->retval = ntohl (mp->retval);
1291   vam->result_ready = 1;
1292 }
1293
1294 static void
1295 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1296 {
1297   u32 sw_if_index = ntohl (mp->sw_if_index);
1298   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1299           mp->mac_ip ? "mac/ip binding" : "address resolution",
1300           ntohl (mp->pid), format_ip4_address, &mp->address,
1301           format_ethernet_address, mp->new_mac, sw_if_index);
1302 }
1303
1304 static void
1305 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1306 {
1307   /* JSON output not supported */
1308 }
1309
1310 static void
1311 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1312 {
1313   u32 sw_if_index = ntohl (mp->sw_if_index);
1314   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1315           mp->mac_ip ? "mac/ip binding" : "address resolution",
1316           ntohl (mp->pid), format_ip6_address, mp->address,
1317           format_ethernet_address, mp->new_mac, sw_if_index);
1318 }
1319
1320 static void
1321 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1322 {
1323   /* JSON output not supported */
1324 }
1325
1326 /*
1327  * Special-case: build the bridge domain table, maintain
1328  * the next bd id vbl.
1329  */
1330 static void vl_api_bridge_domain_details_t_handler
1331   (vl_api_bridge_domain_details_t * mp)
1332 {
1333   vat_main_t *vam = &vat_main;
1334   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1335
1336   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1337          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1338
1339   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1340          ntohl (mp->bd_id), mp->learn, mp->forward,
1341          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1342
1343   if (n_sw_ifs)
1344     print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG", "Interface Name");
1345 }
1346
1347 static void vl_api_bridge_domain_details_t_handler_json
1348   (vl_api_bridge_domain_details_t * mp)
1349 {
1350   vat_main_t *vam = &vat_main;
1351   vat_json_node_t *node, *array = NULL;
1352
1353   if (VAT_JSON_ARRAY != vam->json_tree.type)
1354     {
1355       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1356       vat_json_init_array (&vam->json_tree);
1357     }
1358   node = vat_json_array_add (&vam->json_tree);
1359
1360   vat_json_init_object (node);
1361   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1362   vat_json_object_add_uint (node, "flood", mp->flood);
1363   vat_json_object_add_uint (node, "forward", mp->forward);
1364   vat_json_object_add_uint (node, "learn", mp->learn);
1365   vat_json_object_add_uint (node, "bvi_sw_if_index",
1366                             ntohl (mp->bvi_sw_if_index));
1367   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1368   array = vat_json_object_add (node, "sw_if");
1369   vat_json_init_array (array);
1370 }
1371
1372 /*
1373  * Special-case: build the bridge domain sw if table.
1374  */
1375 static void vl_api_bridge_domain_sw_if_details_t_handler
1376   (vl_api_bridge_domain_sw_if_details_t * mp)
1377 {
1378   vat_main_t *vam = &vat_main;
1379   hash_pair_t *p;
1380   u8 *sw_if_name = 0;
1381   u32 sw_if_index;
1382
1383   sw_if_index = ntohl (mp->sw_if_index);
1384   /* *INDENT-OFF* */
1385   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1386   ({
1387     if ((u32) p->value[0] == sw_if_index)
1388       {
1389         sw_if_name = (u8 *)(p->key);
1390         break;
1391       }
1392   }));
1393   /* *INDENT-ON* */
1394
1395   print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1396          mp->shg, sw_if_name ? (char *) sw_if_name :
1397          "sw_if_index not found!");
1398 }
1399
1400 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1401   (vl_api_bridge_domain_sw_if_details_t * mp)
1402 {
1403   vat_main_t *vam = &vat_main;
1404   vat_json_node_t *node = NULL;
1405   uword last_index = 0;
1406
1407   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1408   ASSERT (vec_len (vam->json_tree.array) >= 1);
1409   last_index = vec_len (vam->json_tree.array) - 1;
1410   node = &vam->json_tree.array[last_index];
1411   node = vat_json_object_get_element (node, "sw_if");
1412   ASSERT (NULL != node);
1413   node = vat_json_array_add (node);
1414
1415   vat_json_init_object (node);
1416   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1417   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1418   vat_json_object_add_uint (node, "shg", mp->shg);
1419 }
1420
1421 static void vl_api_control_ping_reply_t_handler
1422   (vl_api_control_ping_reply_t * mp)
1423 {
1424   vat_main_t *vam = &vat_main;
1425   i32 retval = ntohl (mp->retval);
1426   if (vam->async_mode)
1427     {
1428       vam->async_errors += (retval < 0);
1429     }
1430   else
1431     {
1432       vam->retval = retval;
1433       vam->result_ready = 1;
1434     }
1435 }
1436
1437 static void vl_api_control_ping_reply_t_handler_json
1438   (vl_api_control_ping_reply_t * mp)
1439 {
1440   vat_main_t *vam = &vat_main;
1441   i32 retval = ntohl (mp->retval);
1442
1443   if (VAT_JSON_NONE != vam->json_tree.type)
1444     {
1445       vat_json_print (vam->ofp, &vam->json_tree);
1446       vat_json_free (&vam->json_tree);
1447       vam->json_tree.type = VAT_JSON_NONE;
1448     }
1449   else
1450     {
1451       /* just print [] */
1452       vat_json_init_array (&vam->json_tree);
1453       vat_json_print (vam->ofp, &vam->json_tree);
1454       vam->json_tree.type = VAT_JSON_NONE;
1455     }
1456
1457   vam->retval = retval;
1458   vam->result_ready = 1;
1459 }
1460
1461 static void
1462   vl_api_bridge_domain_set_mac_age_reply_t_handler
1463   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1464 {
1465   vat_main_t *vam = &vat_main;
1466   i32 retval = ntohl (mp->retval);
1467   if (vam->async_mode)
1468     {
1469       vam->async_errors += (retval < 0);
1470     }
1471   else
1472     {
1473       vam->retval = retval;
1474       vam->result_ready = 1;
1475     }
1476 }
1477
1478 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1479   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1480 {
1481   vat_main_t *vam = &vat_main;
1482   vat_json_node_t node;
1483
1484   vat_json_init_object (&node);
1485   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1486
1487   vat_json_print (vam->ofp, &node);
1488   vat_json_free (&node);
1489
1490   vam->retval = ntohl (mp->retval);
1491   vam->result_ready = 1;
1492 }
1493
1494 static void
1495 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1496 {
1497   vat_main_t *vam = &vat_main;
1498   i32 retval = ntohl (mp->retval);
1499   if (vam->async_mode)
1500     {
1501       vam->async_errors += (retval < 0);
1502     }
1503   else
1504     {
1505       vam->retval = retval;
1506       vam->result_ready = 1;
1507     }
1508 }
1509
1510 static void vl_api_l2_flags_reply_t_handler_json
1511   (vl_api_l2_flags_reply_t * mp)
1512 {
1513   vat_main_t *vam = &vat_main;
1514   vat_json_node_t node;
1515
1516   vat_json_init_object (&node);
1517   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1518   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1519                             ntohl (mp->resulting_feature_bitmap));
1520
1521   vat_json_print (vam->ofp, &node);
1522   vat_json_free (&node);
1523
1524   vam->retval = ntohl (mp->retval);
1525   vam->result_ready = 1;
1526 }
1527
1528 static void vl_api_bridge_flags_reply_t_handler
1529   (vl_api_bridge_flags_reply_t * mp)
1530 {
1531   vat_main_t *vam = &vat_main;
1532   i32 retval = ntohl (mp->retval);
1533   if (vam->async_mode)
1534     {
1535       vam->async_errors += (retval < 0);
1536     }
1537   else
1538     {
1539       vam->retval = retval;
1540       vam->result_ready = 1;
1541     }
1542 }
1543
1544 static void vl_api_bridge_flags_reply_t_handler_json
1545   (vl_api_bridge_flags_reply_t * mp)
1546 {
1547   vat_main_t *vam = &vat_main;
1548   vat_json_node_t node;
1549
1550   vat_json_init_object (&node);
1551   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1552   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1553                             ntohl (mp->resulting_feature_bitmap));
1554
1555   vat_json_print (vam->ofp, &node);
1556   vat_json_free (&node);
1557
1558   vam->retval = ntohl (mp->retval);
1559   vam->result_ready = 1;
1560 }
1561
1562 static void vl_api_tap_connect_reply_t_handler
1563   (vl_api_tap_connect_reply_t * mp)
1564 {
1565   vat_main_t *vam = &vat_main;
1566   i32 retval = ntohl (mp->retval);
1567   if (vam->async_mode)
1568     {
1569       vam->async_errors += (retval < 0);
1570     }
1571   else
1572     {
1573       vam->retval = retval;
1574       vam->sw_if_index = ntohl (mp->sw_if_index);
1575       vam->result_ready = 1;
1576     }
1577
1578 }
1579
1580 static void vl_api_tap_connect_reply_t_handler_json
1581   (vl_api_tap_connect_reply_t * mp)
1582 {
1583   vat_main_t *vam = &vat_main;
1584   vat_json_node_t node;
1585
1586   vat_json_init_object (&node);
1587   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1588   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1589
1590   vat_json_print (vam->ofp, &node);
1591   vat_json_free (&node);
1592
1593   vam->retval = ntohl (mp->retval);
1594   vam->result_ready = 1;
1595
1596 }
1597
1598 static void
1599 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1600 {
1601   vat_main_t *vam = &vat_main;
1602   i32 retval = ntohl (mp->retval);
1603   if (vam->async_mode)
1604     {
1605       vam->async_errors += (retval < 0);
1606     }
1607   else
1608     {
1609       vam->retval = retval;
1610       vam->sw_if_index = ntohl (mp->sw_if_index);
1611       vam->result_ready = 1;
1612     }
1613 }
1614
1615 static void vl_api_tap_modify_reply_t_handler_json
1616   (vl_api_tap_modify_reply_t * mp)
1617 {
1618   vat_main_t *vam = &vat_main;
1619   vat_json_node_t node;
1620
1621   vat_json_init_object (&node);
1622   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1623   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1624
1625   vat_json_print (vam->ofp, &node);
1626   vat_json_free (&node);
1627
1628   vam->retval = ntohl (mp->retval);
1629   vam->result_ready = 1;
1630 }
1631
1632 static void
1633 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1634 {
1635   vat_main_t *vam = &vat_main;
1636   i32 retval = ntohl (mp->retval);
1637   if (vam->async_mode)
1638     {
1639       vam->async_errors += (retval < 0);
1640     }
1641   else
1642     {
1643       vam->retval = retval;
1644       vam->result_ready = 1;
1645     }
1646 }
1647
1648 static void vl_api_tap_delete_reply_t_handler_json
1649   (vl_api_tap_delete_reply_t * mp)
1650 {
1651   vat_main_t *vam = &vat_main;
1652   vat_json_node_t node;
1653
1654   vat_json_init_object (&node);
1655   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1656
1657   vat_json_print (vam->ofp, &node);
1658   vat_json_free (&node);
1659
1660   vam->retval = ntohl (mp->retval);
1661   vam->result_ready = 1;
1662 }
1663
1664 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1665   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1666 {
1667   vat_main_t *vam = &vat_main;
1668   i32 retval = ntohl (mp->retval);
1669   if (vam->async_mode)
1670     {
1671       vam->async_errors += (retval < 0);
1672     }
1673   else
1674     {
1675       vam->retval = retval;
1676       vam->result_ready = 1;
1677     }
1678 }
1679
1680 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1681   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1682 {
1683   vat_main_t *vam = &vat_main;
1684   vat_json_node_t node;
1685
1686   vat_json_init_object (&node);
1687   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1688   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1689                             ntohl (mp->sw_if_index));
1690
1691   vat_json_print (vam->ofp, &node);
1692   vat_json_free (&node);
1693
1694   vam->retval = ntohl (mp->retval);
1695   vam->result_ready = 1;
1696 }
1697
1698 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1699   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1700 {
1701   vat_main_t *vam = &vat_main;
1702   i32 retval = ntohl (mp->retval);
1703   if (vam->async_mode)
1704     {
1705       vam->async_errors += (retval < 0);
1706     }
1707   else
1708     {
1709       vam->retval = retval;
1710       vam->sw_if_index = ntohl (mp->sw_if_index);
1711       vam->result_ready = 1;
1712     }
1713 }
1714
1715 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1716   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1717 {
1718   vat_main_t *vam = &vat_main;
1719   vat_json_node_t node;
1720
1721   vat_json_init_object (&node);
1722   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1723   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1724
1725   vat_json_print (vam->ofp, &node);
1726   vat_json_free (&node);
1727
1728   vam->retval = ntohl (mp->retval);
1729   vam->result_ready = 1;
1730 }
1731
1732
1733 static void vl_api_one_add_del_locator_set_reply_t_handler
1734   (vl_api_one_add_del_locator_set_reply_t * mp)
1735 {
1736   vat_main_t *vam = &vat_main;
1737   i32 retval = ntohl (mp->retval);
1738   if (vam->async_mode)
1739     {
1740       vam->async_errors += (retval < 0);
1741     }
1742   else
1743     {
1744       vam->retval = retval;
1745       vam->result_ready = 1;
1746     }
1747 }
1748
1749 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1750   (vl_api_one_add_del_locator_set_reply_t * mp)
1751 {
1752   vat_main_t *vam = &vat_main;
1753   vat_json_node_t node;
1754
1755   vat_json_init_object (&node);
1756   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1757   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1758
1759   vat_json_print (vam->ofp, &node);
1760   vat_json_free (&node);
1761
1762   vam->retval = ntohl (mp->retval);
1763   vam->result_ready = 1;
1764 }
1765
1766 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1767   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1768 {
1769   vat_main_t *vam = &vat_main;
1770   i32 retval = ntohl (mp->retval);
1771   if (vam->async_mode)
1772     {
1773       vam->async_errors += (retval < 0);
1774     }
1775   else
1776     {
1777       vam->retval = retval;
1778       vam->sw_if_index = ntohl (mp->sw_if_index);
1779       vam->result_ready = 1;
1780     }
1781 }
1782
1783 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1784   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1785 {
1786   vat_main_t *vam = &vat_main;
1787   vat_json_node_t node;
1788
1789   vat_json_init_object (&node);
1790   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1791   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1792
1793   vat_json_print (vam->ofp, &node);
1794   vat_json_free (&node);
1795
1796   vam->retval = ntohl (mp->retval);
1797   vam->result_ready = 1;
1798 }
1799
1800 static void vl_api_gre_add_del_tunnel_reply_t_handler
1801   (vl_api_gre_add_del_tunnel_reply_t * mp)
1802 {
1803   vat_main_t *vam = &vat_main;
1804   i32 retval = ntohl (mp->retval);
1805   if (vam->async_mode)
1806     {
1807       vam->async_errors += (retval < 0);
1808     }
1809   else
1810     {
1811       vam->retval = retval;
1812       vam->sw_if_index = ntohl (mp->sw_if_index);
1813       vam->result_ready = 1;
1814     }
1815 }
1816
1817 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1818   (vl_api_gre_add_del_tunnel_reply_t * mp)
1819 {
1820   vat_main_t *vam = &vat_main;
1821   vat_json_node_t node;
1822
1823   vat_json_init_object (&node);
1824   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1825   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1826
1827   vat_json_print (vam->ofp, &node);
1828   vat_json_free (&node);
1829
1830   vam->retval = ntohl (mp->retval);
1831   vam->result_ready = 1;
1832 }
1833
1834 static void vl_api_create_vhost_user_if_reply_t_handler
1835   (vl_api_create_vhost_user_if_reply_t * mp)
1836 {
1837   vat_main_t *vam = &vat_main;
1838   i32 retval = ntohl (mp->retval);
1839   if (vam->async_mode)
1840     {
1841       vam->async_errors += (retval < 0);
1842     }
1843   else
1844     {
1845       vam->retval = retval;
1846       vam->sw_if_index = ntohl (mp->sw_if_index);
1847       vam->result_ready = 1;
1848     }
1849 }
1850
1851 static void vl_api_create_vhost_user_if_reply_t_handler_json
1852   (vl_api_create_vhost_user_if_reply_t * mp)
1853 {
1854   vat_main_t *vam = &vat_main;
1855   vat_json_node_t node;
1856
1857   vat_json_init_object (&node);
1858   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1859   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1860
1861   vat_json_print (vam->ofp, &node);
1862   vat_json_free (&node);
1863
1864   vam->retval = ntohl (mp->retval);
1865   vam->result_ready = 1;
1866 }
1867
1868 static void vl_api_ip_address_details_t_handler
1869   (vl_api_ip_address_details_t * mp)
1870 {
1871   vat_main_t *vam = &vat_main;
1872   static ip_address_details_t empty_ip_address_details = { {0} };
1873   ip_address_details_t *address = NULL;
1874   ip_details_t *current_ip_details = NULL;
1875   ip_details_t *details = NULL;
1876
1877   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1878
1879   if (!details || vam->current_sw_if_index >= vec_len (details)
1880       || !details[vam->current_sw_if_index].present)
1881     {
1882       errmsg ("ip address details arrived but not stored");
1883       errmsg ("ip_dump should be called first");
1884       return;
1885     }
1886
1887   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1888
1889 #define addresses (current_ip_details->addr)
1890
1891   vec_validate_init_empty (addresses, vec_len (addresses),
1892                            empty_ip_address_details);
1893
1894   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1895
1896   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1897   address->prefix_length = mp->prefix_length;
1898 #undef addresses
1899 }
1900
1901 static void vl_api_ip_address_details_t_handler_json
1902   (vl_api_ip_address_details_t * mp)
1903 {
1904   vat_main_t *vam = &vat_main;
1905   vat_json_node_t *node = NULL;
1906   struct in6_addr ip6;
1907   struct in_addr ip4;
1908
1909   if (VAT_JSON_ARRAY != vam->json_tree.type)
1910     {
1911       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1912       vat_json_init_array (&vam->json_tree);
1913     }
1914   node = vat_json_array_add (&vam->json_tree);
1915
1916   vat_json_init_object (node);
1917   if (vam->is_ipv6)
1918     {
1919       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1920       vat_json_object_add_ip6 (node, "ip", ip6);
1921     }
1922   else
1923     {
1924       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1925       vat_json_object_add_ip4 (node, "ip", ip4);
1926     }
1927   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1928 }
1929
1930 static void
1931 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1932 {
1933   vat_main_t *vam = &vat_main;
1934   static ip_details_t empty_ip_details = { 0 };
1935   ip_details_t *ip = NULL;
1936   u32 sw_if_index = ~0;
1937
1938   sw_if_index = ntohl (mp->sw_if_index);
1939
1940   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1941                            sw_if_index, empty_ip_details);
1942
1943   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1944                          sw_if_index);
1945
1946   ip->present = 1;
1947 }
1948
1949 static void
1950 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1951 {
1952   vat_main_t *vam = &vat_main;
1953
1954   if (VAT_JSON_ARRAY != vam->json_tree.type)
1955     {
1956       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1957       vat_json_init_array (&vam->json_tree);
1958     }
1959   vat_json_array_add_uint (&vam->json_tree,
1960                            clib_net_to_host_u32 (mp->sw_if_index));
1961 }
1962
1963 static void vl_api_map_domain_details_t_handler_json
1964   (vl_api_map_domain_details_t * mp)
1965 {
1966   vat_json_node_t *node = NULL;
1967   vat_main_t *vam = &vat_main;
1968   struct in6_addr ip6;
1969   struct in_addr ip4;
1970
1971   if (VAT_JSON_ARRAY != vam->json_tree.type)
1972     {
1973       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1974       vat_json_init_array (&vam->json_tree);
1975     }
1976
1977   node = vat_json_array_add (&vam->json_tree);
1978   vat_json_init_object (node);
1979
1980   vat_json_object_add_uint (node, "domain_index",
1981                             clib_net_to_host_u32 (mp->domain_index));
1982   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1983   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1984   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1985   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1986   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1987   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1988   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1989   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1990   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1991   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1992   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1993   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1994   vat_json_object_add_uint (node, "flags", mp->flags);
1995   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1996   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1997 }
1998
1999 static void vl_api_map_domain_details_t_handler
2000   (vl_api_map_domain_details_t * mp)
2001 {
2002   vat_main_t *vam = &vat_main;
2003
2004   if (mp->is_translation)
2005     {
2006       print (vam->ofp,
2007              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2008              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2009              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2010              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2011              clib_net_to_host_u32 (mp->domain_index));
2012     }
2013   else
2014     {
2015       print (vam->ofp,
2016              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2017              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2018              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2019              format_ip6_address, mp->ip6_src,
2020              clib_net_to_host_u32 (mp->domain_index));
2021     }
2022   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2023          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2024          mp->is_translation ? "map-t" : "");
2025 }
2026
2027 static void vl_api_map_rule_details_t_handler_json
2028   (vl_api_map_rule_details_t * mp)
2029 {
2030   struct in6_addr ip6;
2031   vat_json_node_t *node = NULL;
2032   vat_main_t *vam = &vat_main;
2033
2034   if (VAT_JSON_ARRAY != vam->json_tree.type)
2035     {
2036       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2037       vat_json_init_array (&vam->json_tree);
2038     }
2039
2040   node = vat_json_array_add (&vam->json_tree);
2041   vat_json_init_object (node);
2042
2043   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2044   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2045   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2046 }
2047
2048 static void
2049 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2050 {
2051   vat_main_t *vam = &vat_main;
2052   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2053          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2054 }
2055
2056 static void
2057 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2058 {
2059   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2060           "router_addr %U host_mac %U",
2061           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2062           format_ip4_address, &mp->host_address,
2063           format_ip4_address, &mp->router_address,
2064           format_ethernet_address, mp->host_mac);
2065 }
2066
2067 static void vl_api_dhcp_compl_event_t_handler_json
2068   (vl_api_dhcp_compl_event_t * mp)
2069 {
2070   /* JSON output not supported */
2071 }
2072
2073 static void
2074 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2075                               u32 counter)
2076 {
2077   vat_main_t *vam = &vat_main;
2078   static u64 default_counter = 0;
2079
2080   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2081                            NULL);
2082   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2083                            sw_if_index, default_counter);
2084   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2085 }
2086
2087 static void
2088 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2089                                 interface_counter_t counter)
2090 {
2091   vat_main_t *vam = &vat_main;
2092   static interface_counter_t default_counter = { 0, };
2093
2094   vec_validate_init_empty (vam->combined_interface_counters,
2095                            vnet_counter_type, NULL);
2096   vec_validate_init_empty (vam->combined_interface_counters
2097                            [vnet_counter_type], sw_if_index, default_counter);
2098   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2099 }
2100
2101 static void vl_api_vnet_interface_simple_counters_t_handler
2102   (vl_api_vnet_interface_simple_counters_t * mp)
2103 {
2104   /* not supported */
2105 }
2106
2107 static void vl_api_vnet_interface_combined_counters_t_handler
2108   (vl_api_vnet_interface_combined_counters_t * mp)
2109 {
2110   /* not supported */
2111 }
2112
2113 static void vl_api_vnet_interface_simple_counters_t_handler_json
2114   (vl_api_vnet_interface_simple_counters_t * mp)
2115 {
2116   u64 *v_packets;
2117   u64 packets;
2118   u32 count;
2119   u32 first_sw_if_index;
2120   int i;
2121
2122   count = ntohl (mp->count);
2123   first_sw_if_index = ntohl (mp->first_sw_if_index);
2124
2125   v_packets = (u64 *) & mp->data;
2126   for (i = 0; i < count; i++)
2127     {
2128       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2129       set_simple_interface_counter (mp->vnet_counter_type,
2130                                     first_sw_if_index + i, packets);
2131       v_packets++;
2132     }
2133 }
2134
2135 static void vl_api_vnet_interface_combined_counters_t_handler_json
2136   (vl_api_vnet_interface_combined_counters_t * mp)
2137 {
2138   interface_counter_t counter;
2139   vlib_counter_t *v;
2140   u32 first_sw_if_index;
2141   int i;
2142   u32 count;
2143
2144   count = ntohl (mp->count);
2145   first_sw_if_index = ntohl (mp->first_sw_if_index);
2146
2147   v = (vlib_counter_t *) & mp->data;
2148   for (i = 0; i < count; i++)
2149     {
2150       counter.packets =
2151         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2152       counter.bytes =
2153         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2154       set_combined_interface_counter (mp->vnet_counter_type,
2155                                       first_sw_if_index + i, counter);
2156       v++;
2157     }
2158 }
2159
2160 static u32
2161 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2162 {
2163   vat_main_t *vam = &vat_main;
2164   u32 i;
2165
2166   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2167     {
2168       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2169         {
2170           return i;
2171         }
2172     }
2173   return ~0;
2174 }
2175
2176 static u32
2177 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2178 {
2179   vat_main_t *vam = &vat_main;
2180   u32 i;
2181
2182   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2183     {
2184       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2185         {
2186           return i;
2187         }
2188     }
2189   return ~0;
2190 }
2191
2192 static void vl_api_vnet_ip4_fib_counters_t_handler
2193   (vl_api_vnet_ip4_fib_counters_t * mp)
2194 {
2195   /* not supported */
2196 }
2197
2198 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2199   (vl_api_vnet_ip4_fib_counters_t * mp)
2200 {
2201   vat_main_t *vam = &vat_main;
2202   vl_api_ip4_fib_counter_t *v;
2203   ip4_fib_counter_t *counter;
2204   struct in_addr ip4;
2205   u32 vrf_id;
2206   u32 vrf_index;
2207   u32 count;
2208   int i;
2209
2210   vrf_id = ntohl (mp->vrf_id);
2211   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2212   if (~0 == vrf_index)
2213     {
2214       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2215       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2216       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2217       vec_validate (vam->ip4_fib_counters, vrf_index);
2218       vam->ip4_fib_counters[vrf_index] = NULL;
2219     }
2220
2221   vec_free (vam->ip4_fib_counters[vrf_index]);
2222   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2223   count = ntohl (mp->count);
2224   for (i = 0; i < count; i++)
2225     {
2226       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2227       counter = &vam->ip4_fib_counters[vrf_index][i];
2228       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2229       counter->address = ip4;
2230       counter->address_length = v->address_length;
2231       counter->packets = clib_net_to_host_u64 (v->packets);
2232       counter->bytes = clib_net_to_host_u64 (v->bytes);
2233       v++;
2234     }
2235 }
2236
2237 static void vl_api_vnet_ip4_nbr_counters_t_handler
2238   (vl_api_vnet_ip4_nbr_counters_t * mp)
2239 {
2240   /* not supported */
2241 }
2242
2243 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2244   (vl_api_vnet_ip4_nbr_counters_t * mp)
2245 {
2246   vat_main_t *vam = &vat_main;
2247   vl_api_ip4_nbr_counter_t *v;
2248   ip4_nbr_counter_t *counter;
2249   u32 sw_if_index;
2250   u32 count;
2251   int i;
2252
2253   sw_if_index = ntohl (mp->sw_if_index);
2254   count = ntohl (mp->count);
2255   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2256
2257   if (mp->begin)
2258     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2259
2260   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2261   for (i = 0; i < count; i++)
2262     {
2263       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2264       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2265       counter->address.s_addr = v->address;
2266       counter->packets = clib_net_to_host_u64 (v->packets);
2267       counter->bytes = clib_net_to_host_u64 (v->bytes);
2268       counter->linkt = v->link_type;
2269       v++;
2270     }
2271 }
2272
2273 static void vl_api_vnet_ip6_fib_counters_t_handler
2274   (vl_api_vnet_ip6_fib_counters_t * mp)
2275 {
2276   /* not supported */
2277 }
2278
2279 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2280   (vl_api_vnet_ip6_fib_counters_t * mp)
2281 {
2282   vat_main_t *vam = &vat_main;
2283   vl_api_ip6_fib_counter_t *v;
2284   ip6_fib_counter_t *counter;
2285   struct in6_addr ip6;
2286   u32 vrf_id;
2287   u32 vrf_index;
2288   u32 count;
2289   int i;
2290
2291   vrf_id = ntohl (mp->vrf_id);
2292   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2293   if (~0 == vrf_index)
2294     {
2295       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2296       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2297       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2298       vec_validate (vam->ip6_fib_counters, vrf_index);
2299       vam->ip6_fib_counters[vrf_index] = NULL;
2300     }
2301
2302   vec_free (vam->ip6_fib_counters[vrf_index]);
2303   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2304   count = ntohl (mp->count);
2305   for (i = 0; i < count; i++)
2306     {
2307       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2308       counter = &vam->ip6_fib_counters[vrf_index][i];
2309       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2310       counter->address = ip6;
2311       counter->address_length = v->address_length;
2312       counter->packets = clib_net_to_host_u64 (v->packets);
2313       counter->bytes = clib_net_to_host_u64 (v->bytes);
2314       v++;
2315     }
2316 }
2317
2318 static void vl_api_vnet_ip6_nbr_counters_t_handler
2319   (vl_api_vnet_ip6_nbr_counters_t * mp)
2320 {
2321   /* not supported */
2322 }
2323
2324 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2325   (vl_api_vnet_ip6_nbr_counters_t * mp)
2326 {
2327   vat_main_t *vam = &vat_main;
2328   vl_api_ip6_nbr_counter_t *v;
2329   ip6_nbr_counter_t *counter;
2330   struct in6_addr ip6;
2331   u32 sw_if_index;
2332   u32 count;
2333   int i;
2334
2335   sw_if_index = ntohl (mp->sw_if_index);
2336   count = ntohl (mp->count);
2337   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2338
2339   if (mp->begin)
2340     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2341
2342   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2343   for (i = 0; i < count; i++)
2344     {
2345       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2346       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2347       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2348       counter->address = ip6;
2349       counter->packets = clib_net_to_host_u64 (v->packets);
2350       counter->bytes = clib_net_to_host_u64 (v->bytes);
2351       v++;
2352     }
2353 }
2354
2355 static void vl_api_get_first_msg_id_reply_t_handler
2356   (vl_api_get_first_msg_id_reply_t * mp)
2357 {
2358   vat_main_t *vam = &vat_main;
2359   i32 retval = ntohl (mp->retval);
2360
2361   if (vam->async_mode)
2362     {
2363       vam->async_errors += (retval < 0);
2364     }
2365   else
2366     {
2367       vam->retval = retval;
2368       vam->result_ready = 1;
2369     }
2370   if (retval >= 0)
2371     {
2372       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2373     }
2374 }
2375
2376 static void vl_api_get_first_msg_id_reply_t_handler_json
2377   (vl_api_get_first_msg_id_reply_t * mp)
2378 {
2379   vat_main_t *vam = &vat_main;
2380   vat_json_node_t node;
2381
2382   vat_json_init_object (&node);
2383   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2384   vat_json_object_add_uint (&node, "first_msg_id",
2385                             (uint) ntohs (mp->first_msg_id));
2386
2387   vat_json_print (vam->ofp, &node);
2388   vat_json_free (&node);
2389
2390   vam->retval = ntohl (mp->retval);
2391   vam->result_ready = 1;
2392 }
2393
2394 static void vl_api_get_node_graph_reply_t_handler
2395   (vl_api_get_node_graph_reply_t * mp)
2396 {
2397   vat_main_t *vam = &vat_main;
2398   api_main_t *am = &api_main;
2399   i32 retval = ntohl (mp->retval);
2400   u8 *pvt_copy, *reply;
2401   void *oldheap;
2402   vlib_node_t *node;
2403   int i;
2404
2405   if (vam->async_mode)
2406     {
2407       vam->async_errors += (retval < 0);
2408     }
2409   else
2410     {
2411       vam->retval = retval;
2412       vam->result_ready = 1;
2413     }
2414
2415   /* "Should never happen..." */
2416   if (retval != 0)
2417     return;
2418
2419   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2420   pvt_copy = vec_dup (reply);
2421
2422   /* Toss the shared-memory original... */
2423   pthread_mutex_lock (&am->vlib_rp->mutex);
2424   oldheap = svm_push_data_heap (am->vlib_rp);
2425
2426   vec_free (reply);
2427
2428   svm_pop_heap (oldheap);
2429   pthread_mutex_unlock (&am->vlib_rp->mutex);
2430
2431   if (vam->graph_nodes)
2432     {
2433       hash_free (vam->graph_node_index_by_name);
2434
2435       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2436         {
2437           node = vam->graph_nodes[i];
2438           vec_free (node->name);
2439           vec_free (node->next_nodes);
2440           vec_free (node);
2441         }
2442       vec_free (vam->graph_nodes);
2443     }
2444
2445   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2446   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2447   vec_free (pvt_copy);
2448
2449   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2450     {
2451       node = vam->graph_nodes[i];
2452       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2453     }
2454 }
2455
2456 static void vl_api_get_node_graph_reply_t_handler_json
2457   (vl_api_get_node_graph_reply_t * mp)
2458 {
2459   vat_main_t *vam = &vat_main;
2460   api_main_t *am = &api_main;
2461   void *oldheap;
2462   vat_json_node_t node;
2463   u8 *reply;
2464
2465   /* $$$$ make this real? */
2466   vat_json_init_object (&node);
2467   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2468   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2469
2470   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2471
2472   /* Toss the shared-memory original... */
2473   pthread_mutex_lock (&am->vlib_rp->mutex);
2474   oldheap = svm_push_data_heap (am->vlib_rp);
2475
2476   vec_free (reply);
2477
2478   svm_pop_heap (oldheap);
2479   pthread_mutex_unlock (&am->vlib_rp->mutex);
2480
2481   vat_json_print (vam->ofp, &node);
2482   vat_json_free (&node);
2483
2484   vam->retval = ntohl (mp->retval);
2485   vam->result_ready = 1;
2486 }
2487
2488 static void
2489 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2490 {
2491   vat_main_t *vam = &vat_main;
2492   u8 *s = 0;
2493
2494   if (mp->local)
2495     {
2496       s = format (s, "%=16d%=16d%=16d",
2497                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2498     }
2499   else
2500     {
2501       s = format (s, "%=16U%=16d%=16d",
2502                   mp->is_ipv6 ? format_ip6_address :
2503                   format_ip4_address,
2504                   mp->ip_address, mp->priority, mp->weight);
2505     }
2506
2507   print (vam->ofp, "%v", s);
2508   vec_free (s);
2509 }
2510
2511 static void
2512 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2513 {
2514   vat_main_t *vam = &vat_main;
2515   vat_json_node_t *node = NULL;
2516   struct in6_addr ip6;
2517   struct in_addr ip4;
2518
2519   if (VAT_JSON_ARRAY != vam->json_tree.type)
2520     {
2521       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2522       vat_json_init_array (&vam->json_tree);
2523     }
2524   node = vat_json_array_add (&vam->json_tree);
2525   vat_json_init_object (node);
2526
2527   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2528   vat_json_object_add_uint (node, "priority", mp->priority);
2529   vat_json_object_add_uint (node, "weight", mp->weight);
2530
2531   if (mp->local)
2532     vat_json_object_add_uint (node, "sw_if_index",
2533                               clib_net_to_host_u32 (mp->sw_if_index));
2534   else
2535     {
2536       if (mp->is_ipv6)
2537         {
2538           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2539           vat_json_object_add_ip6 (node, "address", ip6);
2540         }
2541       else
2542         {
2543           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2544           vat_json_object_add_ip4 (node, "address", ip4);
2545         }
2546     }
2547 }
2548
2549 static void
2550 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2551                                           mp)
2552 {
2553   vat_main_t *vam = &vat_main;
2554   u8 *ls_name = 0;
2555
2556   ls_name = format (0, "%s", mp->ls_name);
2557
2558   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2559          ls_name);
2560   vec_free (ls_name);
2561 }
2562
2563 static void
2564   vl_api_one_locator_set_details_t_handler_json
2565   (vl_api_one_locator_set_details_t * mp)
2566 {
2567   vat_main_t *vam = &vat_main;
2568   vat_json_node_t *node = 0;
2569   u8 *ls_name = 0;
2570
2571   ls_name = format (0, "%s", mp->ls_name);
2572   vec_add1 (ls_name, 0);
2573
2574   if (VAT_JSON_ARRAY != vam->json_tree.type)
2575     {
2576       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2577       vat_json_init_array (&vam->json_tree);
2578     }
2579   node = vat_json_array_add (&vam->json_tree);
2580
2581   vat_json_init_object (node);
2582   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2583   vat_json_object_add_uint (node, "ls_index",
2584                             clib_net_to_host_u32 (mp->ls_index));
2585   vec_free (ls_name);
2586 }
2587
2588 static u8 *
2589 format_lisp_flat_eid (u8 * s, va_list * args)
2590 {
2591   u32 type = va_arg (*args, u32);
2592   u8 *eid = va_arg (*args, u8 *);
2593   u32 eid_len = va_arg (*args, u32);
2594
2595   switch (type)
2596     {
2597     case 0:
2598       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2599     case 1:
2600       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2601     case 2:
2602       return format (s, "%U", format_ethernet_address, eid);
2603     }
2604   return 0;
2605 }
2606
2607 static u8 *
2608 format_lisp_eid_vat (u8 * s, va_list * args)
2609 {
2610   u32 type = va_arg (*args, u32);
2611   u8 *eid = va_arg (*args, u8 *);
2612   u32 eid_len = va_arg (*args, u32);
2613   u8 *seid = va_arg (*args, u8 *);
2614   u32 seid_len = va_arg (*args, u32);
2615   u32 is_src_dst = va_arg (*args, u32);
2616
2617   if (is_src_dst)
2618     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2619
2620   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2621
2622   return s;
2623 }
2624
2625 static void
2626 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2627 {
2628   vat_main_t *vam = &vat_main;
2629   u8 *s = 0, *eid = 0;
2630
2631   if (~0 == mp->locator_set_index)
2632     s = format (0, "action: %d", mp->action);
2633   else
2634     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2635
2636   eid = format (0, "%U", format_lisp_eid_vat,
2637                 mp->eid_type,
2638                 mp->eid,
2639                 mp->eid_prefix_len,
2640                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2641   vec_add1 (eid, 0);
2642
2643   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2644          clib_net_to_host_u32 (mp->vni),
2645          eid,
2646          mp->is_local ? "local" : "remote",
2647          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2648          clib_net_to_host_u16 (mp->key_id), mp->key);
2649
2650   vec_free (s);
2651   vec_free (eid);
2652 }
2653
2654 static void
2655 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2656                                              * mp)
2657 {
2658   vat_main_t *vam = &vat_main;
2659   vat_json_node_t *node = 0;
2660   u8 *eid = 0;
2661
2662   if (VAT_JSON_ARRAY != vam->json_tree.type)
2663     {
2664       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2665       vat_json_init_array (&vam->json_tree);
2666     }
2667   node = vat_json_array_add (&vam->json_tree);
2668
2669   vat_json_init_object (node);
2670   if (~0 == mp->locator_set_index)
2671     vat_json_object_add_uint (node, "action", mp->action);
2672   else
2673     vat_json_object_add_uint (node, "locator_set_index",
2674                               clib_net_to_host_u32 (mp->locator_set_index));
2675
2676   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2677   eid = format (0, "%U", format_lisp_eid_vat,
2678                 mp->eid_type,
2679                 mp->eid,
2680                 mp->eid_prefix_len,
2681                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2682   vec_add1 (eid, 0);
2683   vat_json_object_add_string_copy (node, "eid", eid);
2684   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2685   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2686   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2687
2688   if (mp->key_id)
2689     {
2690       vat_json_object_add_uint (node, "key_id",
2691                                 clib_net_to_host_u16 (mp->key_id));
2692       vat_json_object_add_string_copy (node, "key", mp->key);
2693     }
2694   vec_free (eid);
2695 }
2696
2697 static void
2698 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
2699 {
2700   vat_main_t *vam = &vat_main;
2701   u8 *seid = 0, *deid = 0;
2702   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2703
2704   deid = format (0, "%U", format_lisp_eid_vat,
2705                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2706
2707   seid = format (0, "%U", format_lisp_eid_vat,
2708                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2709
2710   vec_add1 (deid, 0);
2711   vec_add1 (seid, 0);
2712
2713   if (mp->is_ip4)
2714     format_ip_address_fcn = format_ip4_address;
2715   else
2716     format_ip_address_fcn = format_ip6_address;
2717
2718
2719   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
2720          clib_net_to_host_u32 (mp->vni),
2721          seid, deid,
2722          format_ip_address_fcn, mp->lloc,
2723          format_ip_address_fcn, mp->rloc,
2724          clib_net_to_host_u32 (mp->pkt_count),
2725          clib_net_to_host_u32 (mp->bytes));
2726
2727   vec_free (deid);
2728   vec_free (seid);
2729 }
2730
2731 static void
2732 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
2733 {
2734   struct in6_addr ip6;
2735   struct in_addr ip4;
2736   vat_main_t *vam = &vat_main;
2737   vat_json_node_t *node = 0;
2738   u8 *deid = 0, *seid = 0;
2739
2740   if (VAT_JSON_ARRAY != vam->json_tree.type)
2741     {
2742       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2743       vat_json_init_array (&vam->json_tree);
2744     }
2745   node = vat_json_array_add (&vam->json_tree);
2746
2747   vat_json_init_object (node);
2748   deid = format (0, "%U", format_lisp_eid_vat,
2749                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2750
2751   seid = format (0, "%U", format_lisp_eid_vat,
2752                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2753
2754   vec_add1 (deid, 0);
2755   vec_add1 (seid, 0);
2756
2757   vat_json_object_add_string_copy (node, "seid", seid);
2758   vat_json_object_add_string_copy (node, "deid", deid);
2759   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2760
2761   if (mp->is_ip4)
2762     {
2763       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
2764       vat_json_object_add_ip4 (node, "lloc", ip4);
2765       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
2766       vat_json_object_add_ip4 (node, "rloc", ip4);
2767     }
2768   else
2769     {
2770       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
2771       vat_json_object_add_ip6 (node, "lloc", ip6);
2772       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
2773       vat_json_object_add_ip6 (node, "rloc", ip6);
2774     }
2775   vat_json_object_add_uint (node, "pkt_count",
2776                             clib_net_to_host_u32 (mp->pkt_count));
2777   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
2778
2779   vec_free (deid);
2780   vec_free (seid);
2781 }
2782
2783 static void
2784   vl_api_one_eid_table_map_details_t_handler
2785   (vl_api_one_eid_table_map_details_t * mp)
2786 {
2787   vat_main_t *vam = &vat_main;
2788
2789   u8 *line = format (0, "%=10d%=10d",
2790                      clib_net_to_host_u32 (mp->vni),
2791                      clib_net_to_host_u32 (mp->dp_table));
2792   print (vam->ofp, "%v", line);
2793   vec_free (line);
2794 }
2795
2796 static void
2797   vl_api_one_eid_table_map_details_t_handler_json
2798   (vl_api_one_eid_table_map_details_t * mp)
2799 {
2800   vat_main_t *vam = &vat_main;
2801   vat_json_node_t *node = NULL;
2802
2803   if (VAT_JSON_ARRAY != vam->json_tree.type)
2804     {
2805       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2806       vat_json_init_array (&vam->json_tree);
2807     }
2808   node = vat_json_array_add (&vam->json_tree);
2809   vat_json_init_object (node);
2810   vat_json_object_add_uint (node, "dp_table",
2811                             clib_net_to_host_u32 (mp->dp_table));
2812   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2813 }
2814
2815 static void
2816   vl_api_one_eid_table_vni_details_t_handler
2817   (vl_api_one_eid_table_vni_details_t * mp)
2818 {
2819   vat_main_t *vam = &vat_main;
2820
2821   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2822   print (vam->ofp, "%v", line);
2823   vec_free (line);
2824 }
2825
2826 static void
2827   vl_api_one_eid_table_vni_details_t_handler_json
2828   (vl_api_one_eid_table_vni_details_t * mp)
2829 {
2830   vat_main_t *vam = &vat_main;
2831   vat_json_node_t *node = NULL;
2832
2833   if (VAT_JSON_ARRAY != vam->json_tree.type)
2834     {
2835       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2836       vat_json_init_array (&vam->json_tree);
2837     }
2838   node = vat_json_array_add (&vam->json_tree);
2839   vat_json_init_object (node);
2840   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2841 }
2842
2843 static void
2844   vl_api_show_one_map_register_state_reply_t_handler
2845   (vl_api_show_one_map_register_state_reply_t * mp)
2846 {
2847   vat_main_t *vam = &vat_main;
2848   int retval = clib_net_to_host_u32 (mp->retval);
2849
2850   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2851
2852   vam->retval = retval;
2853   vam->result_ready = 1;
2854 }
2855
2856 static void
2857   vl_api_show_one_map_register_state_reply_t_handler_json
2858   (vl_api_show_one_map_register_state_reply_t * mp)
2859 {
2860   vat_main_t *vam = &vat_main;
2861   vat_json_node_t _node, *node = &_node;
2862   int retval = clib_net_to_host_u32 (mp->retval);
2863
2864   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2865
2866   vat_json_init_object (node);
2867   vat_json_object_add_string_copy (node, "state", s);
2868
2869   vat_json_print (vam->ofp, node);
2870   vat_json_free (node);
2871
2872   vam->retval = retval;
2873   vam->result_ready = 1;
2874   vec_free (s);
2875 }
2876
2877 static void
2878   vl_api_show_one_rloc_probe_state_reply_t_handler
2879   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2880 {
2881   vat_main_t *vam = &vat_main;
2882   int retval = clib_net_to_host_u32 (mp->retval);
2883
2884   if (retval)
2885     goto end;
2886
2887   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2888 end:
2889   vam->retval = retval;
2890   vam->result_ready = 1;
2891 }
2892
2893 static void
2894   vl_api_show_one_rloc_probe_state_reply_t_handler_json
2895   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2896 {
2897   vat_main_t *vam = &vat_main;
2898   vat_json_node_t _node, *node = &_node;
2899   int retval = clib_net_to_host_u32 (mp->retval);
2900
2901   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2902   vat_json_init_object (node);
2903   vat_json_object_add_string_copy (node, "state", s);
2904
2905   vat_json_print (vam->ofp, node);
2906   vat_json_free (node);
2907
2908   vam->retval = retval;
2909   vam->result_ready = 1;
2910   vec_free (s);
2911 }
2912
2913 static void
2914   vl_api_show_one_stats_enable_disable_reply_t_handler
2915   (vl_api_show_one_stats_enable_disable_reply_t * mp)
2916 {
2917   vat_main_t *vam = &vat_main;
2918   int retval = clib_net_to_host_u32 (mp->retval);
2919
2920   if (retval)
2921     goto end;
2922
2923   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
2924 end:
2925   vam->retval = retval;
2926   vam->result_ready = 1;
2927 }
2928
2929 static void
2930   vl_api_show_one_stats_enable_disable_reply_t_handler_json
2931   (vl_api_show_one_stats_enable_disable_reply_t * mp)
2932 {
2933   vat_main_t *vam = &vat_main;
2934   vat_json_node_t _node, *node = &_node;
2935   int retval = clib_net_to_host_u32 (mp->retval);
2936
2937   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
2938   vat_json_init_object (node);
2939   vat_json_object_add_string_copy (node, "state", s);
2940
2941   vat_json_print (vam->ofp, node);
2942   vat_json_free (node);
2943
2944   vam->retval = retval;
2945   vam->result_ready = 1;
2946   vec_free (s);
2947 }
2948
2949 static void
2950 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
2951 {
2952   e->dp_table = clib_net_to_host_u32 (e->dp_table);
2953   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
2954 }
2955
2956 static void
2957   gpe_fwd_entries_get_reply_t_net_to_host
2958   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2959 {
2960   u32 i;
2961
2962   mp->count = clib_net_to_host_u32 (mp->count);
2963   for (i = 0; i < mp->count; i++)
2964     {
2965       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
2966     }
2967 }
2968
2969 static u8 *
2970 format_gpe_encap_mode (u8 * s, va_list * args)
2971 {
2972   u32 mode = va_arg (*args, u32);
2973
2974   switch (mode)
2975     {
2976     case 0:
2977       return format (s, "lisp");
2978     case 1:
2979       return format (s, "vxlan");
2980     }
2981   return 0;
2982 }
2983
2984 static void
2985   vl_api_gpe_get_encap_mode_reply_t_handler
2986   (vl_api_gpe_get_encap_mode_reply_t * mp)
2987 {
2988   vat_main_t *vam = &vat_main;
2989
2990   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
2991   vam->retval = ntohl (mp->retval);
2992   vam->result_ready = 1;
2993 }
2994
2995 static void
2996   vl_api_gpe_get_encap_mode_reply_t_handler_json
2997   (vl_api_gpe_get_encap_mode_reply_t * mp)
2998 {
2999   vat_main_t *vam = &vat_main;
3000   vat_json_node_t node;
3001
3002   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3003   vec_add1 (encap_mode, 0);
3004
3005   vat_json_init_object (&node);
3006   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3007
3008   vec_free (encap_mode);
3009   vat_json_print (vam->ofp, &node);
3010   vat_json_free (&node);
3011
3012   vam->retval = ntohl (mp->retval);
3013   vam->result_ready = 1;
3014 }
3015
3016 static void
3017   vl_api_gpe_fwd_entry_path_details_t_handler
3018   (vl_api_gpe_fwd_entry_path_details_t * mp)
3019 {
3020   vat_main_t *vam = &vat_main;
3021   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3022
3023   if (mp->lcl_loc.is_ip4)
3024     format_ip_address_fcn = format_ip4_address;
3025   else
3026     format_ip_address_fcn = format_ip6_address;
3027
3028   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3029          format_ip_address_fcn, &mp->lcl_loc,
3030          format_ip_address_fcn, &mp->rmt_loc);
3031 }
3032
3033 static void
3034 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3035 {
3036   struct in6_addr ip6;
3037   struct in_addr ip4;
3038
3039   if (loc->is_ip4)
3040     {
3041       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3042       vat_json_object_add_ip4 (n, "address", ip4);
3043     }
3044   else
3045     {
3046       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3047       vat_json_object_add_ip6 (n, "address", ip6);
3048     }
3049   vat_json_object_add_uint (n, "weight", loc->weight);
3050 }
3051
3052 static void
3053   vl_api_gpe_fwd_entry_path_details_t_handler_json
3054   (vl_api_gpe_fwd_entry_path_details_t * mp)
3055 {
3056   vat_main_t *vam = &vat_main;
3057   vat_json_node_t *node = NULL;
3058   vat_json_node_t *loc_node;
3059
3060   if (VAT_JSON_ARRAY != vam->json_tree.type)
3061     {
3062       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3063       vat_json_init_array (&vam->json_tree);
3064     }
3065   node = vat_json_array_add (&vam->json_tree);
3066   vat_json_init_object (node);
3067
3068   loc_node = vat_json_object_add (node, "local_locator");
3069   vat_json_init_object (loc_node);
3070   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3071
3072   loc_node = vat_json_object_add (node, "remote_locator");
3073   vat_json_init_object (loc_node);
3074   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3075 }
3076
3077 static void
3078   vl_api_gpe_fwd_entries_get_reply_t_handler
3079   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3080 {
3081   vat_main_t *vam = &vat_main;
3082   u32 i;
3083   int retval = clib_net_to_host_u32 (mp->retval);
3084   vl_api_gpe_fwd_entry_t *e;
3085
3086   if (retval)
3087     goto end;
3088
3089   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3090
3091   for (i = 0; i < mp->count; i++)
3092     {
3093       e = &mp->entries[i];
3094       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3095              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3096              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3097     }
3098
3099 end:
3100   vam->retval = retval;
3101   vam->result_ready = 1;
3102 }
3103
3104 static void
3105   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3106   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3107 {
3108   u8 *s = 0;
3109   vat_main_t *vam = &vat_main;
3110   vat_json_node_t *e = 0, root;
3111   u32 i;
3112   int retval = clib_net_to_host_u32 (mp->retval);
3113   vl_api_gpe_fwd_entry_t *fwd;
3114
3115   if (retval)
3116     goto end;
3117
3118   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3119   vat_json_init_array (&root);
3120
3121   for (i = 0; i < mp->count; i++)
3122     {
3123       e = vat_json_array_add (&root);
3124       fwd = &mp->entries[i];
3125
3126       vat_json_init_object (e);
3127       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3128       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3129
3130       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3131                   fwd->leid_prefix_len);
3132       vec_add1 (s, 0);
3133       vat_json_object_add_string_copy (e, "leid", s);
3134       vec_free (s);
3135
3136       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3137                   fwd->reid_prefix_len);
3138       vec_add1 (s, 0);
3139       vat_json_object_add_string_copy (e, "reid", s);
3140       vec_free (s);
3141     }
3142
3143   vat_json_print (vam->ofp, &root);
3144   vat_json_free (&root);
3145
3146 end:
3147   vam->retval = retval;
3148   vam->result_ready = 1;
3149 }
3150
3151 static void
3152   vl_api_one_adjacencies_get_reply_t_handler
3153   (vl_api_one_adjacencies_get_reply_t * mp)
3154 {
3155   vat_main_t *vam = &vat_main;
3156   u32 i, n;
3157   int retval = clib_net_to_host_u32 (mp->retval);
3158   vl_api_one_adjacency_t *a;
3159
3160   if (retval)
3161     goto end;
3162
3163   n = clib_net_to_host_u32 (mp->count);
3164
3165   for (i = 0; i < n; i++)
3166     {
3167       a = &mp->adjacencies[i];
3168       print (vam->ofp, "%U %40U",
3169              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3170              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3171     }
3172
3173 end:
3174   vam->retval = retval;
3175   vam->result_ready = 1;
3176 }
3177
3178 static void
3179   vl_api_one_adjacencies_get_reply_t_handler_json
3180   (vl_api_one_adjacencies_get_reply_t * mp)
3181 {
3182   u8 *s = 0;
3183   vat_main_t *vam = &vat_main;
3184   vat_json_node_t *e = 0, root;
3185   u32 i, n;
3186   int retval = clib_net_to_host_u32 (mp->retval);
3187   vl_api_one_adjacency_t *a;
3188
3189   if (retval)
3190     goto end;
3191
3192   n = clib_net_to_host_u32 (mp->count);
3193   vat_json_init_array (&root);
3194
3195   for (i = 0; i < n; i++)
3196     {
3197       e = vat_json_array_add (&root);
3198       a = &mp->adjacencies[i];
3199
3200       vat_json_init_object (e);
3201       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3202                   a->leid_prefix_len);
3203       vec_add1 (s, 0);
3204       vat_json_object_add_string_copy (e, "leid", s);
3205       vec_free (s);
3206
3207       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3208                   a->reid_prefix_len);
3209       vec_add1 (s, 0);
3210       vat_json_object_add_string_copy (e, "reid", s);
3211       vec_free (s);
3212     }
3213
3214   vat_json_print (vam->ofp, &root);
3215   vat_json_free (&root);
3216
3217 end:
3218   vam->retval = retval;
3219   vam->result_ready = 1;
3220 }
3221
3222 static void
3223 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3224 {
3225   vat_main_t *vam = &vat_main;
3226
3227   print (vam->ofp, "%=20U",
3228          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3229          mp->ip_address);
3230 }
3231
3232 static void
3233   vl_api_one_map_server_details_t_handler_json
3234   (vl_api_one_map_server_details_t * mp)
3235 {
3236   vat_main_t *vam = &vat_main;
3237   vat_json_node_t *node = NULL;
3238   struct in6_addr ip6;
3239   struct in_addr ip4;
3240
3241   if (VAT_JSON_ARRAY != vam->json_tree.type)
3242     {
3243       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3244       vat_json_init_array (&vam->json_tree);
3245     }
3246   node = vat_json_array_add (&vam->json_tree);
3247
3248   vat_json_init_object (node);
3249   if (mp->is_ipv6)
3250     {
3251       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3252       vat_json_object_add_ip6 (node, "map-server", ip6);
3253     }
3254   else
3255     {
3256       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3257       vat_json_object_add_ip4 (node, "map-server", ip4);
3258     }
3259 }
3260
3261 static void
3262 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3263                                            * mp)
3264 {
3265   vat_main_t *vam = &vat_main;
3266
3267   print (vam->ofp, "%=20U",
3268          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3269          mp->ip_address);
3270 }
3271
3272 static void
3273   vl_api_one_map_resolver_details_t_handler_json
3274   (vl_api_one_map_resolver_details_t * mp)
3275 {
3276   vat_main_t *vam = &vat_main;
3277   vat_json_node_t *node = NULL;
3278   struct in6_addr ip6;
3279   struct in_addr ip4;
3280
3281   if (VAT_JSON_ARRAY != vam->json_tree.type)
3282     {
3283       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3284       vat_json_init_array (&vam->json_tree);
3285     }
3286   node = vat_json_array_add (&vam->json_tree);
3287
3288   vat_json_init_object (node);
3289   if (mp->is_ipv6)
3290     {
3291       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3292       vat_json_object_add_ip6 (node, "map resolver", ip6);
3293     }
3294   else
3295     {
3296       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3297       vat_json_object_add_ip4 (node, "map resolver", ip4);
3298     }
3299 }
3300
3301 static void
3302 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
3303 {
3304   vat_main_t *vam = &vat_main;
3305   i32 retval = ntohl (mp->retval);
3306
3307   if (0 <= retval)
3308     {
3309       print (vam->ofp, "feature: %s\ngpe: %s",
3310              mp->feature_status ? "enabled" : "disabled",
3311              mp->gpe_status ? "enabled" : "disabled");
3312     }
3313
3314   vam->retval = retval;
3315   vam->result_ready = 1;
3316 }
3317
3318 static void
3319   vl_api_show_one_status_reply_t_handler_json
3320   (vl_api_show_one_status_reply_t * mp)
3321 {
3322   vat_main_t *vam = &vat_main;
3323   vat_json_node_t node;
3324   u8 *gpe_status = NULL;
3325   u8 *feature_status = NULL;
3326
3327   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
3328   feature_status = format (0, "%s",
3329                            mp->feature_status ? "enabled" : "disabled");
3330   vec_add1 (gpe_status, 0);
3331   vec_add1 (feature_status, 0);
3332
3333   vat_json_init_object (&node);
3334   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
3335   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
3336
3337   vec_free (gpe_status);
3338   vec_free (feature_status);
3339
3340   vat_json_print (vam->ofp, &node);
3341   vat_json_free (&node);
3342
3343   vam->retval = ntohl (mp->retval);
3344   vam->result_ready = 1;
3345 }
3346
3347 static void
3348   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
3349   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3350 {
3351   vat_main_t *vam = &vat_main;
3352   i32 retval = ntohl (mp->retval);
3353
3354   if (retval >= 0)
3355     {
3356       print (vam->ofp, "%=20s", mp->locator_set_name);
3357     }
3358
3359   vam->retval = retval;
3360   vam->result_ready = 1;
3361 }
3362
3363 static void
3364   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
3365   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3366 {
3367   vat_main_t *vam = &vat_main;
3368   vat_json_node_t *node = NULL;
3369
3370   if (VAT_JSON_ARRAY != vam->json_tree.type)
3371     {
3372       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3373       vat_json_init_array (&vam->json_tree);
3374     }
3375   node = vat_json_array_add (&vam->json_tree);
3376
3377   vat_json_init_object (node);
3378   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
3379
3380   vat_json_print (vam->ofp, node);
3381   vat_json_free (node);
3382
3383   vam->retval = ntohl (mp->retval);
3384   vam->result_ready = 1;
3385 }
3386
3387 static u8 *
3388 format_lisp_map_request_mode (u8 * s, va_list * args)
3389 {
3390   u32 mode = va_arg (*args, u32);
3391
3392   switch (mode)
3393     {
3394     case 0:
3395       return format (0, "dst-only");
3396     case 1:
3397       return format (0, "src-dst");
3398     }
3399   return 0;
3400 }
3401
3402 static void
3403   vl_api_show_one_map_request_mode_reply_t_handler
3404   (vl_api_show_one_map_request_mode_reply_t * mp)
3405 {
3406   vat_main_t *vam = &vat_main;
3407   i32 retval = ntohl (mp->retval);
3408
3409   if (0 <= retval)
3410     {
3411       u32 mode = mp->mode;
3412       print (vam->ofp, "map_request_mode: %U",
3413              format_lisp_map_request_mode, mode);
3414     }
3415
3416   vam->retval = retval;
3417   vam->result_ready = 1;
3418 }
3419
3420 static void
3421   vl_api_show_one_map_request_mode_reply_t_handler_json
3422   (vl_api_show_one_map_request_mode_reply_t * mp)
3423 {
3424   vat_main_t *vam = &vat_main;
3425   vat_json_node_t node;
3426   u8 *s = 0;
3427   u32 mode;
3428
3429   mode = mp->mode;
3430   s = format (0, "%U", format_lisp_map_request_mode, mode);
3431   vec_add1 (s, 0);
3432
3433   vat_json_init_object (&node);
3434   vat_json_object_add_string_copy (&node, "map_request_mode", s);
3435   vat_json_print (vam->ofp, &node);
3436   vat_json_free (&node);
3437
3438   vec_free (s);
3439   vam->retval = ntohl (mp->retval);
3440   vam->result_ready = 1;
3441 }
3442
3443 static void
3444   vl_api_show_one_use_petr_reply_t_handler
3445   (vl_api_show_one_use_petr_reply_t * mp)
3446 {
3447   vat_main_t *vam = &vat_main;
3448   i32 retval = ntohl (mp->retval);
3449
3450   if (0 <= retval)
3451     {
3452       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
3453       if (mp->status)
3454         {
3455           print (vam->ofp, "Proxy-ETR address; %U",
3456                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
3457                  mp->address);
3458         }
3459     }
3460
3461   vam->retval = retval;
3462   vam->result_ready = 1;
3463 }
3464
3465 static void
3466   vl_api_show_one_use_petr_reply_t_handler_json
3467   (vl_api_show_one_use_petr_reply_t * mp)
3468 {
3469   vat_main_t *vam = &vat_main;
3470   vat_json_node_t node;
3471   u8 *status = 0;
3472   struct in_addr ip4;
3473   struct in6_addr ip6;
3474
3475   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3476   vec_add1 (status, 0);
3477
3478   vat_json_init_object (&node);
3479   vat_json_object_add_string_copy (&node, "status", status);
3480   if (mp->status)
3481     {
3482       if (mp->is_ip4)
3483         {
3484           clib_memcpy (&ip6, mp->address, sizeof (ip6));
3485           vat_json_object_add_ip6 (&node, "address", ip6);
3486         }
3487       else
3488         {
3489           clib_memcpy (&ip4, mp->address, sizeof (ip4));
3490           vat_json_object_add_ip4 (&node, "address", ip4);
3491         }
3492     }
3493
3494   vec_free (status);
3495
3496   vat_json_print (vam->ofp, &node);
3497   vat_json_free (&node);
3498
3499   vam->retval = ntohl (mp->retval);
3500   vam->result_ready = 1;
3501 }
3502
3503 static void
3504 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
3505 {
3506   vat_main_t *vam = &vat_main;
3507   i32 retval = ntohl (mp->retval);
3508
3509   if (0 <= retval)
3510     {
3511       print (vam->ofp, "%-20s%-16s",
3512              mp->status ? "enabled" : "disabled",
3513              mp->status ? (char *) mp->locator_set_name : "");
3514     }
3515
3516   vam->retval = retval;
3517   vam->result_ready = 1;
3518 }
3519
3520 static void
3521 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
3522 {
3523   vat_main_t *vam = &vat_main;
3524   vat_json_node_t node;
3525   u8 *status = 0;
3526
3527   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3528   vec_add1 (status, 0);
3529
3530   vat_json_init_object (&node);
3531   vat_json_object_add_string_copy (&node, "status", status);
3532   if (mp->status)
3533     {
3534       vat_json_object_add_string_copy (&node, "locator_set",
3535                                        mp->locator_set_name);
3536     }
3537
3538   vec_free (status);
3539
3540   vat_json_print (vam->ofp, &node);
3541   vat_json_free (&node);
3542
3543   vam->retval = ntohl (mp->retval);
3544   vam->result_ready = 1;
3545 }
3546
3547 static u8 *
3548 format_policer_type (u8 * s, va_list * va)
3549 {
3550   u32 i = va_arg (*va, u32);
3551
3552   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
3553     s = format (s, "1r2c");
3554   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
3555     s = format (s, "1r3c");
3556   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
3557     s = format (s, "2r3c-2698");
3558   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
3559     s = format (s, "2r3c-4115");
3560   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
3561     s = format (s, "2r3c-mef5cf1");
3562   else
3563     s = format (s, "ILLEGAL");
3564   return s;
3565 }
3566
3567 static u8 *
3568 format_policer_rate_type (u8 * s, va_list * va)
3569 {
3570   u32 i = va_arg (*va, u32);
3571
3572   if (i == SSE2_QOS_RATE_KBPS)
3573     s = format (s, "kbps");
3574   else if (i == SSE2_QOS_RATE_PPS)
3575     s = format (s, "pps");
3576   else
3577     s = format (s, "ILLEGAL");
3578   return s;
3579 }
3580
3581 static u8 *
3582 format_policer_round_type (u8 * s, va_list * va)
3583 {
3584   u32 i = va_arg (*va, u32);
3585
3586   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3587     s = format (s, "closest");
3588   else if (i == SSE2_QOS_ROUND_TO_UP)
3589     s = format (s, "up");
3590   else if (i == SSE2_QOS_ROUND_TO_DOWN)
3591     s = format (s, "down");
3592   else
3593     s = format (s, "ILLEGAL");
3594   return s;
3595 }
3596
3597 static u8 *
3598 format_policer_action_type (u8 * s, va_list * va)
3599 {
3600   u32 i = va_arg (*va, u32);
3601
3602   if (i == SSE2_QOS_ACTION_DROP)
3603     s = format (s, "drop");
3604   else if (i == SSE2_QOS_ACTION_TRANSMIT)
3605     s = format (s, "transmit");
3606   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3607     s = format (s, "mark-and-transmit");
3608   else
3609     s = format (s, "ILLEGAL");
3610   return s;
3611 }
3612
3613 static u8 *
3614 format_dscp (u8 * s, va_list * va)
3615 {
3616   u32 i = va_arg (*va, u32);
3617   char *t = 0;
3618
3619   switch (i)
3620     {
3621 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3622       foreach_vnet_dscp
3623 #undef _
3624     default:
3625       return format (s, "ILLEGAL");
3626     }
3627   s = format (s, "%s", t);
3628   return s;
3629 }
3630
3631 static void
3632 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3633 {
3634   vat_main_t *vam = &vat_main;
3635   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3636
3637   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3638     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3639   else
3640     conform_dscp_str = format (0, "");
3641
3642   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3643     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3644   else
3645     exceed_dscp_str = format (0, "");
3646
3647   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3648     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3649   else
3650     violate_dscp_str = format (0, "");
3651
3652   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3653          "rate type %U, round type %U, %s rate, %s color-aware, "
3654          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3655          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3656          "conform action %U%s, exceed action %U%s, violate action %U%s",
3657          mp->name,
3658          format_policer_type, mp->type,
3659          ntohl (mp->cir),
3660          ntohl (mp->eir),
3661          clib_net_to_host_u64 (mp->cb),
3662          clib_net_to_host_u64 (mp->eb),
3663          format_policer_rate_type, mp->rate_type,
3664          format_policer_round_type, mp->round_type,
3665          mp->single_rate ? "single" : "dual",
3666          mp->color_aware ? "is" : "not",
3667          ntohl (mp->cir_tokens_per_period),
3668          ntohl (mp->pir_tokens_per_period),
3669          ntohl (mp->scale),
3670          ntohl (mp->current_limit),
3671          ntohl (mp->current_bucket),
3672          ntohl (mp->extended_limit),
3673          ntohl (mp->extended_bucket),
3674          clib_net_to_host_u64 (mp->last_update_time),
3675          format_policer_action_type, mp->conform_action_type,
3676          conform_dscp_str,
3677          format_policer_action_type, mp->exceed_action_type,
3678          exceed_dscp_str,
3679          format_policer_action_type, mp->violate_action_type,
3680          violate_dscp_str);
3681
3682   vec_free (conform_dscp_str);
3683   vec_free (exceed_dscp_str);
3684   vec_free (violate_dscp_str);
3685 }
3686
3687 static void vl_api_policer_details_t_handler_json
3688   (vl_api_policer_details_t * mp)
3689 {
3690   vat_main_t *vam = &vat_main;
3691   vat_json_node_t *node;
3692   u8 *rate_type_str, *round_type_str, *type_str;
3693   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3694
3695   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3696   round_type_str =
3697     format (0, "%U", format_policer_round_type, mp->round_type);
3698   type_str = format (0, "%U", format_policer_type, mp->type);
3699   conform_action_str = format (0, "%U", format_policer_action_type,
3700                                mp->conform_action_type);
3701   exceed_action_str = format (0, "%U", format_policer_action_type,
3702                               mp->exceed_action_type);
3703   violate_action_str = format (0, "%U", format_policer_action_type,
3704                                mp->violate_action_type);
3705
3706   if (VAT_JSON_ARRAY != vam->json_tree.type)
3707     {
3708       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3709       vat_json_init_array (&vam->json_tree);
3710     }
3711   node = vat_json_array_add (&vam->json_tree);
3712
3713   vat_json_init_object (node);
3714   vat_json_object_add_string_copy (node, "name", mp->name);
3715   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3716   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3717   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
3718   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
3719   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3720   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3721   vat_json_object_add_string_copy (node, "type", type_str);
3722   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3723   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3724   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3725   vat_json_object_add_uint (node, "cir_tokens_per_period",
3726                             ntohl (mp->cir_tokens_per_period));
3727   vat_json_object_add_uint (node, "eir_tokens_per_period",
3728                             ntohl (mp->pir_tokens_per_period));
3729   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3730   vat_json_object_add_uint (node, "current_bucket",
3731                             ntohl (mp->current_bucket));
3732   vat_json_object_add_uint (node, "extended_limit",
3733                             ntohl (mp->extended_limit));
3734   vat_json_object_add_uint (node, "extended_bucket",
3735                             ntohl (mp->extended_bucket));
3736   vat_json_object_add_uint (node, "last_update_time",
3737                             ntohl (mp->last_update_time));
3738   vat_json_object_add_string_copy (node, "conform_action",
3739                                    conform_action_str);
3740   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3741     {
3742       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3743       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3744       vec_free (dscp_str);
3745     }
3746   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3747   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3748     {
3749       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3750       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3751       vec_free (dscp_str);
3752     }
3753   vat_json_object_add_string_copy (node, "violate_action",
3754                                    violate_action_str);
3755   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3756     {
3757       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3758       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3759       vec_free (dscp_str);
3760     }
3761
3762   vec_free (rate_type_str);
3763   vec_free (round_type_str);
3764   vec_free (type_str);
3765   vec_free (conform_action_str);
3766   vec_free (exceed_action_str);
3767   vec_free (violate_action_str);
3768 }
3769
3770 static void
3771 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3772                                            mp)
3773 {
3774   vat_main_t *vam = &vat_main;
3775   int i, count = ntohl (mp->count);
3776
3777   if (count > 0)
3778     print (vam->ofp, "classify table ids (%d) : ", count);
3779   for (i = 0; i < count; i++)
3780     {
3781       print (vam->ofp, "%d", ntohl (mp->ids[i]));
3782       print (vam->ofp, (i < count - 1) ? "," : "");
3783     }
3784   vam->retval = ntohl (mp->retval);
3785   vam->result_ready = 1;
3786 }
3787
3788 static void
3789   vl_api_classify_table_ids_reply_t_handler_json
3790   (vl_api_classify_table_ids_reply_t * mp)
3791 {
3792   vat_main_t *vam = &vat_main;
3793   int i, count = ntohl (mp->count);
3794
3795   if (count > 0)
3796     {
3797       vat_json_node_t node;
3798
3799       vat_json_init_object (&node);
3800       for (i = 0; i < count; i++)
3801         {
3802           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3803         }
3804       vat_json_print (vam->ofp, &node);
3805       vat_json_free (&node);
3806     }
3807   vam->retval = ntohl (mp->retval);
3808   vam->result_ready = 1;
3809 }
3810
3811 static void
3812   vl_api_classify_table_by_interface_reply_t_handler
3813   (vl_api_classify_table_by_interface_reply_t * mp)
3814 {
3815   vat_main_t *vam = &vat_main;
3816   u32 table_id;
3817
3818   table_id = ntohl (mp->l2_table_id);
3819   if (table_id != ~0)
3820     print (vam->ofp, "l2 table id : %d", table_id);
3821   else
3822     print (vam->ofp, "l2 table id : No input ACL tables configured");
3823   table_id = ntohl (mp->ip4_table_id);
3824   if (table_id != ~0)
3825     print (vam->ofp, "ip4 table id : %d", table_id);
3826   else
3827     print (vam->ofp, "ip4 table id : No input ACL tables configured");
3828   table_id = ntohl (mp->ip6_table_id);
3829   if (table_id != ~0)
3830     print (vam->ofp, "ip6 table id : %d", table_id);
3831   else
3832     print (vam->ofp, "ip6 table id : No input ACL tables configured");
3833   vam->retval = ntohl (mp->retval);
3834   vam->result_ready = 1;
3835 }
3836
3837 static void
3838   vl_api_classify_table_by_interface_reply_t_handler_json
3839   (vl_api_classify_table_by_interface_reply_t * mp)
3840 {
3841   vat_main_t *vam = &vat_main;
3842   vat_json_node_t node;
3843
3844   vat_json_init_object (&node);
3845
3846   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3847   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3848   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3849
3850   vat_json_print (vam->ofp, &node);
3851   vat_json_free (&node);
3852
3853   vam->retval = ntohl (mp->retval);
3854   vam->result_ready = 1;
3855 }
3856
3857 static void vl_api_policer_add_del_reply_t_handler
3858   (vl_api_policer_add_del_reply_t * mp)
3859 {
3860   vat_main_t *vam = &vat_main;
3861   i32 retval = ntohl (mp->retval);
3862   if (vam->async_mode)
3863     {
3864       vam->async_errors += (retval < 0);
3865     }
3866   else
3867     {
3868       vam->retval = retval;
3869       vam->result_ready = 1;
3870       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3871         /*
3872          * Note: this is just barely thread-safe, depends on
3873          * the main thread spinning waiting for an answer...
3874          */
3875         errmsg ("policer index %d", ntohl (mp->policer_index));
3876     }
3877 }
3878
3879 static void vl_api_policer_add_del_reply_t_handler_json
3880   (vl_api_policer_add_del_reply_t * mp)
3881 {
3882   vat_main_t *vam = &vat_main;
3883   vat_json_node_t node;
3884
3885   vat_json_init_object (&node);
3886   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3887   vat_json_object_add_uint (&node, "policer_index",
3888                             ntohl (mp->policer_index));
3889
3890   vat_json_print (vam->ofp, &node);
3891   vat_json_free (&node);
3892
3893   vam->retval = ntohl (mp->retval);
3894   vam->result_ready = 1;
3895 }
3896
3897 /* Format hex dump. */
3898 u8 *
3899 format_hex_bytes (u8 * s, va_list * va)
3900 {
3901   u8 *bytes = va_arg (*va, u8 *);
3902   int n_bytes = va_arg (*va, int);
3903   uword i;
3904
3905   /* Print short or long form depending on byte count. */
3906   uword short_form = n_bytes <= 32;
3907   uword indent = format_get_indent (s);
3908
3909   if (n_bytes == 0)
3910     return s;
3911
3912   for (i = 0; i < n_bytes; i++)
3913     {
3914       if (!short_form && (i % 32) == 0)
3915         s = format (s, "%08x: ", i);
3916       s = format (s, "%02x", bytes[i]);
3917       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3918         s = format (s, "\n%U", format_white_space, indent);
3919     }
3920
3921   return s;
3922 }
3923
3924 static void
3925 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3926                                             * mp)
3927 {
3928   vat_main_t *vam = &vat_main;
3929   i32 retval = ntohl (mp->retval);
3930   if (retval == 0)
3931     {
3932       print (vam->ofp, "classify table info :");
3933       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3934              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3935              ntohl (mp->miss_next_index));
3936       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3937              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3938              ntohl (mp->match_n_vectors));
3939       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3940              ntohl (mp->mask_length));
3941     }
3942   vam->retval = retval;
3943   vam->result_ready = 1;
3944 }
3945
3946 static void
3947   vl_api_classify_table_info_reply_t_handler_json
3948   (vl_api_classify_table_info_reply_t * mp)
3949 {
3950   vat_main_t *vam = &vat_main;
3951   vat_json_node_t node;
3952
3953   i32 retval = ntohl (mp->retval);
3954   if (retval == 0)
3955     {
3956       vat_json_init_object (&node);
3957
3958       vat_json_object_add_int (&node, "sessions",
3959                                ntohl (mp->active_sessions));
3960       vat_json_object_add_int (&node, "nexttbl",
3961                                ntohl (mp->next_table_index));
3962       vat_json_object_add_int (&node, "nextnode",
3963                                ntohl (mp->miss_next_index));
3964       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3965       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3966       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3967       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3968                       ntohl (mp->mask_length), 0);
3969       vat_json_object_add_string_copy (&node, "mask", s);
3970
3971       vat_json_print (vam->ofp, &node);
3972       vat_json_free (&node);
3973     }
3974   vam->retval = ntohl (mp->retval);
3975   vam->result_ready = 1;
3976 }
3977
3978 static void
3979 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3980                                            mp)
3981 {
3982   vat_main_t *vam = &vat_main;
3983
3984   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3985          ntohl (mp->hit_next_index), ntohl (mp->advance),
3986          ntohl (mp->opaque_index));
3987   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3988          ntohl (mp->match_length));
3989 }
3990
3991 static void
3992   vl_api_classify_session_details_t_handler_json
3993   (vl_api_classify_session_details_t * mp)
3994 {
3995   vat_main_t *vam = &vat_main;
3996   vat_json_node_t *node = NULL;
3997
3998   if (VAT_JSON_ARRAY != vam->json_tree.type)
3999     {
4000       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4001       vat_json_init_array (&vam->json_tree);
4002     }
4003   node = vat_json_array_add (&vam->json_tree);
4004
4005   vat_json_init_object (node);
4006   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4007   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4008   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4009   u8 *s =
4010     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4011             0);
4012   vat_json_object_add_string_copy (node, "match", s);
4013 }
4014
4015 static void vl_api_pg_create_interface_reply_t_handler
4016   (vl_api_pg_create_interface_reply_t * mp)
4017 {
4018   vat_main_t *vam = &vat_main;
4019
4020   vam->retval = ntohl (mp->retval);
4021   vam->result_ready = 1;
4022 }
4023
4024 static void vl_api_pg_create_interface_reply_t_handler_json
4025   (vl_api_pg_create_interface_reply_t * mp)
4026 {
4027   vat_main_t *vam = &vat_main;
4028   vat_json_node_t node;
4029
4030   i32 retval = ntohl (mp->retval);
4031   if (retval == 0)
4032     {
4033       vat_json_init_object (&node);
4034
4035       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4036
4037       vat_json_print (vam->ofp, &node);
4038       vat_json_free (&node);
4039     }
4040   vam->retval = ntohl (mp->retval);
4041   vam->result_ready = 1;
4042 }
4043
4044 static void vl_api_policer_classify_details_t_handler
4045   (vl_api_policer_classify_details_t * mp)
4046 {
4047   vat_main_t *vam = &vat_main;
4048
4049   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4050          ntohl (mp->table_index));
4051 }
4052
4053 static void vl_api_policer_classify_details_t_handler_json
4054   (vl_api_policer_classify_details_t * mp)
4055 {
4056   vat_main_t *vam = &vat_main;
4057   vat_json_node_t *node;
4058
4059   if (VAT_JSON_ARRAY != vam->json_tree.type)
4060     {
4061       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4062       vat_json_init_array (&vam->json_tree);
4063     }
4064   node = vat_json_array_add (&vam->json_tree);
4065
4066   vat_json_init_object (node);
4067   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4068   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4069 }
4070
4071 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
4072   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4073 {
4074   vat_main_t *vam = &vat_main;
4075   i32 retval = ntohl (mp->retval);
4076   if (vam->async_mode)
4077     {
4078       vam->async_errors += (retval < 0);
4079     }
4080   else
4081     {
4082       vam->retval = retval;
4083       vam->sw_if_index = ntohl (mp->sw_if_index);
4084       vam->result_ready = 1;
4085     }
4086 }
4087
4088 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
4089   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4090 {
4091   vat_main_t *vam = &vat_main;
4092   vat_json_node_t node;
4093
4094   vat_json_init_object (&node);
4095   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4096   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
4097
4098   vat_json_print (vam->ofp, &node);
4099   vat_json_free (&node);
4100
4101   vam->retval = ntohl (mp->retval);
4102   vam->result_ready = 1;
4103 }
4104
4105 static void vl_api_flow_classify_details_t_handler
4106   (vl_api_flow_classify_details_t * mp)
4107 {
4108   vat_main_t *vam = &vat_main;
4109
4110   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4111          ntohl (mp->table_index));
4112 }
4113
4114 static void vl_api_flow_classify_details_t_handler_json
4115   (vl_api_flow_classify_details_t * mp)
4116 {
4117   vat_main_t *vam = &vat_main;
4118   vat_json_node_t *node;
4119
4120   if (VAT_JSON_ARRAY != vam->json_tree.type)
4121     {
4122       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4123       vat_json_init_array (&vam->json_tree);
4124     }
4125   node = vat_json_array_add (&vam->json_tree);
4126
4127   vat_json_init_object (node);
4128   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4129   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4130 }
4131
4132 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
4133 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
4134 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
4135 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
4136 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
4137 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
4138 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
4139 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
4140 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
4141 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
4142 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
4143 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
4144 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
4145 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
4146
4147 /*
4148  * Generate boilerplate reply handlers, which
4149  * dig the return value out of the xxx_reply_t API message,
4150  * stick it into vam->retval, and set vam->result_ready
4151  *
4152  * Could also do this by pointing N message decode slots at
4153  * a single function, but that could break in subtle ways.
4154  */
4155
4156 #define foreach_standard_reply_retval_handler           \
4157 _(sw_interface_set_flags_reply)                         \
4158 _(sw_interface_add_del_address_reply)                   \
4159 _(sw_interface_set_table_reply)                         \
4160 _(sw_interface_set_mpls_enable_reply)                   \
4161 _(sw_interface_set_vpath_reply)                         \
4162 _(sw_interface_set_vxlan_bypass_reply)                  \
4163 _(sw_interface_set_l2_bridge_reply)                     \
4164 _(bridge_domain_add_del_reply)                          \
4165 _(sw_interface_set_l2_xconnect_reply)                   \
4166 _(l2fib_add_del_reply)                                  \
4167 _(l2fib_flush_int_reply)                                \
4168 _(l2fib_flush_bd_reply)                                 \
4169 _(ip_add_del_route_reply)                               \
4170 _(ip_mroute_add_del_reply)                              \
4171 _(mpls_route_add_del_reply)                             \
4172 _(mpls_ip_bind_unbind_reply)                            \
4173 _(proxy_arp_add_del_reply)                              \
4174 _(proxy_arp_intfc_enable_disable_reply)                 \
4175 _(sw_interface_set_unnumbered_reply)                    \
4176 _(ip_neighbor_add_del_reply)                            \
4177 _(reset_vrf_reply)                                      \
4178 _(oam_add_del_reply)                                    \
4179 _(reset_fib_reply)                                      \
4180 _(dhcp_proxy_config_reply)                              \
4181 _(dhcp_proxy_set_vss_reply)                             \
4182 _(dhcp_client_config_reply)                             \
4183 _(set_ip_flow_hash_reply)                               \
4184 _(sw_interface_ip6_enable_disable_reply)                \
4185 _(sw_interface_ip6_set_link_local_address_reply)        \
4186 _(ip6nd_proxy_add_del_reply)                            \
4187 _(sw_interface_ip6nd_ra_prefix_reply)                   \
4188 _(sw_interface_ip6nd_ra_config_reply)                   \
4189 _(set_arp_neighbor_limit_reply)                         \
4190 _(l2_patch_add_del_reply)                               \
4191 _(sr_policy_add_reply)                                  \
4192 _(sr_policy_mod_reply)                                  \
4193 _(sr_policy_del_reply)                                  \
4194 _(sr_localsid_add_del_reply)                            \
4195 _(sr_steering_add_del_reply)                            \
4196 _(classify_add_del_session_reply)                       \
4197 _(classify_set_interface_ip_table_reply)                \
4198 _(classify_set_interface_l2_tables_reply)               \
4199 _(l2tpv3_set_tunnel_cookies_reply)                      \
4200 _(l2tpv3_interface_enable_disable_reply)                \
4201 _(l2tpv3_set_lookup_key_reply)                          \
4202 _(l2_fib_clear_table_reply)                             \
4203 _(l2_interface_efp_filter_reply)                        \
4204 _(l2_interface_vlan_tag_rewrite_reply)                  \
4205 _(modify_vhost_user_if_reply)                           \
4206 _(delete_vhost_user_if_reply)                           \
4207 _(want_ip4_arp_events_reply)                            \
4208 _(want_ip6_nd_events_reply)                             \
4209 _(input_acl_set_interface_reply)                        \
4210 _(ipsec_spd_add_del_reply)                              \
4211 _(ipsec_interface_add_del_spd_reply)                    \
4212 _(ipsec_spd_add_del_entry_reply)                        \
4213 _(ipsec_sad_add_del_entry_reply)                        \
4214 _(ipsec_sa_set_key_reply)                               \
4215 _(ipsec_tunnel_if_add_del_reply)                        \
4216 _(ikev2_profile_add_del_reply)                          \
4217 _(ikev2_profile_set_auth_reply)                         \
4218 _(ikev2_profile_set_id_reply)                           \
4219 _(ikev2_profile_set_ts_reply)                           \
4220 _(ikev2_set_local_key_reply)                            \
4221 _(ikev2_set_responder_reply)                            \
4222 _(ikev2_set_ike_transforms_reply)                       \
4223 _(ikev2_set_esp_transforms_reply)                       \
4224 _(ikev2_set_sa_lifetime_reply)                          \
4225 _(ikev2_initiate_sa_init_reply)                         \
4226 _(ikev2_initiate_del_ike_sa_reply)                      \
4227 _(ikev2_initiate_del_child_sa_reply)                    \
4228 _(ikev2_initiate_rekey_child_sa_reply)                  \
4229 _(delete_loopback_reply)                                \
4230 _(bd_ip_mac_add_del_reply)                              \
4231 _(map_del_domain_reply)                                 \
4232 _(map_add_del_rule_reply)                               \
4233 _(want_interface_events_reply)                          \
4234 _(want_stats_reply)                                     \
4235 _(cop_interface_enable_disable_reply)                   \
4236 _(cop_whitelist_enable_disable_reply)                   \
4237 _(sw_interface_clear_stats_reply)                       \
4238 _(ioam_enable_reply)                              \
4239 _(ioam_disable_reply)                              \
4240 _(one_add_del_locator_reply)                            \
4241 _(one_add_del_local_eid_reply)                          \
4242 _(one_add_del_remote_mapping_reply)                     \
4243 _(one_add_del_adjacency_reply)                          \
4244 _(one_add_del_map_resolver_reply)                       \
4245 _(one_add_del_map_server_reply)                         \
4246 _(one_enable_disable_reply)                             \
4247 _(one_rloc_probe_enable_disable_reply)                  \
4248 _(one_map_register_enable_disable_reply)                \
4249 _(one_pitr_set_locator_set_reply)                       \
4250 _(one_map_request_mode_reply)                           \
4251 _(one_add_del_map_request_itr_rlocs_reply)              \
4252 _(one_eid_table_add_del_map_reply)                      \
4253 _(one_use_petr_reply)                                   \
4254 _(one_stats_enable_disable_reply)                       \
4255 _(one_stats_flush_reply)                                \
4256 _(gpe_add_del_fwd_entry_reply)                          \
4257 _(gpe_enable_disable_reply)                             \
4258 _(gpe_set_encap_mode_reply)                             \
4259 _(gpe_add_del_iface_reply)                              \
4260 _(vxlan_gpe_add_del_tunnel_reply)                       \
4261 _(af_packet_delete_reply)                               \
4262 _(policer_classify_set_interface_reply)                 \
4263 _(netmap_create_reply)                                  \
4264 _(netmap_delete_reply)                                  \
4265 _(set_ipfix_exporter_reply)                             \
4266 _(set_ipfix_classify_stream_reply)                      \
4267 _(ipfix_classify_table_add_del_reply)                   \
4268 _(flow_classify_set_interface_reply)                    \
4269 _(sw_interface_span_enable_disable_reply)               \
4270 _(pg_capture_reply)                                     \
4271 _(pg_enable_disable_reply)                              \
4272 _(ip_source_and_port_range_check_add_del_reply)         \
4273 _(ip_source_and_port_range_check_interface_add_del_reply)\
4274 _(delete_subif_reply)                                   \
4275 _(l2_interface_pbb_tag_rewrite_reply)                   \
4276 _(punt_reply)                                           \
4277 _(feature_enable_disable_reply)                         \
4278 _(sw_interface_tag_add_del_reply)                       \
4279 _(sw_interface_set_mtu_reply)
4280
4281 #define _(n)                                    \
4282     static void vl_api_##n##_t_handler          \
4283     (vl_api_##n##_t * mp)                       \
4284     {                                           \
4285         vat_main_t * vam = &vat_main;           \
4286         i32 retval = ntohl(mp->retval);         \
4287         if (vam->async_mode) {                  \
4288             vam->async_errors += (retval < 0);  \
4289         } else {                                \
4290             vam->retval = retval;               \
4291             vam->result_ready = 1;              \
4292         }                                       \
4293     }
4294 foreach_standard_reply_retval_handler;
4295 #undef _
4296
4297 #define _(n)                                    \
4298     static void vl_api_##n##_t_handler_json     \
4299     (vl_api_##n##_t * mp)                       \
4300     {                                           \
4301         vat_main_t * vam = &vat_main;           \
4302         vat_json_node_t node;                   \
4303         vat_json_init_object(&node);            \
4304         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
4305         vat_json_print(vam->ofp, &node);        \
4306         vam->retval = ntohl(mp->retval);        \
4307         vam->result_ready = 1;                  \
4308     }
4309 foreach_standard_reply_retval_handler;
4310 #undef _
4311
4312 /*
4313  * Table of message reply handlers, must include boilerplate handlers
4314  * we just generated
4315  */
4316
4317 #define foreach_vpe_api_reply_msg                                       \
4318 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
4319 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
4320 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
4321 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
4322 _(CONTROL_PING_REPLY, control_ping_reply)                               \
4323 _(CLI_REPLY, cli_reply)                                                 \
4324 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
4325 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
4326   sw_interface_add_del_address_reply)                                   \
4327 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
4328 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
4329 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
4330 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
4331 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
4332   sw_interface_set_l2_xconnect_reply)                                   \
4333 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
4334   sw_interface_set_l2_bridge_reply)                                     \
4335 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
4336 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
4337 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
4338 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
4339 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
4340 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
4341 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
4342 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
4343 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
4344 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
4345 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
4346 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
4347 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
4348 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
4349 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
4350 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
4351 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
4352 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
4353 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
4354   proxy_arp_intfc_enable_disable_reply)                                 \
4355 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
4356 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
4357   sw_interface_set_unnumbered_reply)                                    \
4358 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
4359 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
4360 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
4361 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
4362 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
4363 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
4364 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
4365 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
4366 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
4367 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
4368 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
4369 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
4370   sw_interface_ip6_enable_disable_reply)                                \
4371 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
4372   sw_interface_ip6_set_link_local_address_reply)                        \
4373 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
4374 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
4375 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
4376   sw_interface_ip6nd_ra_prefix_reply)                                   \
4377 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
4378   sw_interface_ip6nd_ra_config_reply)                                   \
4379 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
4380 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
4381 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
4382 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
4383 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
4384 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
4385 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
4386 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
4387 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
4388 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
4389 classify_set_interface_ip_table_reply)                                  \
4390 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
4391   classify_set_interface_l2_tables_reply)                               \
4392 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
4393 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
4394 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
4395 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
4396 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
4397   l2tpv3_interface_enable_disable_reply)                                \
4398 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
4399 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
4400 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
4401 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
4402 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
4403 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
4404 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
4405 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
4406 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4407 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
4408 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
4409 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
4410 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
4411 _(SHOW_VERSION_REPLY, show_version_reply)                               \
4412 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
4413 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
4414 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
4415 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
4416 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
4417 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
4418 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
4419 _(IP6_ND_EVENT, ip6_nd_event)                                           \
4420 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
4421 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
4422 _(IP_DETAILS, ip_details)                                               \
4423 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
4424 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4425 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
4426 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
4427 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
4428 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
4429 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
4430 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
4431 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
4432 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
4433 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
4434 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
4435 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
4436 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
4437 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
4438 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
4439 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
4440 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
4441 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
4442 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
4443 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
4444 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
4445 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
4446 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
4447 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
4448 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
4449 _(MAP_RULE_DETAILS, map_rule_details)                                   \
4450 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
4451 _(WANT_STATS_REPLY, want_stats_reply)                                   \
4452 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
4453 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4454 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4455 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
4456 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
4457 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
4458 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
4459 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
4460 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
4461 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
4462 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
4463 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
4464 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
4465 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
4466 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
4467 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
4468   one_map_register_enable_disable_reply)                                \
4469 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
4470   one_rloc_probe_enable_disable_reply)                                  \
4471 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
4472 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
4473 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
4474 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
4475 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
4476 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
4477 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
4478 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
4479 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
4480 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
4481 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
4482 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
4483 _(ONE_STATS_DETAILS, one_stats_details)                                 \
4484 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
4485 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
4486 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
4487   show_one_stats_enable_disable_reply)                                  \
4488 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
4489 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
4490 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
4491 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
4492 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
4493 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
4494 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
4495   gpe_fwd_entry_path_details)                                           \
4496 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
4497 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
4498   one_add_del_map_request_itr_rlocs_reply)                              \
4499 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
4500   one_get_map_request_itr_rlocs_reply)                                  \
4501 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
4502 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
4503 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
4504 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
4505 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
4506   show_one_map_register_state_reply)                                    \
4507 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
4508 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
4509 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
4510 _(POLICER_DETAILS, policer_details)                                     \
4511 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4512 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
4513 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
4514 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
4515 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
4516 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
4517 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
4518 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4519 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
4520 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
4521 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
4522 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
4523 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
4524 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
4525 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4526 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
4527 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4528 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
4529 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
4530 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
4531 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
4532 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
4533 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
4534 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
4535 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
4536  ip_source_and_port_range_check_add_del_reply)                          \
4537 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
4538  ip_source_and_port_range_check_interface_add_del_reply)                \
4539 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
4540 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
4541 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
4542 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
4543 _(PUNT_REPLY, punt_reply)                                               \
4544 _(IP_FIB_DETAILS, ip_fib_details)                                       \
4545 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
4546 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
4547 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
4548 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
4549 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
4550 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
4551 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
4552
4553 #define foreach_standalone_reply_msg                                    \
4554 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
4555 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
4556 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
4557 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
4558 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
4559 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
4560 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
4561
4562 typedef struct
4563 {
4564   u8 *name;
4565   u32 value;
4566 } name_sort_t;
4567
4568
4569 #define STR_VTR_OP_CASE(op)     \
4570     case L2_VTR_ ## op:         \
4571         return "" # op;
4572
4573 static const char *
4574 str_vtr_op (u32 vtr_op)
4575 {
4576   switch (vtr_op)
4577     {
4578       STR_VTR_OP_CASE (DISABLED);
4579       STR_VTR_OP_CASE (PUSH_1);
4580       STR_VTR_OP_CASE (PUSH_2);
4581       STR_VTR_OP_CASE (POP_1);
4582       STR_VTR_OP_CASE (POP_2);
4583       STR_VTR_OP_CASE (TRANSLATE_1_1);
4584       STR_VTR_OP_CASE (TRANSLATE_1_2);
4585       STR_VTR_OP_CASE (TRANSLATE_2_1);
4586       STR_VTR_OP_CASE (TRANSLATE_2_2);
4587     }
4588
4589   return "UNKNOWN";
4590 }
4591
4592 static int
4593 dump_sub_interface_table (vat_main_t * vam)
4594 {
4595   const sw_interface_subif_t *sub = NULL;
4596
4597   if (vam->json_output)
4598     {
4599       clib_warning
4600         ("JSON output supported only for VPE API calls and dump_stats_table");
4601       return -99;
4602     }
4603
4604   print (vam->ofp,
4605          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4606          "Interface", "sw_if_index",
4607          "sub id", "dot1ad", "tags", "outer id",
4608          "inner id", "exact", "default", "outer any", "inner any");
4609
4610   vec_foreach (sub, vam->sw_if_subif_table)
4611   {
4612     print (vam->ofp,
4613            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4614            sub->interface_name,
4615            sub->sw_if_index,
4616            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4617            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4618            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4619            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4620     if (sub->vtr_op != L2_VTR_DISABLED)
4621       {
4622         print (vam->ofp,
4623                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4624                "tag1: %d tag2: %d ]",
4625                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4626                sub->vtr_tag1, sub->vtr_tag2);
4627       }
4628   }
4629
4630   return 0;
4631 }
4632
4633 static int
4634 name_sort_cmp (void *a1, void *a2)
4635 {
4636   name_sort_t *n1 = a1;
4637   name_sort_t *n2 = a2;
4638
4639   return strcmp ((char *) n1->name, (char *) n2->name);
4640 }
4641
4642 static int
4643 dump_interface_table (vat_main_t * vam)
4644 {
4645   hash_pair_t *p;
4646   name_sort_t *nses = 0, *ns;
4647
4648   if (vam->json_output)
4649     {
4650       clib_warning
4651         ("JSON output supported only for VPE API calls and dump_stats_table");
4652       return -99;
4653     }
4654
4655   /* *INDENT-OFF* */
4656   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4657   ({
4658     vec_add2 (nses, ns, 1);
4659     ns->name = (u8 *)(p->key);
4660     ns->value = (u32) p->value[0];
4661   }));
4662   /* *INDENT-ON* */
4663
4664   vec_sort_with_function (nses, name_sort_cmp);
4665
4666   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4667   vec_foreach (ns, nses)
4668   {
4669     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4670   }
4671   vec_free (nses);
4672   return 0;
4673 }
4674
4675 static int
4676 dump_ip_table (vat_main_t * vam, int is_ipv6)
4677 {
4678   const ip_details_t *det = NULL;
4679   const ip_address_details_t *address = NULL;
4680   u32 i = ~0;
4681
4682   print (vam->ofp, "%-12s", "sw_if_index");
4683
4684   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4685   {
4686     i++;
4687     if (!det->present)
4688       {
4689         continue;
4690       }
4691     print (vam->ofp, "%-12d", i);
4692     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
4693     if (!det->addr)
4694       {
4695         continue;
4696       }
4697     vec_foreach (address, det->addr)
4698     {
4699       print (vam->ofp,
4700              "            %-30U%-13d",
4701              is_ipv6 ? format_ip6_address : format_ip4_address,
4702              address->ip, address->prefix_length);
4703     }
4704   }
4705
4706   return 0;
4707 }
4708
4709 static int
4710 dump_ipv4_table (vat_main_t * vam)
4711 {
4712   if (vam->json_output)
4713     {
4714       clib_warning
4715         ("JSON output supported only for VPE API calls and dump_stats_table");
4716       return -99;
4717     }
4718
4719   return dump_ip_table (vam, 0);
4720 }
4721
4722 static int
4723 dump_ipv6_table (vat_main_t * vam)
4724 {
4725   if (vam->json_output)
4726     {
4727       clib_warning
4728         ("JSON output supported only for VPE API calls and dump_stats_table");
4729       return -99;
4730     }
4731
4732   return dump_ip_table (vam, 1);
4733 }
4734
4735 static char *
4736 counter_type_to_str (u8 counter_type, u8 is_combined)
4737 {
4738   if (!is_combined)
4739     {
4740       switch (counter_type)
4741         {
4742         case VNET_INTERFACE_COUNTER_DROP:
4743           return "drop";
4744         case VNET_INTERFACE_COUNTER_PUNT:
4745           return "punt";
4746         case VNET_INTERFACE_COUNTER_IP4:
4747           return "ip4";
4748         case VNET_INTERFACE_COUNTER_IP6:
4749           return "ip6";
4750         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4751           return "rx-no-buf";
4752         case VNET_INTERFACE_COUNTER_RX_MISS:
4753           return "rx-miss";
4754         case VNET_INTERFACE_COUNTER_RX_ERROR:
4755           return "rx-error";
4756         case VNET_INTERFACE_COUNTER_TX_ERROR:
4757           return "tx-error";
4758         default:
4759           return "INVALID-COUNTER-TYPE";
4760         }
4761     }
4762   else
4763     {
4764       switch (counter_type)
4765         {
4766         case VNET_INTERFACE_COUNTER_RX:
4767           return "rx";
4768         case VNET_INTERFACE_COUNTER_TX:
4769           return "tx";
4770         default:
4771           return "INVALID-COUNTER-TYPE";
4772         }
4773     }
4774 }
4775
4776 static int
4777 dump_stats_table (vat_main_t * vam)
4778 {
4779   vat_json_node_t node;
4780   vat_json_node_t *msg_array;
4781   vat_json_node_t *msg;
4782   vat_json_node_t *counter_array;
4783   vat_json_node_t *counter;
4784   interface_counter_t c;
4785   u64 packets;
4786   ip4_fib_counter_t *c4;
4787   ip6_fib_counter_t *c6;
4788   ip4_nbr_counter_t *n4;
4789   ip6_nbr_counter_t *n6;
4790   int i, j;
4791
4792   if (!vam->json_output)
4793     {
4794       clib_warning ("dump_stats_table supported only in JSON format");
4795       return -99;
4796     }
4797
4798   vat_json_init_object (&node);
4799
4800   /* interface counters */
4801   msg_array = vat_json_object_add (&node, "interface_counters");
4802   vat_json_init_array (msg_array);
4803   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4804     {
4805       msg = vat_json_array_add (msg_array);
4806       vat_json_init_object (msg);
4807       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4808                                        (u8 *) counter_type_to_str (i, 0));
4809       vat_json_object_add_int (msg, "is_combined", 0);
4810       counter_array = vat_json_object_add (msg, "data");
4811       vat_json_init_array (counter_array);
4812       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4813         {
4814           packets = vam->simple_interface_counters[i][j];
4815           vat_json_array_add_uint (counter_array, packets);
4816         }
4817     }
4818   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4819     {
4820       msg = vat_json_array_add (msg_array);
4821       vat_json_init_object (msg);
4822       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4823                                        (u8 *) counter_type_to_str (i, 1));
4824       vat_json_object_add_int (msg, "is_combined", 1);
4825       counter_array = vat_json_object_add (msg, "data");
4826       vat_json_init_array (counter_array);
4827       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4828         {
4829           c = vam->combined_interface_counters[i][j];
4830           counter = vat_json_array_add (counter_array);
4831           vat_json_init_object (counter);
4832           vat_json_object_add_uint (counter, "packets", c.packets);
4833           vat_json_object_add_uint (counter, "bytes", c.bytes);
4834         }
4835     }
4836
4837   /* ip4 fib counters */
4838   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4839   vat_json_init_array (msg_array);
4840   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4841     {
4842       msg = vat_json_array_add (msg_array);
4843       vat_json_init_object (msg);
4844       vat_json_object_add_uint (msg, "vrf_id",
4845                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4846       counter_array = vat_json_object_add (msg, "c");
4847       vat_json_init_array (counter_array);
4848       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4849         {
4850           counter = vat_json_array_add (counter_array);
4851           vat_json_init_object (counter);
4852           c4 = &vam->ip4_fib_counters[i][j];
4853           vat_json_object_add_ip4 (counter, "address", c4->address);
4854           vat_json_object_add_uint (counter, "address_length",
4855                                     c4->address_length);
4856           vat_json_object_add_uint (counter, "packets", c4->packets);
4857           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4858         }
4859     }
4860
4861   /* ip6 fib counters */
4862   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4863   vat_json_init_array (msg_array);
4864   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4865     {
4866       msg = vat_json_array_add (msg_array);
4867       vat_json_init_object (msg);
4868       vat_json_object_add_uint (msg, "vrf_id",
4869                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4870       counter_array = vat_json_object_add (msg, "c");
4871       vat_json_init_array (counter_array);
4872       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4873         {
4874           counter = vat_json_array_add (counter_array);
4875           vat_json_init_object (counter);
4876           c6 = &vam->ip6_fib_counters[i][j];
4877           vat_json_object_add_ip6 (counter, "address", c6->address);
4878           vat_json_object_add_uint (counter, "address_length",
4879                                     c6->address_length);
4880           vat_json_object_add_uint (counter, "packets", c6->packets);
4881           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4882         }
4883     }
4884
4885   /* ip4 nbr counters */
4886   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
4887   vat_json_init_array (msg_array);
4888   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
4889     {
4890       msg = vat_json_array_add (msg_array);
4891       vat_json_init_object (msg);
4892       vat_json_object_add_uint (msg, "sw_if_index", i);
4893       counter_array = vat_json_object_add (msg, "c");
4894       vat_json_init_array (counter_array);
4895       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
4896         {
4897           counter = vat_json_array_add (counter_array);
4898           vat_json_init_object (counter);
4899           n4 = &vam->ip4_nbr_counters[i][j];
4900           vat_json_object_add_ip4 (counter, "address", n4->address);
4901           vat_json_object_add_uint (counter, "link-type", n4->linkt);
4902           vat_json_object_add_uint (counter, "packets", n4->packets);
4903           vat_json_object_add_uint (counter, "bytes", n4->bytes);
4904         }
4905     }
4906
4907   /* ip6 nbr counters */
4908   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
4909   vat_json_init_array (msg_array);
4910   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
4911     {
4912       msg = vat_json_array_add (msg_array);
4913       vat_json_init_object (msg);
4914       vat_json_object_add_uint (msg, "sw_if_index", i);
4915       counter_array = vat_json_object_add (msg, "c");
4916       vat_json_init_array (counter_array);
4917       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
4918         {
4919           counter = vat_json_array_add (counter_array);
4920           vat_json_init_object (counter);
4921           n6 = &vam->ip6_nbr_counters[i][j];
4922           vat_json_object_add_ip6 (counter, "address", n6->address);
4923           vat_json_object_add_uint (counter, "packets", n6->packets);
4924           vat_json_object_add_uint (counter, "bytes", n6->bytes);
4925         }
4926     }
4927
4928   vat_json_print (vam->ofp, &node);
4929   vat_json_free (&node);
4930
4931   return 0;
4932 }
4933
4934 int
4935 exec (vat_main_t * vam)
4936 {
4937   api_main_t *am = &api_main;
4938   vl_api_cli_request_t *mp;
4939   f64 timeout;
4940   void *oldheap;
4941   u8 *cmd = 0;
4942   unformat_input_t *i = vam->input;
4943
4944   if (vec_len (i->buffer) == 0)
4945     return -1;
4946
4947   if (vam->exec_mode == 0 && unformat (i, "mode"))
4948     {
4949       vam->exec_mode = 1;
4950       return 0;
4951     }
4952   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4953     {
4954       vam->exec_mode = 0;
4955       return 0;
4956     }
4957
4958
4959   M (CLI_REQUEST, mp);
4960
4961   /*
4962    * Copy cmd into shared memory.
4963    * In order for the CLI command to work, it
4964    * must be a vector ending in \n, not a C-string ending
4965    * in \n\0.
4966    */
4967   pthread_mutex_lock (&am->vlib_rp->mutex);
4968   oldheap = svm_push_data_heap (am->vlib_rp);
4969
4970   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4971   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4972
4973   svm_pop_heap (oldheap);
4974   pthread_mutex_unlock (&am->vlib_rp->mutex);
4975
4976   mp->cmd_in_shmem = pointer_to_uword (cmd);
4977   S (mp);
4978   timeout = vat_time_now (vam) + 10.0;
4979
4980   while (vat_time_now (vam) < timeout)
4981     {
4982       if (vam->result_ready == 1)
4983         {
4984           u8 *free_me;
4985           if (vam->shmem_result != NULL)
4986             print (vam->ofp, "%s", vam->shmem_result);
4987           pthread_mutex_lock (&am->vlib_rp->mutex);
4988           oldheap = svm_push_data_heap (am->vlib_rp);
4989
4990           free_me = (u8 *) vam->shmem_result;
4991           vec_free (free_me);
4992
4993           svm_pop_heap (oldheap);
4994           pthread_mutex_unlock (&am->vlib_rp->mutex);
4995           return 0;
4996         }
4997     }
4998   return -99;
4999 }
5000
5001 /*
5002  * Future replacement of exec() that passes CLI buffers directly in
5003  * the API messages instead of an additional shared memory area.
5004  */
5005 static int
5006 exec_inband (vat_main_t * vam)
5007 {
5008   vl_api_cli_inband_t *mp;
5009   unformat_input_t *i = vam->input;
5010   int ret;
5011
5012   if (vec_len (i->buffer) == 0)
5013     return -1;
5014
5015   if (vam->exec_mode == 0 && unformat (i, "mode"))
5016     {
5017       vam->exec_mode = 1;
5018       return 0;
5019     }
5020   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5021     {
5022       vam->exec_mode = 0;
5023       return 0;
5024     }
5025
5026   /*
5027    * In order for the CLI command to work, it
5028    * must be a vector ending in \n, not a C-string ending
5029    * in \n\0.
5030    */
5031   u32 len = vec_len (vam->input->buffer);
5032   M2 (CLI_INBAND, mp, len);
5033   clib_memcpy (mp->cmd, vam->input->buffer, len);
5034   mp->length = htonl (len);
5035
5036   S (mp);
5037   W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
5038   return ret;
5039 }
5040
5041 static int
5042 api_create_loopback (vat_main_t * vam)
5043 {
5044   unformat_input_t *i = vam->input;
5045   vl_api_create_loopback_t *mp;
5046   vl_api_create_loopback_instance_t *mp_lbi;
5047   u8 mac_address[6];
5048   u8 mac_set = 0;
5049   u8 is_specified = 0;
5050   u32 user_instance = 0;
5051   int ret;
5052
5053   memset (mac_address, 0, sizeof (mac_address));
5054
5055   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5056     {
5057       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5058         mac_set = 1;
5059       if (unformat (i, "instance %d", &user_instance))
5060         is_specified = 1;
5061       else
5062         break;
5063     }
5064
5065   if (is_specified)
5066     {
5067       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5068       mp_lbi->is_specified = is_specified;
5069       if (is_specified)
5070         mp_lbi->user_instance = htonl (user_instance);
5071       if (mac_set)
5072         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5073       S (mp_lbi);
5074     }
5075   else
5076     {
5077       /* Construct the API message */
5078       M (CREATE_LOOPBACK, mp);
5079       if (mac_set)
5080         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5081       S (mp);
5082     }
5083
5084   W (ret);
5085   return ret;
5086 }
5087
5088 static int
5089 api_delete_loopback (vat_main_t * vam)
5090 {
5091   unformat_input_t *i = vam->input;
5092   vl_api_delete_loopback_t *mp;
5093   u32 sw_if_index = ~0;
5094   int ret;
5095
5096   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5097     {
5098       if (unformat (i, "sw_if_index %d", &sw_if_index))
5099         ;
5100       else
5101         break;
5102     }
5103
5104   if (sw_if_index == ~0)
5105     {
5106       errmsg ("missing sw_if_index");
5107       return -99;
5108     }
5109
5110   /* Construct the API message */
5111   M (DELETE_LOOPBACK, mp);
5112   mp->sw_if_index = ntohl (sw_if_index);
5113
5114   S (mp);
5115   W (ret);
5116   return ret;
5117 }
5118
5119 static int
5120 api_want_stats (vat_main_t * vam)
5121 {
5122   unformat_input_t *i = vam->input;
5123   vl_api_want_stats_t *mp;
5124   int enable = -1;
5125   int ret;
5126
5127   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5128     {
5129       if (unformat (i, "enable"))
5130         enable = 1;
5131       else if (unformat (i, "disable"))
5132         enable = 0;
5133       else
5134         break;
5135     }
5136
5137   if (enable == -1)
5138     {
5139       errmsg ("missing enable|disable");
5140       return -99;
5141     }
5142
5143   M (WANT_STATS, mp);
5144   mp->enable_disable = enable;
5145
5146   S (mp);
5147   W (ret);
5148   return ret;
5149 }
5150
5151 static int
5152 api_want_interface_events (vat_main_t * vam)
5153 {
5154   unformat_input_t *i = vam->input;
5155   vl_api_want_interface_events_t *mp;
5156   int enable = -1;
5157   int ret;
5158
5159   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5160     {
5161       if (unformat (i, "enable"))
5162         enable = 1;
5163       else if (unformat (i, "disable"))
5164         enable = 0;
5165       else
5166         break;
5167     }
5168
5169   if (enable == -1)
5170     {
5171       errmsg ("missing enable|disable");
5172       return -99;
5173     }
5174
5175   M (WANT_INTERFACE_EVENTS, mp);
5176   mp->enable_disable = enable;
5177
5178   vam->interface_event_display = enable;
5179
5180   S (mp);
5181   W (ret);
5182   return ret;
5183 }
5184
5185
5186 /* Note: non-static, called once to set up the initial intfc table */
5187 int
5188 api_sw_interface_dump (vat_main_t * vam)
5189 {
5190   vl_api_sw_interface_dump_t *mp;
5191   vl_api_control_ping_t *mp_ping;
5192   hash_pair_t *p;
5193   name_sort_t *nses = 0, *ns;
5194   sw_interface_subif_t *sub = NULL;
5195   int ret;
5196
5197   /* Toss the old name table */
5198   /* *INDENT-OFF* */
5199   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5200   ({
5201     vec_add2 (nses, ns, 1);
5202     ns->name = (u8 *)(p->key);
5203     ns->value = (u32) p->value[0];
5204   }));
5205   /* *INDENT-ON* */
5206
5207   hash_free (vam->sw_if_index_by_interface_name);
5208
5209   vec_foreach (ns, nses) vec_free (ns->name);
5210
5211   vec_free (nses);
5212
5213   vec_foreach (sub, vam->sw_if_subif_table)
5214   {
5215     vec_free (sub->interface_name);
5216   }
5217   vec_free (vam->sw_if_subif_table);
5218
5219   /* recreate the interface name hash table */
5220   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5221
5222   /* Get list of ethernets */
5223   M (SW_INTERFACE_DUMP, mp);
5224   mp->name_filter_valid = 1;
5225   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
5226   S (mp);
5227
5228   /* and local / loopback interfaces */
5229   M (SW_INTERFACE_DUMP, mp);
5230   mp->name_filter_valid = 1;
5231   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
5232   S (mp);
5233
5234   /* and packet-generator interfaces */
5235   M (SW_INTERFACE_DUMP, mp);
5236   mp->name_filter_valid = 1;
5237   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
5238   S (mp);
5239
5240   /* and vxlan-gpe tunnel interfaces */
5241   M (SW_INTERFACE_DUMP, mp);
5242   mp->name_filter_valid = 1;
5243   strncpy ((char *) mp->name_filter, "vxlan_gpe",
5244            sizeof (mp->name_filter) - 1);
5245   S (mp);
5246
5247   /* and vxlan tunnel interfaces */
5248   M (SW_INTERFACE_DUMP, mp);
5249   mp->name_filter_valid = 1;
5250   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
5251   S (mp);
5252
5253   /* and host (af_packet) interfaces */
5254   M (SW_INTERFACE_DUMP, mp);
5255   mp->name_filter_valid = 1;
5256   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
5257   S (mp);
5258
5259   /* and l2tpv3 tunnel interfaces */
5260   M (SW_INTERFACE_DUMP, mp);
5261   mp->name_filter_valid = 1;
5262   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
5263            sizeof (mp->name_filter) - 1);
5264   S (mp);
5265
5266   /* and GRE tunnel interfaces */
5267   M (SW_INTERFACE_DUMP, mp);
5268   mp->name_filter_valid = 1;
5269   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
5270   S (mp);
5271
5272   /* and LISP-GPE interfaces */
5273   M (SW_INTERFACE_DUMP, mp);
5274   mp->name_filter_valid = 1;
5275   strncpy ((char *) mp->name_filter, "lisp_gpe",
5276            sizeof (mp->name_filter) - 1);
5277   S (mp);
5278
5279   /* and IPSEC tunnel interfaces */
5280   M (SW_INTERFACE_DUMP, mp);
5281   mp->name_filter_valid = 1;
5282   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
5283   S (mp);
5284
5285   /* Use a control ping for synchronization */
5286   M (CONTROL_PING, mp_ping);
5287   S (mp_ping);
5288
5289   W (ret);
5290   return ret;
5291 }
5292
5293 static int
5294 api_sw_interface_set_flags (vat_main_t * vam)
5295 {
5296   unformat_input_t *i = vam->input;
5297   vl_api_sw_interface_set_flags_t *mp;
5298   u32 sw_if_index;
5299   u8 sw_if_index_set = 0;
5300   u8 admin_up = 0, link_up = 0;
5301   int ret;
5302
5303   /* Parse args required to build the message */
5304   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5305     {
5306       if (unformat (i, "admin-up"))
5307         admin_up = 1;
5308       else if (unformat (i, "admin-down"))
5309         admin_up = 0;
5310       else if (unformat (i, "link-up"))
5311         link_up = 1;
5312       else if (unformat (i, "link-down"))
5313         link_up = 0;
5314       else
5315         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5316         sw_if_index_set = 1;
5317       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5318         sw_if_index_set = 1;
5319       else
5320         break;
5321     }
5322
5323   if (sw_if_index_set == 0)
5324     {
5325       errmsg ("missing interface name or sw_if_index");
5326       return -99;
5327     }
5328
5329   /* Construct the API message */
5330   M (SW_INTERFACE_SET_FLAGS, mp);
5331   mp->sw_if_index = ntohl (sw_if_index);
5332   mp->admin_up_down = admin_up;
5333   mp->link_up_down = link_up;
5334
5335   /* send it... */
5336   S (mp);
5337
5338   /* Wait for a reply, return the good/bad news... */
5339   W (ret);
5340   return ret;
5341 }
5342
5343 static int
5344 api_sw_interface_clear_stats (vat_main_t * vam)
5345 {
5346   unformat_input_t *i = vam->input;
5347   vl_api_sw_interface_clear_stats_t *mp;
5348   u32 sw_if_index;
5349   u8 sw_if_index_set = 0;
5350   int ret;
5351
5352   /* Parse args required to build the message */
5353   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5354     {
5355       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5356         sw_if_index_set = 1;
5357       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5358         sw_if_index_set = 1;
5359       else
5360         break;
5361     }
5362
5363   /* Construct the API message */
5364   M (SW_INTERFACE_CLEAR_STATS, mp);
5365
5366   if (sw_if_index_set == 1)
5367     mp->sw_if_index = ntohl (sw_if_index);
5368   else
5369     mp->sw_if_index = ~0;
5370
5371   /* send it... */
5372   S (mp);
5373
5374   /* Wait for a reply, return the good/bad news... */
5375   W (ret);
5376   return ret;
5377 }
5378
5379 static int
5380 api_sw_interface_add_del_address (vat_main_t * vam)
5381 {
5382   unformat_input_t *i = vam->input;
5383   vl_api_sw_interface_add_del_address_t *mp;
5384   u32 sw_if_index;
5385   u8 sw_if_index_set = 0;
5386   u8 is_add = 1, del_all = 0;
5387   u32 address_length = 0;
5388   u8 v4_address_set = 0;
5389   u8 v6_address_set = 0;
5390   ip4_address_t v4address;
5391   ip6_address_t v6address;
5392   int ret;
5393
5394   /* Parse args required to build the message */
5395   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5396     {
5397       if (unformat (i, "del-all"))
5398         del_all = 1;
5399       else if (unformat (i, "del"))
5400         is_add = 0;
5401       else
5402         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5403         sw_if_index_set = 1;
5404       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5405         sw_if_index_set = 1;
5406       else if (unformat (i, "%U/%d",
5407                          unformat_ip4_address, &v4address, &address_length))
5408         v4_address_set = 1;
5409       else if (unformat (i, "%U/%d",
5410                          unformat_ip6_address, &v6address, &address_length))
5411         v6_address_set = 1;
5412       else
5413         break;
5414     }
5415
5416   if (sw_if_index_set == 0)
5417     {
5418       errmsg ("missing interface name or sw_if_index");
5419       return -99;
5420     }
5421   if (v4_address_set && v6_address_set)
5422     {
5423       errmsg ("both v4 and v6 addresses set");
5424       return -99;
5425     }
5426   if (!v4_address_set && !v6_address_set && !del_all)
5427     {
5428       errmsg ("no addresses set");
5429       return -99;
5430     }
5431
5432   /* Construct the API message */
5433   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
5434
5435   mp->sw_if_index = ntohl (sw_if_index);
5436   mp->is_add = is_add;
5437   mp->del_all = del_all;
5438   if (v6_address_set)
5439     {
5440       mp->is_ipv6 = 1;
5441       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5442     }
5443   else
5444     {
5445       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5446     }
5447   mp->address_length = address_length;
5448
5449   /* send it... */
5450   S (mp);
5451
5452   /* Wait for a reply, return good/bad news  */
5453   W (ret);
5454   return ret;
5455 }
5456
5457 static int
5458 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5459 {
5460   unformat_input_t *i = vam->input;
5461   vl_api_sw_interface_set_mpls_enable_t *mp;
5462   u32 sw_if_index;
5463   u8 sw_if_index_set = 0;
5464   u8 enable = 1;
5465   int ret;
5466
5467   /* Parse args required to build the message */
5468   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5469     {
5470       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5471         sw_if_index_set = 1;
5472       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5473         sw_if_index_set = 1;
5474       else if (unformat (i, "disable"))
5475         enable = 0;
5476       else if (unformat (i, "dis"))
5477         enable = 0;
5478       else
5479         break;
5480     }
5481
5482   if (sw_if_index_set == 0)
5483     {
5484       errmsg ("missing interface name or sw_if_index");
5485       return -99;
5486     }
5487
5488   /* Construct the API message */
5489   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
5490
5491   mp->sw_if_index = ntohl (sw_if_index);
5492   mp->enable = enable;
5493
5494   /* send it... */
5495   S (mp);
5496
5497   /* Wait for a reply... */
5498   W (ret);
5499   return ret;
5500 }
5501
5502 static int
5503 api_sw_interface_set_table (vat_main_t * vam)
5504 {
5505   unformat_input_t *i = vam->input;
5506   vl_api_sw_interface_set_table_t *mp;
5507   u32 sw_if_index, vrf_id = 0;
5508   u8 sw_if_index_set = 0;
5509   u8 is_ipv6 = 0;
5510   int ret;
5511
5512   /* Parse args required to build the message */
5513   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5514     {
5515       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5516         sw_if_index_set = 1;
5517       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5518         sw_if_index_set = 1;
5519       else if (unformat (i, "vrf %d", &vrf_id))
5520         ;
5521       else if (unformat (i, "ipv6"))
5522         is_ipv6 = 1;
5523       else
5524         break;
5525     }
5526
5527   if (sw_if_index_set == 0)
5528     {
5529       errmsg ("missing interface name or sw_if_index");
5530       return -99;
5531     }
5532
5533   /* Construct the API message */
5534   M (SW_INTERFACE_SET_TABLE, mp);
5535
5536   mp->sw_if_index = ntohl (sw_if_index);
5537   mp->is_ipv6 = is_ipv6;
5538   mp->vrf_id = ntohl (vrf_id);
5539
5540   /* send it... */
5541   S (mp);
5542
5543   /* Wait for a reply... */
5544   W (ret);
5545   return ret;
5546 }
5547
5548 static void vl_api_sw_interface_get_table_reply_t_handler
5549   (vl_api_sw_interface_get_table_reply_t * mp)
5550 {
5551   vat_main_t *vam = &vat_main;
5552
5553   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5554
5555   vam->retval = ntohl (mp->retval);
5556   vam->result_ready = 1;
5557
5558 }
5559
5560 static void vl_api_sw_interface_get_table_reply_t_handler_json
5561   (vl_api_sw_interface_get_table_reply_t * mp)
5562 {
5563   vat_main_t *vam = &vat_main;
5564   vat_json_node_t node;
5565
5566   vat_json_init_object (&node);
5567   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5568   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5569
5570   vat_json_print (vam->ofp, &node);
5571   vat_json_free (&node);
5572
5573   vam->retval = ntohl (mp->retval);
5574   vam->result_ready = 1;
5575 }
5576
5577 static int
5578 api_sw_interface_get_table (vat_main_t * vam)
5579 {
5580   unformat_input_t *i = vam->input;
5581   vl_api_sw_interface_get_table_t *mp;
5582   u32 sw_if_index;
5583   u8 sw_if_index_set = 0;
5584   u8 is_ipv6 = 0;
5585   int ret;
5586
5587   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5588     {
5589       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5590         sw_if_index_set = 1;
5591       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5592         sw_if_index_set = 1;
5593       else if (unformat (i, "ipv6"))
5594         is_ipv6 = 1;
5595       else
5596         break;
5597     }
5598
5599   if (sw_if_index_set == 0)
5600     {
5601       errmsg ("missing interface name or sw_if_index");
5602       return -99;
5603     }
5604
5605   M (SW_INTERFACE_GET_TABLE, mp);
5606   mp->sw_if_index = htonl (sw_if_index);
5607   mp->is_ipv6 = is_ipv6;
5608
5609   S (mp);
5610   W (ret);
5611   return ret;
5612 }
5613
5614 static int
5615 api_sw_interface_set_vpath (vat_main_t * vam)
5616 {
5617   unformat_input_t *i = vam->input;
5618   vl_api_sw_interface_set_vpath_t *mp;
5619   u32 sw_if_index = 0;
5620   u8 sw_if_index_set = 0;
5621   u8 is_enable = 0;
5622   int ret;
5623
5624   /* Parse args required to build the message */
5625   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5626     {
5627       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5628         sw_if_index_set = 1;
5629       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5630         sw_if_index_set = 1;
5631       else if (unformat (i, "enable"))
5632         is_enable = 1;
5633       else if (unformat (i, "disable"))
5634         is_enable = 0;
5635       else
5636         break;
5637     }
5638
5639   if (sw_if_index_set == 0)
5640     {
5641       errmsg ("missing interface name or sw_if_index");
5642       return -99;
5643     }
5644
5645   /* Construct the API message */
5646   M (SW_INTERFACE_SET_VPATH, mp);
5647
5648   mp->sw_if_index = ntohl (sw_if_index);
5649   mp->enable = is_enable;
5650
5651   /* send it... */
5652   S (mp);
5653
5654   /* Wait for a reply... */
5655   W (ret);
5656   return ret;
5657 }
5658
5659 static int
5660 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5661 {
5662   unformat_input_t *i = vam->input;
5663   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5664   u32 sw_if_index = 0;
5665   u8 sw_if_index_set = 0;
5666   u8 is_enable = 1;
5667   u8 is_ipv6 = 0;
5668   int ret;
5669
5670   /* Parse args required to build the message */
5671   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5672     {
5673       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5674         sw_if_index_set = 1;
5675       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5676         sw_if_index_set = 1;
5677       else if (unformat (i, "enable"))
5678         is_enable = 1;
5679       else if (unformat (i, "disable"))
5680         is_enable = 0;
5681       else if (unformat (i, "ip4"))
5682         is_ipv6 = 0;
5683       else if (unformat (i, "ip6"))
5684         is_ipv6 = 1;
5685       else
5686         break;
5687     }
5688
5689   if (sw_if_index_set == 0)
5690     {
5691       errmsg ("missing interface name or sw_if_index");
5692       return -99;
5693     }
5694
5695   /* Construct the API message */
5696   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
5697
5698   mp->sw_if_index = ntohl (sw_if_index);
5699   mp->enable = is_enable;
5700   mp->is_ipv6 = is_ipv6;
5701
5702   /* send it... */
5703   S (mp);
5704
5705   /* Wait for a reply... */
5706   W (ret);
5707   return ret;
5708 }
5709
5710 static int
5711 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5712 {
5713   unformat_input_t *i = vam->input;
5714   vl_api_sw_interface_set_l2_xconnect_t *mp;
5715   u32 rx_sw_if_index;
5716   u8 rx_sw_if_index_set = 0;
5717   u32 tx_sw_if_index;
5718   u8 tx_sw_if_index_set = 0;
5719   u8 enable = 1;
5720   int ret;
5721
5722   /* Parse args required to build the message */
5723   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5724     {
5725       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5726         rx_sw_if_index_set = 1;
5727       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5728         tx_sw_if_index_set = 1;
5729       else if (unformat (i, "rx"))
5730         {
5731           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5732             {
5733               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5734                             &rx_sw_if_index))
5735                 rx_sw_if_index_set = 1;
5736             }
5737           else
5738             break;
5739         }
5740       else if (unformat (i, "tx"))
5741         {
5742           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5743             {
5744               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5745                             &tx_sw_if_index))
5746                 tx_sw_if_index_set = 1;
5747             }
5748           else
5749             break;
5750         }
5751       else if (unformat (i, "enable"))
5752         enable = 1;
5753       else if (unformat (i, "disable"))
5754         enable = 0;
5755       else
5756         break;
5757     }
5758
5759   if (rx_sw_if_index_set == 0)
5760     {
5761       errmsg ("missing rx interface name or rx_sw_if_index");
5762       return -99;
5763     }
5764
5765   if (enable && (tx_sw_if_index_set == 0))
5766     {
5767       errmsg ("missing tx interface name or tx_sw_if_index");
5768       return -99;
5769     }
5770
5771   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
5772
5773   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5774   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5775   mp->enable = enable;
5776
5777   S (mp);
5778   W (ret);
5779   return ret;
5780 }
5781
5782 static int
5783 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5784 {
5785   unformat_input_t *i = vam->input;
5786   vl_api_sw_interface_set_l2_bridge_t *mp;
5787   u32 rx_sw_if_index;
5788   u8 rx_sw_if_index_set = 0;
5789   u32 bd_id;
5790   u8 bd_id_set = 0;
5791   u8 bvi = 0;
5792   u32 shg = 0;
5793   u8 enable = 1;
5794   int ret;
5795
5796   /* Parse args required to build the message */
5797   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5798     {
5799       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5800         rx_sw_if_index_set = 1;
5801       else if (unformat (i, "bd_id %d", &bd_id))
5802         bd_id_set = 1;
5803       else
5804         if (unformat
5805             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5806         rx_sw_if_index_set = 1;
5807       else if (unformat (i, "shg %d", &shg))
5808         ;
5809       else if (unformat (i, "bvi"))
5810         bvi = 1;
5811       else if (unformat (i, "enable"))
5812         enable = 1;
5813       else if (unformat (i, "disable"))
5814         enable = 0;
5815       else
5816         break;
5817     }
5818
5819   if (rx_sw_if_index_set == 0)
5820     {
5821       errmsg ("missing rx interface name or sw_if_index");
5822       return -99;
5823     }
5824
5825   if (enable && (bd_id_set == 0))
5826     {
5827       errmsg ("missing bridge domain");
5828       return -99;
5829     }
5830
5831   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
5832
5833   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5834   mp->bd_id = ntohl (bd_id);
5835   mp->shg = (u8) shg;
5836   mp->bvi = bvi;
5837   mp->enable = enable;
5838
5839   S (mp);
5840   W (ret);
5841   return ret;
5842 }
5843
5844 static int
5845 api_bridge_domain_dump (vat_main_t * vam)
5846 {
5847   unformat_input_t *i = vam->input;
5848   vl_api_bridge_domain_dump_t *mp;
5849   vl_api_control_ping_t *mp_ping;
5850   u32 bd_id = ~0;
5851   int ret;
5852
5853   /* Parse args required to build the message */
5854   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5855     {
5856       if (unformat (i, "bd_id %d", &bd_id))
5857         ;
5858       else
5859         break;
5860     }
5861
5862   M (BRIDGE_DOMAIN_DUMP, mp);
5863   mp->bd_id = ntohl (bd_id);
5864   S (mp);
5865
5866   /* Use a control ping for synchronization */
5867   M (CONTROL_PING, mp_ping);
5868   S (mp_ping);
5869
5870   W (ret);
5871   return ret;
5872 }
5873
5874 static int
5875 api_bridge_domain_add_del (vat_main_t * vam)
5876 {
5877   unformat_input_t *i = vam->input;
5878   vl_api_bridge_domain_add_del_t *mp;
5879   u32 bd_id = ~0;
5880   u8 is_add = 1;
5881   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5882   u32 mac_age = 0;
5883   int ret;
5884
5885   /* Parse args required to build the message */
5886   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5887     {
5888       if (unformat (i, "bd_id %d", &bd_id))
5889         ;
5890       else if (unformat (i, "flood %d", &flood))
5891         ;
5892       else if (unformat (i, "uu-flood %d", &uu_flood))
5893         ;
5894       else if (unformat (i, "forward %d", &forward))
5895         ;
5896       else if (unformat (i, "learn %d", &learn))
5897         ;
5898       else if (unformat (i, "arp-term %d", &arp_term))
5899         ;
5900       else if (unformat (i, "mac-age %d", &mac_age))
5901         ;
5902       else if (unformat (i, "del"))
5903         {
5904           is_add = 0;
5905           flood = uu_flood = forward = learn = 0;
5906         }
5907       else
5908         break;
5909     }
5910
5911   if (bd_id == ~0)
5912     {
5913       errmsg ("missing bridge domain");
5914       return -99;
5915     }
5916
5917   if (mac_age > 255)
5918     {
5919       errmsg ("mac age must be less than 256 ");
5920       return -99;
5921     }
5922
5923   M (BRIDGE_DOMAIN_ADD_DEL, mp);
5924
5925   mp->bd_id = ntohl (bd_id);
5926   mp->flood = flood;
5927   mp->uu_flood = uu_flood;
5928   mp->forward = forward;
5929   mp->learn = learn;
5930   mp->arp_term = arp_term;
5931   mp->is_add = is_add;
5932   mp->mac_age = (u8) mac_age;
5933
5934   S (mp);
5935   W (ret);
5936   return ret;
5937 }
5938
5939 static int
5940 api_l2fib_flush_bd (vat_main_t * vam)
5941 {
5942   unformat_input_t *i = vam->input;
5943   vl_api_l2fib_flush_bd_t *mp;
5944   u32 bd_id = ~0;
5945   int ret;
5946
5947   /* Parse args required to build the message */
5948   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5949     {
5950       if (unformat (i, "bd_id %d", &bd_id));
5951       else
5952         break;
5953     }
5954
5955   if (bd_id == ~0)
5956     {
5957       errmsg ("missing bridge domain");
5958       return -99;
5959     }
5960
5961   M (L2FIB_FLUSH_BD, mp);
5962
5963   mp->bd_id = htonl (bd_id);
5964
5965   S (mp);
5966   W (ret);
5967   return ret;
5968 }
5969
5970 static int
5971 api_l2fib_flush_int (vat_main_t * vam)
5972 {
5973   unformat_input_t *i = vam->input;
5974   vl_api_l2fib_flush_int_t *mp;
5975   u32 sw_if_index = ~0;
5976   int ret;
5977
5978   /* Parse args required to build the message */
5979   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5980     {
5981       if (unformat (i, "sw_if_index %d", &sw_if_index));
5982       else
5983         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
5984       else
5985         break;
5986     }
5987
5988   if (sw_if_index == ~0)
5989     {
5990       errmsg ("missing interface name or sw_if_index");
5991       return -99;
5992     }
5993
5994   M (L2FIB_FLUSH_INT, mp);
5995
5996   mp->sw_if_index = ntohl (sw_if_index);
5997
5998   S (mp);
5999   W (ret);
6000   return ret;
6001 }
6002
6003 static int
6004 api_l2fib_add_del (vat_main_t * vam)
6005 {
6006   unformat_input_t *i = vam->input;
6007   vl_api_l2fib_add_del_t *mp;
6008   f64 timeout;
6009   u64 mac = 0;
6010   u8 mac_set = 0;
6011   u32 bd_id;
6012   u8 bd_id_set = 0;
6013   u32 sw_if_index = ~0;
6014   u8 sw_if_index_set = 0;
6015   u8 is_add = 1;
6016   u8 static_mac = 0;
6017   u8 filter_mac = 0;
6018   u8 bvi_mac = 0;
6019   int count = 1;
6020   f64 before = 0;
6021   int j;
6022
6023   /* Parse args required to build the message */
6024   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6025     {
6026       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
6027         mac_set = 1;
6028       else if (unformat (i, "bd_id %d", &bd_id))
6029         bd_id_set = 1;
6030       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6031         sw_if_index_set = 1;
6032       else if (unformat (i, "sw_if"))
6033         {
6034           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6035             {
6036               if (unformat
6037                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6038                 sw_if_index_set = 1;
6039             }
6040           else
6041             break;
6042         }
6043       else if (unformat (i, "static"))
6044         static_mac = 1;
6045       else if (unformat (i, "filter"))
6046         {
6047           filter_mac = 1;
6048           static_mac = 1;
6049         }
6050       else if (unformat (i, "bvi"))
6051         {
6052           bvi_mac = 1;
6053           static_mac = 1;
6054         }
6055       else if (unformat (i, "del"))
6056         is_add = 0;
6057       else if (unformat (i, "count %d", &count))
6058         ;
6059       else
6060         break;
6061     }
6062
6063   if (mac_set == 0)
6064     {
6065       errmsg ("missing mac address");
6066       return -99;
6067     }
6068
6069   if (bd_id_set == 0)
6070     {
6071       errmsg ("missing bridge domain");
6072       return -99;
6073     }
6074
6075   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6076     {
6077       errmsg ("missing interface name or sw_if_index");
6078       return -99;
6079     }
6080
6081   if (count > 1)
6082     {
6083       /* Turn on async mode */
6084       vam->async_mode = 1;
6085       vam->async_errors = 0;
6086       before = vat_time_now (vam);
6087     }
6088
6089   for (j = 0; j < count; j++)
6090     {
6091       M (L2FIB_ADD_DEL, mp);
6092
6093       mp->mac = mac;
6094       mp->bd_id = ntohl (bd_id);
6095       mp->is_add = is_add;
6096
6097       if (is_add)
6098         {
6099           mp->sw_if_index = ntohl (sw_if_index);
6100           mp->static_mac = static_mac;
6101           mp->filter_mac = filter_mac;
6102           mp->bvi_mac = bvi_mac;
6103         }
6104       increment_mac_address (&mac);
6105       /* send it... */
6106       S (mp);
6107     }
6108
6109   if (count > 1)
6110     {
6111       vl_api_control_ping_t *mp_ping;
6112       f64 after;
6113
6114       /* Shut off async mode */
6115       vam->async_mode = 0;
6116
6117       M (CONTROL_PING, mp_ping);
6118       S (mp_ping);
6119
6120       timeout = vat_time_now (vam) + 1.0;
6121       while (vat_time_now (vam) < timeout)
6122         if (vam->result_ready == 1)
6123           goto out;
6124       vam->retval = -99;
6125
6126     out:
6127       if (vam->retval == -99)
6128         errmsg ("timeout");
6129
6130       if (vam->async_errors > 0)
6131         {
6132           errmsg ("%d asynchronous errors", vam->async_errors);
6133           vam->retval = -98;
6134         }
6135       vam->async_errors = 0;
6136       after = vat_time_now (vam);
6137
6138       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6139              count, after - before, count / (after - before));
6140     }
6141   else
6142     {
6143       int ret;
6144
6145       /* Wait for a reply... */
6146       W (ret);
6147       return ret;
6148     }
6149   /* Return the good/bad news */
6150   return (vam->retval);
6151 }
6152
6153 static int
6154 api_bridge_domain_set_mac_age (vat_main_t * vam)
6155 {
6156   unformat_input_t *i = vam->input;
6157   vl_api_bridge_domain_set_mac_age_t *mp;
6158   u32 bd_id = ~0;
6159   u32 mac_age = 0;
6160   int ret;
6161
6162   /* Parse args required to build the message */
6163   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6164     {
6165       if (unformat (i, "bd_id %d", &bd_id));
6166       else if (unformat (i, "mac-age %d", &mac_age));
6167       else
6168         break;
6169     }
6170
6171   if (bd_id == ~0)
6172     {
6173       errmsg ("missing bridge domain");
6174       return -99;
6175     }
6176
6177   if (mac_age > 255)
6178     {
6179       errmsg ("mac age must be less than 256 ");
6180       return -99;
6181     }
6182
6183   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6184
6185   mp->bd_id = htonl (bd_id);
6186   mp->mac_age = (u8) mac_age;
6187
6188   S (mp);
6189   W (ret);
6190   return ret;
6191 }
6192
6193 static int
6194 api_l2_flags (vat_main_t * vam)
6195 {
6196   unformat_input_t *i = vam->input;
6197   vl_api_l2_flags_t *mp;
6198   u32 sw_if_index;
6199   u32 feature_bitmap = 0;
6200   u8 sw_if_index_set = 0;
6201   int ret;
6202
6203   /* Parse args required to build the message */
6204   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6205     {
6206       if (unformat (i, "sw_if_index %d", &sw_if_index))
6207         sw_if_index_set = 1;
6208       else if (unformat (i, "sw_if"))
6209         {
6210           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6211             {
6212               if (unformat
6213                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6214                 sw_if_index_set = 1;
6215             }
6216           else
6217             break;
6218         }
6219       else if (unformat (i, "learn"))
6220         feature_bitmap |= L2INPUT_FEAT_LEARN;
6221       else if (unformat (i, "forward"))
6222         feature_bitmap |= L2INPUT_FEAT_FWD;
6223       else if (unformat (i, "flood"))
6224         feature_bitmap |= L2INPUT_FEAT_FLOOD;
6225       else if (unformat (i, "uu-flood"))
6226         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
6227       else
6228         break;
6229     }
6230
6231   if (sw_if_index_set == 0)
6232     {
6233       errmsg ("missing interface name or sw_if_index");
6234       return -99;
6235     }
6236
6237   M (L2_FLAGS, mp);
6238
6239   mp->sw_if_index = ntohl (sw_if_index);
6240   mp->feature_bitmap = ntohl (feature_bitmap);
6241
6242   S (mp);
6243   W (ret);
6244   return ret;
6245 }
6246
6247 static int
6248 api_bridge_flags (vat_main_t * vam)
6249 {
6250   unformat_input_t *i = vam->input;
6251   vl_api_bridge_flags_t *mp;
6252   u32 bd_id;
6253   u8 bd_id_set = 0;
6254   u8 is_set = 1;
6255   u32 flags = 0;
6256   int ret;
6257
6258   /* Parse args required to build the message */
6259   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6260     {
6261       if (unformat (i, "bd_id %d", &bd_id))
6262         bd_id_set = 1;
6263       else if (unformat (i, "learn"))
6264         flags |= L2_LEARN;
6265       else if (unformat (i, "forward"))
6266         flags |= L2_FWD;
6267       else if (unformat (i, "flood"))
6268         flags |= L2_FLOOD;
6269       else if (unformat (i, "uu-flood"))
6270         flags |= L2_UU_FLOOD;
6271       else if (unformat (i, "arp-term"))
6272         flags |= L2_ARP_TERM;
6273       else if (unformat (i, "off"))
6274         is_set = 0;
6275       else if (unformat (i, "disable"))
6276         is_set = 0;
6277       else
6278         break;
6279     }
6280
6281   if (bd_id_set == 0)
6282     {
6283       errmsg ("missing bridge domain");
6284       return -99;
6285     }
6286
6287   M (BRIDGE_FLAGS, mp);
6288
6289   mp->bd_id = ntohl (bd_id);
6290   mp->feature_bitmap = ntohl (flags);
6291   mp->is_set = is_set;
6292
6293   S (mp);
6294   W (ret);
6295   return ret;
6296 }
6297
6298 static int
6299 api_bd_ip_mac_add_del (vat_main_t * vam)
6300 {
6301   unformat_input_t *i = vam->input;
6302   vl_api_bd_ip_mac_add_del_t *mp;
6303   u32 bd_id;
6304   u8 is_ipv6 = 0;
6305   u8 is_add = 1;
6306   u8 bd_id_set = 0;
6307   u8 ip_set = 0;
6308   u8 mac_set = 0;
6309   ip4_address_t v4addr;
6310   ip6_address_t v6addr;
6311   u8 macaddr[6];
6312   int ret;
6313
6314
6315   /* Parse args required to build the message */
6316   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6317     {
6318       if (unformat (i, "bd_id %d", &bd_id))
6319         {
6320           bd_id_set++;
6321         }
6322       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
6323         {
6324           ip_set++;
6325         }
6326       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
6327         {
6328           ip_set++;
6329           is_ipv6++;
6330         }
6331       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
6332         {
6333           mac_set++;
6334         }
6335       else if (unformat (i, "del"))
6336         is_add = 0;
6337       else
6338         break;
6339     }
6340
6341   if (bd_id_set == 0)
6342     {
6343       errmsg ("missing bridge domain");
6344       return -99;
6345     }
6346   else if (ip_set == 0)
6347     {
6348       errmsg ("missing IP address");
6349       return -99;
6350     }
6351   else if (mac_set == 0)
6352     {
6353       errmsg ("missing MAC address");
6354       return -99;
6355     }
6356
6357   M (BD_IP_MAC_ADD_DEL, mp);
6358
6359   mp->bd_id = ntohl (bd_id);
6360   mp->is_ipv6 = is_ipv6;
6361   mp->is_add = is_add;
6362   if (is_ipv6)
6363     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
6364   else
6365     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
6366   clib_memcpy (mp->mac_address, macaddr, 6);
6367   S (mp);
6368   W (ret);
6369   return ret;
6370 }
6371
6372 static int
6373 api_tap_connect (vat_main_t * vam)
6374 {
6375   unformat_input_t *i = vam->input;
6376   vl_api_tap_connect_t *mp;
6377   u8 mac_address[6];
6378   u8 random_mac = 1;
6379   u8 name_set = 0;
6380   u8 *tap_name;
6381   u8 *tag = 0;
6382   ip4_address_t ip4_address;
6383   u32 ip4_mask_width;
6384   int ip4_address_set = 0;
6385   ip6_address_t ip6_address;
6386   u32 ip6_mask_width;
6387   int ip6_address_set = 0;
6388   int ret;
6389
6390   memset (mac_address, 0, sizeof (mac_address));
6391
6392   /* Parse args required to build the message */
6393   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6394     {
6395       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6396         {
6397           random_mac = 0;
6398         }
6399       else if (unformat (i, "random-mac"))
6400         random_mac = 1;
6401       else if (unformat (i, "tapname %s", &tap_name))
6402         name_set = 1;
6403       else if (unformat (i, "tag %s", &tag))
6404         ;
6405       else if (unformat (i, "address %U/%d",
6406                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
6407         ip4_address_set = 1;
6408       else if (unformat (i, "address %U/%d",
6409                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
6410         ip6_address_set = 1;
6411       else
6412         break;
6413     }
6414
6415   if (name_set == 0)
6416     {
6417       errmsg ("missing tap name");
6418       return -99;
6419     }
6420   if (vec_len (tap_name) > 63)
6421     {
6422       errmsg ("tap name too long");
6423       return -99;
6424     }
6425   vec_add1 (tap_name, 0);
6426
6427   if (vec_len (tag) > 63)
6428     {
6429       errmsg ("tag too long");
6430       return -99;
6431     }
6432
6433   /* Construct the API message */
6434   M (TAP_CONNECT, mp);
6435
6436   mp->use_random_mac = random_mac;
6437   clib_memcpy (mp->mac_address, mac_address, 6);
6438   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6439   if (tag)
6440     clib_memcpy (mp->tag, tag, vec_len (tag));
6441
6442   if (ip4_address_set)
6443     {
6444       mp->ip4_address_set = 1;
6445       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6446       mp->ip4_mask_width = ip4_mask_width;
6447     }
6448   if (ip6_address_set)
6449     {
6450       mp->ip6_address_set = 1;
6451       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6452       mp->ip6_mask_width = ip6_mask_width;
6453     }
6454
6455   vec_free (tap_name);
6456   vec_free (tag);
6457
6458   /* send it... */
6459   S (mp);
6460
6461   /* Wait for a reply... */
6462   W (ret);
6463   return ret;
6464 }
6465
6466 static int
6467 api_tap_modify (vat_main_t * vam)
6468 {
6469   unformat_input_t *i = vam->input;
6470   vl_api_tap_modify_t *mp;
6471   u8 mac_address[6];
6472   u8 random_mac = 1;
6473   u8 name_set = 0;
6474   u8 *tap_name;
6475   u32 sw_if_index = ~0;
6476   u8 sw_if_index_set = 0;
6477   int ret;
6478
6479   memset (mac_address, 0, sizeof (mac_address));
6480
6481   /* Parse args required to build the message */
6482   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6483     {
6484       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6485         sw_if_index_set = 1;
6486       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6487         sw_if_index_set = 1;
6488       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6489         {
6490           random_mac = 0;
6491         }
6492       else if (unformat (i, "random-mac"))
6493         random_mac = 1;
6494       else if (unformat (i, "tapname %s", &tap_name))
6495         name_set = 1;
6496       else
6497         break;
6498     }
6499
6500   if (sw_if_index_set == 0)
6501     {
6502       errmsg ("missing vpp interface name");
6503       return -99;
6504     }
6505   if (name_set == 0)
6506     {
6507       errmsg ("missing tap name");
6508       return -99;
6509     }
6510   if (vec_len (tap_name) > 63)
6511     {
6512       errmsg ("tap name too long");
6513     }
6514   vec_add1 (tap_name, 0);
6515
6516   /* Construct the API message */
6517   M (TAP_MODIFY, mp);
6518
6519   mp->use_random_mac = random_mac;
6520   mp->sw_if_index = ntohl (sw_if_index);
6521   clib_memcpy (mp->mac_address, mac_address, 6);
6522   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6523   vec_free (tap_name);
6524
6525   /* send it... */
6526   S (mp);
6527
6528   /* Wait for a reply... */
6529   W (ret);
6530   return ret;
6531 }
6532
6533 static int
6534 api_tap_delete (vat_main_t * vam)
6535 {
6536   unformat_input_t *i = vam->input;
6537   vl_api_tap_delete_t *mp;
6538   u32 sw_if_index = ~0;
6539   u8 sw_if_index_set = 0;
6540   int ret;
6541
6542   /* Parse args required to build the message */
6543   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6544     {
6545       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6546         sw_if_index_set = 1;
6547       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6548         sw_if_index_set = 1;
6549       else
6550         break;
6551     }
6552
6553   if (sw_if_index_set == 0)
6554     {
6555       errmsg ("missing vpp interface name");
6556       return -99;
6557     }
6558
6559   /* Construct the API message */
6560   M (TAP_DELETE, mp);
6561
6562   mp->sw_if_index = ntohl (sw_if_index);
6563
6564   /* send it... */
6565   S (mp);
6566
6567   /* Wait for a reply... */
6568   W (ret);
6569   return ret;
6570 }
6571
6572 static int
6573 api_ip_add_del_route (vat_main_t * vam)
6574 {
6575   unformat_input_t *i = vam->input;
6576   vl_api_ip_add_del_route_t *mp;
6577   u32 sw_if_index = ~0, vrf_id = 0;
6578   u8 is_ipv6 = 0;
6579   u8 is_local = 0, is_drop = 0;
6580   u8 is_unreach = 0, is_prohibit = 0;
6581   u8 create_vrf_if_needed = 0;
6582   u8 is_add = 1;
6583   u32 next_hop_weight = 1;
6584   u8 not_last = 0;
6585   u8 is_multipath = 0;
6586   u8 address_set = 0;
6587   u8 address_length_set = 0;
6588   u32 next_hop_table_id = 0;
6589   u32 resolve_attempts = 0;
6590   u32 dst_address_length = 0;
6591   u8 next_hop_set = 0;
6592   ip4_address_t v4_dst_address, v4_next_hop_address;
6593   ip6_address_t v6_dst_address, v6_next_hop_address;
6594   int count = 1;
6595   int j;
6596   f64 before = 0;
6597   u32 random_add_del = 0;
6598   u32 *random_vector = 0;
6599   uword *random_hash;
6600   u32 random_seed = 0xdeaddabe;
6601   u32 classify_table_index = ~0;
6602   u8 is_classify = 0;
6603   u8 resolve_host = 0, resolve_attached = 0;
6604   mpls_label_t *next_hop_out_label_stack = NULL;
6605   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6606   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6607
6608   /* Parse args required to build the message */
6609   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6610     {
6611       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6612         ;
6613       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6614         ;
6615       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6616         {
6617           address_set = 1;
6618           is_ipv6 = 0;
6619         }
6620       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6621         {
6622           address_set = 1;
6623           is_ipv6 = 1;
6624         }
6625       else if (unformat (i, "/%d", &dst_address_length))
6626         {
6627           address_length_set = 1;
6628         }
6629
6630       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6631                                          &v4_next_hop_address))
6632         {
6633           next_hop_set = 1;
6634         }
6635       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6636                                          &v6_next_hop_address))
6637         {
6638           next_hop_set = 1;
6639         }
6640       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6641         ;
6642       else if (unformat (i, "weight %d", &next_hop_weight))
6643         ;
6644       else if (unformat (i, "drop"))
6645         {
6646           is_drop = 1;
6647         }
6648       else if (unformat (i, "null-send-unreach"))
6649         {
6650           is_unreach = 1;
6651         }
6652       else if (unformat (i, "null-send-prohibit"))
6653         {
6654           is_prohibit = 1;
6655         }
6656       else if (unformat (i, "local"))
6657         {
6658           is_local = 1;
6659         }
6660       else if (unformat (i, "classify %d", &classify_table_index))
6661         {
6662           is_classify = 1;
6663         }
6664       else if (unformat (i, "del"))
6665         is_add = 0;
6666       else if (unformat (i, "add"))
6667         is_add = 1;
6668       else if (unformat (i, "not-last"))
6669         not_last = 1;
6670       else if (unformat (i, "resolve-via-host"))
6671         resolve_host = 1;
6672       else if (unformat (i, "resolve-via-attached"))
6673         resolve_attached = 1;
6674       else if (unformat (i, "multipath"))
6675         is_multipath = 1;
6676       else if (unformat (i, "vrf %d", &vrf_id))
6677         ;
6678       else if (unformat (i, "create-vrf"))
6679         create_vrf_if_needed = 1;
6680       else if (unformat (i, "count %d", &count))
6681         ;
6682       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6683         ;
6684       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6685         ;
6686       else if (unformat (i, "out-label %d", &next_hop_out_label))
6687         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6688       else if (unformat (i, "via-label %d", &next_hop_via_label))
6689         ;
6690       else if (unformat (i, "random"))
6691         random_add_del = 1;
6692       else if (unformat (i, "seed %d", &random_seed))
6693         ;
6694       else
6695         {
6696           clib_warning ("parse error '%U'", format_unformat_error, i);
6697           return -99;
6698         }
6699     }
6700
6701   if (!next_hop_set && !is_drop && !is_local &&
6702       !is_classify && !is_unreach && !is_prohibit &&
6703       MPLS_LABEL_INVALID == next_hop_via_label)
6704     {
6705       errmsg
6706         ("next hop / local / drop / unreach / prohibit / classify not set");
6707       return -99;
6708     }
6709
6710   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6711     {
6712       errmsg ("next hop and next-hop via label set");
6713       return -99;
6714     }
6715   if (address_set == 0)
6716     {
6717       errmsg ("missing addresses");
6718       return -99;
6719     }
6720
6721   if (address_length_set == 0)
6722     {
6723       errmsg ("missing address length");
6724       return -99;
6725     }
6726
6727   /* Generate a pile of unique, random routes */
6728   if (random_add_del)
6729     {
6730       u32 this_random_address;
6731       random_hash = hash_create (count, sizeof (uword));
6732
6733       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6734       for (j = 0; j <= count; j++)
6735         {
6736           do
6737             {
6738               this_random_address = random_u32 (&random_seed);
6739               this_random_address =
6740                 clib_host_to_net_u32 (this_random_address);
6741             }
6742           while (hash_get (random_hash, this_random_address));
6743           vec_add1 (random_vector, this_random_address);
6744           hash_set (random_hash, this_random_address, 1);
6745         }
6746       hash_free (random_hash);
6747       v4_dst_address.as_u32 = random_vector[0];
6748     }
6749
6750   if (count > 1)
6751     {
6752       /* Turn on async mode */
6753       vam->async_mode = 1;
6754       vam->async_errors = 0;
6755       before = vat_time_now (vam);
6756     }
6757
6758   for (j = 0; j < count; j++)
6759     {
6760       /* Construct the API message */
6761       M2 (IP_ADD_DEL_ROUTE, mp,
6762           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6763
6764       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6765       mp->table_id = ntohl (vrf_id);
6766       mp->create_vrf_if_needed = create_vrf_if_needed;
6767
6768       mp->is_add = is_add;
6769       mp->is_drop = is_drop;
6770       mp->is_unreach = is_unreach;
6771       mp->is_prohibit = is_prohibit;
6772       mp->is_ipv6 = is_ipv6;
6773       mp->is_local = is_local;
6774       mp->is_classify = is_classify;
6775       mp->is_multipath = is_multipath;
6776       mp->is_resolve_host = resolve_host;
6777       mp->is_resolve_attached = resolve_attached;
6778       mp->not_last = not_last;
6779       mp->next_hop_weight = next_hop_weight;
6780       mp->dst_address_length = dst_address_length;
6781       mp->next_hop_table_id = ntohl (next_hop_table_id);
6782       mp->classify_table_index = ntohl (classify_table_index);
6783       mp->next_hop_via_label = ntohl (next_hop_via_label);
6784       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6785       if (0 != mp->next_hop_n_out_labels)
6786         {
6787           memcpy (mp->next_hop_out_label_stack,
6788                   next_hop_out_label_stack,
6789                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6790           vec_free (next_hop_out_label_stack);
6791         }
6792
6793       if (is_ipv6)
6794         {
6795           clib_memcpy (mp->dst_address, &v6_dst_address,
6796                        sizeof (v6_dst_address));
6797           if (next_hop_set)
6798             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6799                          sizeof (v6_next_hop_address));
6800           increment_v6_address (&v6_dst_address);
6801         }
6802       else
6803         {
6804           clib_memcpy (mp->dst_address, &v4_dst_address,
6805                        sizeof (v4_dst_address));
6806           if (next_hop_set)
6807             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6808                          sizeof (v4_next_hop_address));
6809           if (random_add_del)
6810             v4_dst_address.as_u32 = random_vector[j + 1];
6811           else
6812             increment_v4_address (&v4_dst_address);
6813         }
6814       /* send it... */
6815       S (mp);
6816       /* If we receive SIGTERM, stop now... */
6817       if (vam->do_exit)
6818         break;
6819     }
6820
6821   /* When testing multiple add/del ops, use a control-ping to sync */
6822   if (count > 1)
6823     {
6824       vl_api_control_ping_t *mp_ping;
6825       f64 after;
6826       f64 timeout;
6827
6828       /* Shut off async mode */
6829       vam->async_mode = 0;
6830
6831       M (CONTROL_PING, mp_ping);
6832       S (mp_ping);
6833
6834       timeout = vat_time_now (vam) + 1.0;
6835       while (vat_time_now (vam) < timeout)
6836         if (vam->result_ready == 1)
6837           goto out;
6838       vam->retval = -99;
6839
6840     out:
6841       if (vam->retval == -99)
6842         errmsg ("timeout");
6843
6844       if (vam->async_errors > 0)
6845         {
6846           errmsg ("%d asynchronous errors", vam->async_errors);
6847           vam->retval = -98;
6848         }
6849       vam->async_errors = 0;
6850       after = vat_time_now (vam);
6851
6852       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6853       if (j > 0)
6854         count = j;
6855
6856       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6857              count, after - before, count / (after - before));
6858     }
6859   else
6860     {
6861       int ret;
6862
6863       /* Wait for a reply... */
6864       W (ret);
6865       return ret;
6866     }
6867
6868   /* Return the good/bad news */
6869   return (vam->retval);
6870 }
6871
6872 static int
6873 api_ip_mroute_add_del (vat_main_t * vam)
6874 {
6875   unformat_input_t *i = vam->input;
6876   vl_api_ip_mroute_add_del_t *mp;
6877   u32 sw_if_index = ~0, vrf_id = 0;
6878   u8 is_ipv6 = 0;
6879   u8 is_local = 0;
6880   u8 create_vrf_if_needed = 0;
6881   u8 is_add = 1;
6882   u8 address_set = 0;
6883   u32 grp_address_length = 0;
6884   ip4_address_t v4_grp_address, v4_src_address;
6885   ip6_address_t v6_grp_address, v6_src_address;
6886   mfib_itf_flags_t iflags = 0;
6887   mfib_entry_flags_t eflags = 0;
6888   int ret;
6889
6890   /* Parse args required to build the message */
6891   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6892     {
6893       if (unformat (i, "sw_if_index %d", &sw_if_index))
6894         ;
6895       else if (unformat (i, "%U %U",
6896                          unformat_ip4_address, &v4_src_address,
6897                          unformat_ip4_address, &v4_grp_address))
6898         {
6899           grp_address_length = 64;
6900           address_set = 1;
6901           is_ipv6 = 0;
6902         }
6903       else if (unformat (i, "%U %U",
6904                          unformat_ip6_address, &v6_src_address,
6905                          unformat_ip6_address, &v6_grp_address))
6906         {
6907           grp_address_length = 256;
6908           address_set = 1;
6909           is_ipv6 = 1;
6910         }
6911       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
6912         {
6913           memset (&v4_src_address, 0, sizeof (v4_src_address));
6914           grp_address_length = 32;
6915           address_set = 1;
6916           is_ipv6 = 0;
6917         }
6918       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
6919         {
6920           memset (&v6_src_address, 0, sizeof (v6_src_address));
6921           grp_address_length = 128;
6922           address_set = 1;
6923           is_ipv6 = 1;
6924         }
6925       else if (unformat (i, "/%d", &grp_address_length))
6926         ;
6927       else if (unformat (i, "local"))
6928         {
6929           is_local = 1;
6930         }
6931       else if (unformat (i, "del"))
6932         is_add = 0;
6933       else if (unformat (i, "add"))
6934         is_add = 1;
6935       else if (unformat (i, "vrf %d", &vrf_id))
6936         ;
6937       else if (unformat (i, "create-vrf"))
6938         create_vrf_if_needed = 1;
6939       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
6940         ;
6941       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6942         ;
6943       else
6944         {
6945           clib_warning ("parse error '%U'", format_unformat_error, i);
6946           return -99;
6947         }
6948     }
6949
6950   if (address_set == 0)
6951     {
6952       errmsg ("missing addresses\n");
6953       return -99;
6954     }
6955
6956   /* Construct the API message */
6957   M (IP_MROUTE_ADD_DEL, mp);
6958
6959   mp->next_hop_sw_if_index = ntohl (sw_if_index);
6960   mp->table_id = ntohl (vrf_id);
6961   mp->create_vrf_if_needed = create_vrf_if_needed;
6962
6963   mp->is_add = is_add;
6964   mp->is_ipv6 = is_ipv6;
6965   mp->is_local = is_local;
6966   mp->itf_flags = ntohl (iflags);
6967   mp->entry_flags = ntohl (eflags);
6968   mp->grp_address_length = grp_address_length;
6969   mp->grp_address_length = ntohs (mp->grp_address_length);
6970
6971   if (is_ipv6)
6972     {
6973       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
6974       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
6975     }
6976   else
6977     {
6978       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
6979       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
6980
6981     }
6982
6983   /* send it... */
6984   S (mp);
6985   /* Wait for a reply... */
6986   W (ret);
6987   return ret;
6988 }
6989
6990 static int
6991 api_mpls_route_add_del (vat_main_t * vam)
6992 {
6993   unformat_input_t *i = vam->input;
6994   vl_api_mpls_route_add_del_t *mp;
6995   u32 sw_if_index = ~0, table_id = 0;
6996   u8 create_table_if_needed = 0;
6997   u8 is_add = 1;
6998   u32 next_hop_weight = 1;
6999   u8 is_multipath = 0;
7000   u32 next_hop_table_id = 0;
7001   u8 next_hop_set = 0;
7002   ip4_address_t v4_next_hop_address = {
7003     .as_u32 = 0,
7004   };
7005   ip6_address_t v6_next_hop_address = { {0} };
7006   int count = 1;
7007   int j;
7008   f64 before = 0;
7009   u32 classify_table_index = ~0;
7010   u8 is_classify = 0;
7011   u8 resolve_host = 0, resolve_attached = 0;
7012   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7013   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7014   mpls_label_t *next_hop_out_label_stack = NULL;
7015   mpls_label_t local_label = MPLS_LABEL_INVALID;
7016   u8 is_eos = 0;
7017   u8 next_hop_proto_is_ip4 = 1;
7018
7019   /* Parse args required to build the message */
7020   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7021     {
7022       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7023         ;
7024       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7025         ;
7026       else if (unformat (i, "%d", &local_label))
7027         ;
7028       else if (unformat (i, "eos"))
7029         is_eos = 1;
7030       else if (unformat (i, "non-eos"))
7031         is_eos = 0;
7032       else if (unformat (i, "via %U", unformat_ip4_address,
7033                          &v4_next_hop_address))
7034         {
7035           next_hop_set = 1;
7036           next_hop_proto_is_ip4 = 1;
7037         }
7038       else if (unformat (i, "via %U", unformat_ip6_address,
7039                          &v6_next_hop_address))
7040         {
7041           next_hop_set = 1;
7042           next_hop_proto_is_ip4 = 0;
7043         }
7044       else if (unformat (i, "weight %d", &next_hop_weight))
7045         ;
7046       else if (unformat (i, "create-table"))
7047         create_table_if_needed = 1;
7048       else if (unformat (i, "classify %d", &classify_table_index))
7049         {
7050           is_classify = 1;
7051         }
7052       else if (unformat (i, "del"))
7053         is_add = 0;
7054       else if (unformat (i, "add"))
7055         is_add = 1;
7056       else if (unformat (i, "resolve-via-host"))
7057         resolve_host = 1;
7058       else if (unformat (i, "resolve-via-attached"))
7059         resolve_attached = 1;
7060       else if (unformat (i, "multipath"))
7061         is_multipath = 1;
7062       else if (unformat (i, "count %d", &count))
7063         ;
7064       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
7065         {
7066           next_hop_set = 1;
7067           next_hop_proto_is_ip4 = 1;
7068         }
7069       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
7070         {
7071           next_hop_set = 1;
7072           next_hop_proto_is_ip4 = 0;
7073         }
7074       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7075         ;
7076       else if (unformat (i, "via-label %d", &next_hop_via_label))
7077         ;
7078       else if (unformat (i, "out-label %d", &next_hop_out_label))
7079         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7080       else
7081         {
7082           clib_warning ("parse error '%U'", format_unformat_error, i);
7083           return -99;
7084         }
7085     }
7086
7087   if (!next_hop_set && !is_classify)
7088     {
7089       errmsg ("next hop / classify not set");
7090       return -99;
7091     }
7092
7093   if (MPLS_LABEL_INVALID == local_label)
7094     {
7095       errmsg ("missing label");
7096       return -99;
7097     }
7098
7099   if (count > 1)
7100     {
7101       /* Turn on async mode */
7102       vam->async_mode = 1;
7103       vam->async_errors = 0;
7104       before = vat_time_now (vam);
7105     }
7106
7107   for (j = 0; j < count; j++)
7108     {
7109       /* Construct the API message */
7110       M2 (MPLS_ROUTE_ADD_DEL, mp,
7111           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7112
7113       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
7114       mp->mr_table_id = ntohl (table_id);
7115       mp->mr_create_table_if_needed = create_table_if_needed;
7116
7117       mp->mr_is_add = is_add;
7118       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7119       mp->mr_is_classify = is_classify;
7120       mp->mr_is_multipath = is_multipath;
7121       mp->mr_is_resolve_host = resolve_host;
7122       mp->mr_is_resolve_attached = resolve_attached;
7123       mp->mr_next_hop_weight = next_hop_weight;
7124       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
7125       mp->mr_classify_table_index = ntohl (classify_table_index);
7126       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
7127       mp->mr_label = ntohl (local_label);
7128       mp->mr_eos = is_eos;
7129
7130       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7131       if (0 != mp->mr_next_hop_n_out_labels)
7132         {
7133           memcpy (mp->mr_next_hop_out_label_stack,
7134                   next_hop_out_label_stack,
7135                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7136           vec_free (next_hop_out_label_stack);
7137         }
7138
7139       if (next_hop_set)
7140         {
7141           if (next_hop_proto_is_ip4)
7142             {
7143               clib_memcpy (mp->mr_next_hop,
7144                            &v4_next_hop_address,
7145                            sizeof (v4_next_hop_address));
7146             }
7147           else
7148             {
7149               clib_memcpy (mp->mr_next_hop,
7150                            &v6_next_hop_address,
7151                            sizeof (v6_next_hop_address));
7152             }
7153         }
7154       local_label++;
7155
7156       /* send it... */
7157       S (mp);
7158       /* If we receive SIGTERM, stop now... */
7159       if (vam->do_exit)
7160         break;
7161     }
7162
7163   /* When testing multiple add/del ops, use a control-ping to sync */
7164   if (count > 1)
7165     {
7166       vl_api_control_ping_t *mp_ping;
7167       f64 after;
7168       f64 timeout;
7169
7170       /* Shut off async mode */
7171       vam->async_mode = 0;
7172
7173       M (CONTROL_PING, mp_ping);
7174       S (mp_ping);
7175
7176       timeout = vat_time_now (vam) + 1.0;
7177       while (vat_time_now (vam) < timeout)
7178         if (vam->result_ready == 1)
7179           goto out;
7180       vam->retval = -99;
7181
7182     out:
7183       if (vam->retval == -99)
7184         errmsg ("timeout");
7185
7186       if (vam->async_errors > 0)
7187         {
7188           errmsg ("%d asynchronous errors", vam->async_errors);
7189           vam->retval = -98;
7190         }
7191       vam->async_errors = 0;
7192       after = vat_time_now (vam);
7193
7194       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7195       if (j > 0)
7196         count = j;
7197
7198       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7199              count, after - before, count / (after - before));
7200     }
7201   else
7202     {
7203       int ret;
7204
7205       /* Wait for a reply... */
7206       W (ret);
7207       return ret;
7208     }
7209
7210   /* Return the good/bad news */
7211   return (vam->retval);
7212 }
7213
7214 static int
7215 api_mpls_ip_bind_unbind (vat_main_t * vam)
7216 {
7217   unformat_input_t *i = vam->input;
7218   vl_api_mpls_ip_bind_unbind_t *mp;
7219   u32 ip_table_id = 0;
7220   u8 create_table_if_needed = 0;
7221   u8 is_bind = 1;
7222   u8 is_ip4 = 1;
7223   ip4_address_t v4_address;
7224   ip6_address_t v6_address;
7225   u32 address_length;
7226   u8 address_set = 0;
7227   mpls_label_t local_label = MPLS_LABEL_INVALID;
7228   int ret;
7229
7230   /* Parse args required to build the message */
7231   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7232     {
7233       if (unformat (i, "%U/%d", unformat_ip4_address,
7234                     &v4_address, &address_length))
7235         {
7236           is_ip4 = 1;
7237           address_set = 1;
7238         }
7239       else if (unformat (i, "%U/%d", unformat_ip6_address,
7240                          &v6_address, &address_length))
7241         {
7242           is_ip4 = 0;
7243           address_set = 1;
7244         }
7245       else if (unformat (i, "%d", &local_label))
7246         ;
7247       else if (unformat (i, "create-table"))
7248         create_table_if_needed = 1;
7249       else if (unformat (i, "table-id %d", &ip_table_id))
7250         ;
7251       else if (unformat (i, "unbind"))
7252         is_bind = 0;
7253       else if (unformat (i, "bind"))
7254         is_bind = 1;
7255       else
7256         {
7257           clib_warning ("parse error '%U'", format_unformat_error, i);
7258           return -99;
7259         }
7260     }
7261
7262   if (!address_set)
7263     {
7264       errmsg ("IP addres not set");
7265       return -99;
7266     }
7267
7268   if (MPLS_LABEL_INVALID == local_label)
7269     {
7270       errmsg ("missing label");
7271       return -99;
7272     }
7273
7274   /* Construct the API message */
7275   M (MPLS_IP_BIND_UNBIND, mp);
7276
7277   mp->mb_create_table_if_needed = create_table_if_needed;
7278   mp->mb_is_bind = is_bind;
7279   mp->mb_is_ip4 = is_ip4;
7280   mp->mb_ip_table_id = ntohl (ip_table_id);
7281   mp->mb_mpls_table_id = 0;
7282   mp->mb_label = ntohl (local_label);
7283   mp->mb_address_length = address_length;
7284
7285   if (is_ip4)
7286     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
7287   else
7288     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
7289
7290   /* send it... */
7291   S (mp);
7292
7293   /* Wait for a reply... */
7294   W (ret);
7295   return ret;
7296 }
7297
7298 static int
7299 api_proxy_arp_add_del (vat_main_t * vam)
7300 {
7301   unformat_input_t *i = vam->input;
7302   vl_api_proxy_arp_add_del_t *mp;
7303   u32 vrf_id = 0;
7304   u8 is_add = 1;
7305   ip4_address_t lo, hi;
7306   u8 range_set = 0;
7307   int ret;
7308
7309   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7310     {
7311       if (unformat (i, "vrf %d", &vrf_id))
7312         ;
7313       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
7314                          unformat_ip4_address, &hi))
7315         range_set = 1;
7316       else if (unformat (i, "del"))
7317         is_add = 0;
7318       else
7319         {
7320           clib_warning ("parse error '%U'", format_unformat_error, i);
7321           return -99;
7322         }
7323     }
7324
7325   if (range_set == 0)
7326     {
7327       errmsg ("address range not set");
7328       return -99;
7329     }
7330
7331   M (PROXY_ARP_ADD_DEL, mp);
7332
7333   mp->vrf_id = ntohl (vrf_id);
7334   mp->is_add = is_add;
7335   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
7336   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
7337
7338   S (mp);
7339   W (ret);
7340   return ret;
7341 }
7342
7343 static int
7344 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
7345 {
7346   unformat_input_t *i = vam->input;
7347   vl_api_proxy_arp_intfc_enable_disable_t *mp;
7348   u32 sw_if_index;
7349   u8 enable = 1;
7350   u8 sw_if_index_set = 0;
7351   int ret;
7352
7353   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7354     {
7355       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7356         sw_if_index_set = 1;
7357       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7358         sw_if_index_set = 1;
7359       else if (unformat (i, "enable"))
7360         enable = 1;
7361       else if (unformat (i, "disable"))
7362         enable = 0;
7363       else
7364         {
7365           clib_warning ("parse error '%U'", format_unformat_error, i);
7366           return -99;
7367         }
7368     }
7369
7370   if (sw_if_index_set == 0)
7371     {
7372       errmsg ("missing interface name or sw_if_index");
7373       return -99;
7374     }
7375
7376   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
7377
7378   mp->sw_if_index = ntohl (sw_if_index);
7379   mp->enable_disable = enable;
7380
7381   S (mp);
7382   W (ret);
7383   return ret;
7384 }
7385
7386 static int
7387 api_mpls_tunnel_add_del (vat_main_t * vam)
7388 {
7389   unformat_input_t *i = vam->input;
7390   vl_api_mpls_tunnel_add_del_t *mp;
7391
7392   u8 is_add = 1;
7393   u8 l2_only = 0;
7394   u32 sw_if_index = ~0;
7395   u32 next_hop_sw_if_index = ~0;
7396   u32 next_hop_proto_is_ip4 = 1;
7397
7398   u32 next_hop_table_id = 0;
7399   ip4_address_t v4_next_hop_address = {
7400     .as_u32 = 0,
7401   };
7402   ip6_address_t v6_next_hop_address = { {0} };
7403   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
7404   int ret;
7405
7406   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7407     {
7408       if (unformat (i, "add"))
7409         is_add = 1;
7410       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7411         is_add = 0;
7412       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7413         ;
7414       else if (unformat (i, "via %U",
7415                          unformat_ip4_address, &v4_next_hop_address))
7416         {
7417           next_hop_proto_is_ip4 = 1;
7418         }
7419       else if (unformat (i, "via %U",
7420                          unformat_ip6_address, &v6_next_hop_address))
7421         {
7422           next_hop_proto_is_ip4 = 0;
7423         }
7424       else if (unformat (i, "l2-only"))
7425         l2_only = 1;
7426       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7427         ;
7428       else if (unformat (i, "out-label %d", &next_hop_out_label))
7429         vec_add1 (labels, ntohl (next_hop_out_label));
7430       else
7431         {
7432           clib_warning ("parse error '%U'", format_unformat_error, i);
7433           return -99;
7434         }
7435     }
7436
7437   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
7438
7439   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
7440   mp->mt_sw_if_index = ntohl (sw_if_index);
7441   mp->mt_is_add = is_add;
7442   mp->mt_l2_only = l2_only;
7443   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
7444   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7445
7446   mp->mt_next_hop_n_out_labels = vec_len (labels);
7447
7448   if (0 != mp->mt_next_hop_n_out_labels)
7449     {
7450       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7451                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7452       vec_free (labels);
7453     }
7454
7455   if (next_hop_proto_is_ip4)
7456     {
7457       clib_memcpy (mp->mt_next_hop,
7458                    &v4_next_hop_address, sizeof (v4_next_hop_address));
7459     }
7460   else
7461     {
7462       clib_memcpy (mp->mt_next_hop,
7463                    &v6_next_hop_address, sizeof (v6_next_hop_address));
7464     }
7465
7466   S (mp);
7467   W (ret);
7468   return ret;
7469 }
7470
7471 static int
7472 api_sw_interface_set_unnumbered (vat_main_t * vam)
7473 {
7474   unformat_input_t *i = vam->input;
7475   vl_api_sw_interface_set_unnumbered_t *mp;
7476   u32 sw_if_index;
7477   u32 unnum_sw_index = ~0;
7478   u8 is_add = 1;
7479   u8 sw_if_index_set = 0;
7480   int ret;
7481
7482   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7483     {
7484       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7485         sw_if_index_set = 1;
7486       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7487         sw_if_index_set = 1;
7488       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7489         ;
7490       else if (unformat (i, "del"))
7491         is_add = 0;
7492       else
7493         {
7494           clib_warning ("parse error '%U'", format_unformat_error, i);
7495           return -99;
7496         }
7497     }
7498
7499   if (sw_if_index_set == 0)
7500     {
7501       errmsg ("missing interface name or sw_if_index");
7502       return -99;
7503     }
7504
7505   M (SW_INTERFACE_SET_UNNUMBERED, mp);
7506
7507   mp->sw_if_index = ntohl (sw_if_index);
7508   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7509   mp->is_add = is_add;
7510
7511   S (mp);
7512   W (ret);
7513   return ret;
7514 }
7515
7516 static int
7517 api_ip_neighbor_add_del (vat_main_t * vam)
7518 {
7519   unformat_input_t *i = vam->input;
7520   vl_api_ip_neighbor_add_del_t *mp;
7521   u32 sw_if_index;
7522   u8 sw_if_index_set = 0;
7523   u8 is_add = 1;
7524   u8 is_static = 0;
7525   u8 is_no_fib_entry = 0;
7526   u8 mac_address[6];
7527   u8 mac_set = 0;
7528   u8 v4_address_set = 0;
7529   u8 v6_address_set = 0;
7530   ip4_address_t v4address;
7531   ip6_address_t v6address;
7532   int ret;
7533
7534   memset (mac_address, 0, sizeof (mac_address));
7535
7536   /* Parse args required to build the message */
7537   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7538     {
7539       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7540         {
7541           mac_set = 1;
7542         }
7543       else if (unformat (i, "del"))
7544         is_add = 0;
7545       else
7546         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7547         sw_if_index_set = 1;
7548       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7549         sw_if_index_set = 1;
7550       else if (unformat (i, "is_static"))
7551         is_static = 1;
7552       else if (unformat (i, "no-fib-entry"))
7553         is_no_fib_entry = 1;
7554       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
7555         v4_address_set = 1;
7556       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
7557         v6_address_set = 1;
7558       else
7559         {
7560           clib_warning ("parse error '%U'", format_unformat_error, i);
7561           return -99;
7562         }
7563     }
7564
7565   if (sw_if_index_set == 0)
7566     {
7567       errmsg ("missing interface name or sw_if_index");
7568       return -99;
7569     }
7570   if (v4_address_set && v6_address_set)
7571     {
7572       errmsg ("both v4 and v6 addresses set");
7573       return -99;
7574     }
7575   if (!v4_address_set && !v6_address_set)
7576     {
7577       errmsg ("no address set");
7578       return -99;
7579     }
7580
7581   /* Construct the API message */
7582   M (IP_NEIGHBOR_ADD_DEL, mp);
7583
7584   mp->sw_if_index = ntohl (sw_if_index);
7585   mp->is_add = is_add;
7586   mp->is_static = is_static;
7587   mp->is_no_adj_fib = is_no_fib_entry;
7588   if (mac_set)
7589     clib_memcpy (mp->mac_address, mac_address, 6);
7590   if (v6_address_set)
7591     {
7592       mp->is_ipv6 = 1;
7593       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
7594     }
7595   else
7596     {
7597       /* mp->is_ipv6 = 0; via memset in M macro above */
7598       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
7599     }
7600
7601   /* send it... */
7602   S (mp);
7603
7604   /* Wait for a reply, return good/bad news  */
7605   W (ret);
7606   return ret;
7607 }
7608
7609 static int
7610 api_reset_vrf (vat_main_t * vam)
7611 {
7612   unformat_input_t *i = vam->input;
7613   vl_api_reset_vrf_t *mp;
7614   u32 vrf_id = 0;
7615   u8 is_ipv6 = 0;
7616   u8 vrf_id_set = 0;
7617   int ret;
7618
7619   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7620     {
7621       if (unformat (i, "vrf %d", &vrf_id))
7622         vrf_id_set = 1;
7623       else if (unformat (i, "ipv6"))
7624         is_ipv6 = 1;
7625       else
7626         {
7627           clib_warning ("parse error '%U'", format_unformat_error, i);
7628           return -99;
7629         }
7630     }
7631
7632   if (vrf_id_set == 0)
7633     {
7634       errmsg ("missing vrf id");
7635       return -99;
7636     }
7637
7638   M (RESET_VRF, mp);
7639
7640   mp->vrf_id = ntohl (vrf_id);
7641   mp->is_ipv6 = is_ipv6;
7642
7643   S (mp);
7644   W (ret);
7645   return ret;
7646 }
7647
7648 static int
7649 api_create_vlan_subif (vat_main_t * vam)
7650 {
7651   unformat_input_t *i = vam->input;
7652   vl_api_create_vlan_subif_t *mp;
7653   u32 sw_if_index;
7654   u8 sw_if_index_set = 0;
7655   u32 vlan_id;
7656   u8 vlan_id_set = 0;
7657   int ret;
7658
7659   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7660     {
7661       if (unformat (i, "sw_if_index %d", &sw_if_index))
7662         sw_if_index_set = 1;
7663       else
7664         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7665         sw_if_index_set = 1;
7666       else if (unformat (i, "vlan %d", &vlan_id))
7667         vlan_id_set = 1;
7668       else
7669         {
7670           clib_warning ("parse error '%U'", format_unformat_error, i);
7671           return -99;
7672         }
7673     }
7674
7675   if (sw_if_index_set == 0)
7676     {
7677       errmsg ("missing interface name or sw_if_index");
7678       return -99;
7679     }
7680
7681   if (vlan_id_set == 0)
7682     {
7683       errmsg ("missing vlan_id");
7684       return -99;
7685     }
7686   M (CREATE_VLAN_SUBIF, mp);
7687
7688   mp->sw_if_index = ntohl (sw_if_index);
7689   mp->vlan_id = ntohl (vlan_id);
7690
7691   S (mp);
7692   W (ret);
7693   return ret;
7694 }
7695
7696 #define foreach_create_subif_bit                \
7697 _(no_tags)                                      \
7698 _(one_tag)                                      \
7699 _(two_tags)                                     \
7700 _(dot1ad)                                       \
7701 _(exact_match)                                  \
7702 _(default_sub)                                  \
7703 _(outer_vlan_id_any)                            \
7704 _(inner_vlan_id_any)
7705
7706 static int
7707 api_create_subif (vat_main_t * vam)
7708 {
7709   unformat_input_t *i = vam->input;
7710   vl_api_create_subif_t *mp;
7711   u32 sw_if_index;
7712   u8 sw_if_index_set = 0;
7713   u32 sub_id;
7714   u8 sub_id_set = 0;
7715   u32 no_tags = 0;
7716   u32 one_tag = 0;
7717   u32 two_tags = 0;
7718   u32 dot1ad = 0;
7719   u32 exact_match = 0;
7720   u32 default_sub = 0;
7721   u32 outer_vlan_id_any = 0;
7722   u32 inner_vlan_id_any = 0;
7723   u32 tmp;
7724   u16 outer_vlan_id = 0;
7725   u16 inner_vlan_id = 0;
7726   int ret;
7727
7728   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7729     {
7730       if (unformat (i, "sw_if_index %d", &sw_if_index))
7731         sw_if_index_set = 1;
7732       else
7733         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7734         sw_if_index_set = 1;
7735       else if (unformat (i, "sub_id %d", &sub_id))
7736         sub_id_set = 1;
7737       else if (unformat (i, "outer_vlan_id %d", &tmp))
7738         outer_vlan_id = tmp;
7739       else if (unformat (i, "inner_vlan_id %d", &tmp))
7740         inner_vlan_id = tmp;
7741
7742 #define _(a) else if (unformat (i, #a)) a = 1 ;
7743       foreach_create_subif_bit
7744 #undef _
7745         else
7746         {
7747           clib_warning ("parse error '%U'", format_unformat_error, i);
7748           return -99;
7749         }
7750     }
7751
7752   if (sw_if_index_set == 0)
7753     {
7754       errmsg ("missing interface name or sw_if_index");
7755       return -99;
7756     }
7757
7758   if (sub_id_set == 0)
7759     {
7760       errmsg ("missing sub_id");
7761       return -99;
7762     }
7763   M (CREATE_SUBIF, mp);
7764
7765   mp->sw_if_index = ntohl (sw_if_index);
7766   mp->sub_id = ntohl (sub_id);
7767
7768 #define _(a) mp->a = a;
7769   foreach_create_subif_bit;
7770 #undef _
7771
7772   mp->outer_vlan_id = ntohs (outer_vlan_id);
7773   mp->inner_vlan_id = ntohs (inner_vlan_id);
7774
7775   S (mp);
7776   W (ret);
7777   return ret;
7778 }
7779
7780 static int
7781 api_oam_add_del (vat_main_t * vam)
7782 {
7783   unformat_input_t *i = vam->input;
7784   vl_api_oam_add_del_t *mp;
7785   u32 vrf_id = 0;
7786   u8 is_add = 1;
7787   ip4_address_t src, dst;
7788   u8 src_set = 0;
7789   u8 dst_set = 0;
7790   int ret;
7791
7792   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7793     {
7794       if (unformat (i, "vrf %d", &vrf_id))
7795         ;
7796       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7797         src_set = 1;
7798       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7799         dst_set = 1;
7800       else if (unformat (i, "del"))
7801         is_add = 0;
7802       else
7803         {
7804           clib_warning ("parse error '%U'", format_unformat_error, i);
7805           return -99;
7806         }
7807     }
7808
7809   if (src_set == 0)
7810     {
7811       errmsg ("missing src addr");
7812       return -99;
7813     }
7814
7815   if (dst_set == 0)
7816     {
7817       errmsg ("missing dst addr");
7818       return -99;
7819     }
7820
7821   M (OAM_ADD_DEL, mp);
7822
7823   mp->vrf_id = ntohl (vrf_id);
7824   mp->is_add = is_add;
7825   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7826   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7827
7828   S (mp);
7829   W (ret);
7830   return ret;
7831 }
7832
7833 static int
7834 api_reset_fib (vat_main_t * vam)
7835 {
7836   unformat_input_t *i = vam->input;
7837   vl_api_reset_fib_t *mp;
7838   u32 vrf_id = 0;
7839   u8 is_ipv6 = 0;
7840   u8 vrf_id_set = 0;
7841
7842   int ret;
7843   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7844     {
7845       if (unformat (i, "vrf %d", &vrf_id))
7846         vrf_id_set = 1;
7847       else if (unformat (i, "ipv6"))
7848         is_ipv6 = 1;
7849       else
7850         {
7851           clib_warning ("parse error '%U'", format_unformat_error, i);
7852           return -99;
7853         }
7854     }
7855
7856   if (vrf_id_set == 0)
7857     {
7858       errmsg ("missing vrf id");
7859       return -99;
7860     }
7861
7862   M (RESET_FIB, mp);
7863
7864   mp->vrf_id = ntohl (vrf_id);
7865   mp->is_ipv6 = is_ipv6;
7866
7867   S (mp);
7868   W (ret);
7869   return ret;
7870 }
7871
7872 static int
7873 api_dhcp_proxy_config (vat_main_t * vam)
7874 {
7875   unformat_input_t *i = vam->input;
7876   vl_api_dhcp_proxy_config_t *mp;
7877   u32 rx_vrf_id = 0;
7878   u32 server_vrf_id = 0;
7879   u8 is_add = 1;
7880   u8 v4_address_set = 0;
7881   u8 v6_address_set = 0;
7882   ip4_address_t v4address;
7883   ip6_address_t v6address;
7884   u8 v4_src_address_set = 0;
7885   u8 v6_src_address_set = 0;
7886   ip4_address_t v4srcaddress;
7887   ip6_address_t v6srcaddress;
7888   int ret;
7889
7890   /* Parse args required to build the message */
7891   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7892     {
7893       if (unformat (i, "del"))
7894         is_add = 0;
7895       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7896         ;
7897       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7898         ;
7899       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7900         v4_address_set = 1;
7901       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7902         v6_address_set = 1;
7903       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7904         v4_src_address_set = 1;
7905       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7906         v6_src_address_set = 1;
7907       else
7908         break;
7909     }
7910
7911   if (v4_address_set && v6_address_set)
7912     {
7913       errmsg ("both v4 and v6 server addresses set");
7914       return -99;
7915     }
7916   if (!v4_address_set && !v6_address_set)
7917     {
7918       errmsg ("no server addresses set");
7919       return -99;
7920     }
7921
7922   if (v4_src_address_set && v6_src_address_set)
7923     {
7924       errmsg ("both v4 and v6  src addresses set");
7925       return -99;
7926     }
7927   if (!v4_src_address_set && !v6_src_address_set)
7928     {
7929       errmsg ("no src addresses set");
7930       return -99;
7931     }
7932
7933   if (!(v4_src_address_set && v4_address_set) &&
7934       !(v6_src_address_set && v6_address_set))
7935     {
7936       errmsg ("no matching server and src addresses set");
7937       return -99;
7938     }
7939
7940   /* Construct the API message */
7941   M (DHCP_PROXY_CONFIG, mp);
7942
7943   mp->is_add = is_add;
7944   mp->rx_vrf_id = ntohl (rx_vrf_id);
7945   mp->server_vrf_id = ntohl (server_vrf_id);
7946   if (v6_address_set)
7947     {
7948       mp->is_ipv6 = 1;
7949       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7950       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7951     }
7952   else
7953     {
7954       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7955       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7956     }
7957
7958   /* send it... */
7959   S (mp);
7960
7961   /* Wait for a reply, return good/bad news  */
7962   W (ret);
7963   return ret;
7964 }
7965
7966 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
7967 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
7968
7969 static void
7970 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
7971 {
7972   vat_main_t *vam = &vat_main;
7973   u32 i, count = mp->count;
7974   vl_api_dhcp_server_t *s;
7975
7976   if (mp->is_ipv6)
7977     print (vam->ofp,
7978            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7979            ntohl (mp->rx_vrf_id),
7980            format_ip6_address, mp->dhcp_src_address,
7981            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7982   else
7983     print (vam->ofp,
7984            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7985            ntohl (mp->rx_vrf_id),
7986            format_ip4_address, mp->dhcp_src_address,
7987            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7988
7989   for (i = 0; i < count; i++)
7990     {
7991       s = &mp->servers[i];
7992
7993       if (mp->is_ipv6)
7994         print (vam->ofp,
7995                " Server Table-ID %d, Server Address %U",
7996                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
7997       else
7998         print (vam->ofp,
7999                " Server Table-ID %d, Server Address %U",
8000                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
8001     }
8002 }
8003
8004 static void vl_api_dhcp_proxy_details_t_handler_json
8005   (vl_api_dhcp_proxy_details_t * mp)
8006 {
8007   vat_main_t *vam = &vat_main;
8008   vat_json_node_t *node = NULL;
8009   u32 i, count = mp->count;
8010   struct in_addr ip4;
8011   struct in6_addr ip6;
8012   vl_api_dhcp_server_t *s;
8013
8014   if (VAT_JSON_ARRAY != vam->json_tree.type)
8015     {
8016       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8017       vat_json_init_array (&vam->json_tree);
8018     }
8019   node = vat_json_array_add (&vam->json_tree);
8020
8021   vat_json_init_object (node);
8022   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
8023   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
8024   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
8025
8026   if (mp->is_ipv6)
8027     {
8028       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
8029       vat_json_object_add_ip6 (node, "src_address", ip6);
8030     }
8031   else
8032     {
8033       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
8034       vat_json_object_add_ip4 (node, "src_address", ip4);
8035     }
8036
8037   for (i = 0; i < count; i++)
8038     {
8039       s = &mp->servers[i];
8040
8041       vat_json_object_add_uint (node, "server-table-id",
8042                                 ntohl (s->server_vrf_id));
8043
8044       if (mp->is_ipv6)
8045         {
8046           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
8047           vat_json_object_add_ip4 (node, "src_address", ip4);
8048         }
8049       else
8050         {
8051           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
8052           vat_json_object_add_ip6 (node, "server_address", ip6);
8053         }
8054     }
8055 }
8056
8057 static int
8058 api_dhcp_proxy_dump (vat_main_t * vam)
8059 {
8060   unformat_input_t *i = vam->input;
8061   vl_api_control_ping_t *mp_ping;
8062   vl_api_dhcp_proxy_dump_t *mp;
8063   u8 is_ipv6 = 0;
8064   int ret;
8065
8066   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8067     {
8068       if (unformat (i, "ipv6"))
8069         is_ipv6 = 1;
8070       else
8071         {
8072           clib_warning ("parse error '%U'", format_unformat_error, i);
8073           return -99;
8074         }
8075     }
8076
8077   M (DHCP_PROXY_DUMP, mp);
8078
8079   mp->is_ip6 = is_ipv6;
8080   S (mp);
8081
8082   /* Use a control ping for synchronization */
8083   M (CONTROL_PING, mp_ping);
8084   S (mp_ping);
8085
8086   W (ret);
8087   return ret;
8088 }
8089
8090 static int
8091 api_dhcp_proxy_set_vss (vat_main_t * vam)
8092 {
8093   unformat_input_t *i = vam->input;
8094   vl_api_dhcp_proxy_set_vss_t *mp;
8095   u8 is_ipv6 = 0;
8096   u8 is_add = 1;
8097   u32 tbl_id;
8098   u8 tbl_id_set = 0;
8099   u32 oui;
8100   u8 oui_set = 0;
8101   u32 fib_id;
8102   u8 fib_id_set = 0;
8103   int ret;
8104
8105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8106     {
8107       if (unformat (i, "tbl_id %d", &tbl_id))
8108         tbl_id_set = 1;
8109       if (unformat (i, "fib_id %d", &fib_id))
8110         fib_id_set = 1;
8111       if (unformat (i, "oui %d", &oui))
8112         oui_set = 1;
8113       else if (unformat (i, "ipv6"))
8114         is_ipv6 = 1;
8115       else if (unformat (i, "del"))
8116         is_add = 0;
8117       else
8118         {
8119           clib_warning ("parse error '%U'", format_unformat_error, i);
8120           return -99;
8121         }
8122     }
8123
8124   if (tbl_id_set == 0)
8125     {
8126       errmsg ("missing tbl id");
8127       return -99;
8128     }
8129
8130   if (fib_id_set == 0)
8131     {
8132       errmsg ("missing fib id");
8133       return -99;
8134     }
8135   if (oui_set == 0)
8136     {
8137       errmsg ("missing oui");
8138       return -99;
8139     }
8140
8141   M (DHCP_PROXY_SET_VSS, mp);
8142   mp->tbl_id = ntohl (tbl_id);
8143   mp->fib_id = ntohl (fib_id);
8144   mp->oui = ntohl (oui);
8145   mp->is_ipv6 = is_ipv6;
8146   mp->is_add = is_add;
8147
8148   S (mp);
8149   W (ret);
8150   return ret;
8151 }
8152
8153 static int
8154 api_dhcp_client_config (vat_main_t * vam)
8155 {
8156   unformat_input_t *i = vam->input;
8157   vl_api_dhcp_client_config_t *mp;
8158   u32 sw_if_index;
8159   u8 sw_if_index_set = 0;
8160   u8 is_add = 1;
8161   u8 *hostname = 0;
8162   u8 disable_event = 0;
8163   int ret;
8164
8165   /* Parse args required to build the message */
8166   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8167     {
8168       if (unformat (i, "del"))
8169         is_add = 0;
8170       else
8171         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8172         sw_if_index_set = 1;
8173       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8174         sw_if_index_set = 1;
8175       else if (unformat (i, "hostname %s", &hostname))
8176         ;
8177       else if (unformat (i, "disable_event"))
8178         disable_event = 1;
8179       else
8180         break;
8181     }
8182
8183   if (sw_if_index_set == 0)
8184     {
8185       errmsg ("missing interface name or sw_if_index");
8186       return -99;
8187     }
8188
8189   if (vec_len (hostname) > 63)
8190     {
8191       errmsg ("hostname too long");
8192     }
8193   vec_add1 (hostname, 0);
8194
8195   /* Construct the API message */
8196   M (DHCP_CLIENT_CONFIG, mp);
8197
8198   mp->sw_if_index = htonl (sw_if_index);
8199   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
8200   vec_free (hostname);
8201   mp->is_add = is_add;
8202   mp->want_dhcp_event = disable_event ? 0 : 1;
8203   mp->pid = htonl (getpid ());
8204
8205   /* send it... */
8206   S (mp);
8207
8208   /* Wait for a reply, return good/bad news  */
8209   W (ret);
8210   return ret;
8211 }
8212
8213 static int
8214 api_set_ip_flow_hash (vat_main_t * vam)
8215 {
8216   unformat_input_t *i = vam->input;
8217   vl_api_set_ip_flow_hash_t *mp;
8218   u32 vrf_id = 0;
8219   u8 is_ipv6 = 0;
8220   u8 vrf_id_set = 0;
8221   u8 src = 0;
8222   u8 dst = 0;
8223   u8 sport = 0;
8224   u8 dport = 0;
8225   u8 proto = 0;
8226   u8 reverse = 0;
8227   int ret;
8228
8229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8230     {
8231       if (unformat (i, "vrf %d", &vrf_id))
8232         vrf_id_set = 1;
8233       else if (unformat (i, "ipv6"))
8234         is_ipv6 = 1;
8235       else if (unformat (i, "src"))
8236         src = 1;
8237       else if (unformat (i, "dst"))
8238         dst = 1;
8239       else if (unformat (i, "sport"))
8240         sport = 1;
8241       else if (unformat (i, "dport"))
8242         dport = 1;
8243       else if (unformat (i, "proto"))
8244         proto = 1;
8245       else if (unformat (i, "reverse"))
8246         reverse = 1;
8247
8248       else
8249         {
8250           clib_warning ("parse error '%U'", format_unformat_error, i);
8251           return -99;
8252         }
8253     }
8254
8255   if (vrf_id_set == 0)
8256     {
8257       errmsg ("missing vrf id");
8258       return -99;
8259     }
8260
8261   M (SET_IP_FLOW_HASH, mp);
8262   mp->src = src;
8263   mp->dst = dst;
8264   mp->sport = sport;
8265   mp->dport = dport;
8266   mp->proto = proto;
8267   mp->reverse = reverse;
8268   mp->vrf_id = ntohl (vrf_id);
8269   mp->is_ipv6 = is_ipv6;
8270
8271   S (mp);
8272   W (ret);
8273   return ret;
8274 }
8275
8276 static int
8277 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
8278 {
8279   unformat_input_t *i = vam->input;
8280   vl_api_sw_interface_ip6_enable_disable_t *mp;
8281   u32 sw_if_index;
8282   u8 sw_if_index_set = 0;
8283   u8 enable = 0;
8284   int ret;
8285
8286   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8287     {
8288       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8289         sw_if_index_set = 1;
8290       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8291         sw_if_index_set = 1;
8292       else if (unformat (i, "enable"))
8293         enable = 1;
8294       else if (unformat (i, "disable"))
8295         enable = 0;
8296       else
8297         {
8298           clib_warning ("parse error '%U'", format_unformat_error, i);
8299           return -99;
8300         }
8301     }
8302
8303   if (sw_if_index_set == 0)
8304     {
8305       errmsg ("missing interface name or sw_if_index");
8306       return -99;
8307     }
8308
8309   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
8310
8311   mp->sw_if_index = ntohl (sw_if_index);
8312   mp->enable = enable;
8313
8314   S (mp);
8315   W (ret);
8316   return ret;
8317 }
8318
8319 static int
8320 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
8321 {
8322   unformat_input_t *i = vam->input;
8323   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
8324   u32 sw_if_index;
8325   u8 sw_if_index_set = 0;
8326   u8 v6_address_set = 0;
8327   ip6_address_t v6address;
8328   int ret;
8329
8330   /* Parse args required to build the message */
8331   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8332     {
8333       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8334         sw_if_index_set = 1;
8335       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8336         sw_if_index_set = 1;
8337       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8338         v6_address_set = 1;
8339       else
8340         break;
8341     }
8342
8343   if (sw_if_index_set == 0)
8344     {
8345       errmsg ("missing interface name or sw_if_index");
8346       return -99;
8347     }
8348   if (!v6_address_set)
8349     {
8350       errmsg ("no address set");
8351       return -99;
8352     }
8353
8354   /* Construct the API message */
8355   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
8356
8357   mp->sw_if_index = ntohl (sw_if_index);
8358   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8359
8360   /* send it... */
8361   S (mp);
8362
8363   /* Wait for a reply, return good/bad news  */
8364   W (ret);
8365   return ret;
8366 }
8367
8368 static int
8369 api_ip6nd_proxy_add_del (vat_main_t * vam)
8370 {
8371   unformat_input_t *i = vam->input;
8372   vl_api_ip6nd_proxy_add_del_t *mp;
8373   u32 sw_if_index = ~0;
8374   u8 v6_address_set = 0;
8375   ip6_address_t v6address;
8376   u8 is_del = 0;
8377   int ret;
8378
8379   /* Parse args required to build the message */
8380   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8381     {
8382       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8383         ;
8384       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8385         ;
8386       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8387         v6_address_set = 1;
8388       if (unformat (i, "del"))
8389         is_del = 1;
8390       else
8391         {
8392           clib_warning ("parse error '%U'", format_unformat_error, i);
8393           return -99;
8394         }
8395     }
8396
8397   if (sw_if_index == ~0)
8398     {
8399       errmsg ("missing interface name or sw_if_index");
8400       return -99;
8401     }
8402   if (!v6_address_set)
8403     {
8404       errmsg ("no address set");
8405       return -99;
8406     }
8407
8408   /* Construct the API message */
8409   M (IP6ND_PROXY_ADD_DEL, mp);
8410
8411   mp->is_del = is_del;
8412   mp->sw_if_index = ntohl (sw_if_index);
8413   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8414
8415   /* send it... */
8416   S (mp);
8417
8418   /* Wait for a reply, return good/bad news  */
8419   W (ret);
8420   return ret;
8421 }
8422
8423 static int
8424 api_ip6nd_proxy_dump (vat_main_t * vam)
8425 {
8426   vl_api_ip6nd_proxy_dump_t *mp;
8427   vl_api_control_ping_t *mp_ping;
8428   int ret;
8429
8430   M (IP6ND_PROXY_DUMP, mp);
8431
8432   S (mp);
8433
8434   /* Use a control ping for synchronization */
8435   M (CONTROL_PING, mp_ping);
8436   S (mp_ping);
8437
8438   W (ret);
8439   return ret;
8440 }
8441
8442 static void vl_api_ip6nd_proxy_details_t_handler
8443   (vl_api_ip6nd_proxy_details_t * mp)
8444 {
8445   vat_main_t *vam = &vat_main;
8446
8447   print (vam->ofp, "host %U sw_if_index %d",
8448          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
8449 }
8450
8451 static void vl_api_ip6nd_proxy_details_t_handler_json
8452   (vl_api_ip6nd_proxy_details_t * mp)
8453 {
8454   vat_main_t *vam = &vat_main;
8455   struct in6_addr ip6;
8456   vat_json_node_t *node = NULL;
8457
8458   if (VAT_JSON_ARRAY != vam->json_tree.type)
8459     {
8460       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8461       vat_json_init_array (&vam->json_tree);
8462     }
8463   node = vat_json_array_add (&vam->json_tree);
8464
8465   vat_json_init_object (node);
8466   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
8467
8468   clib_memcpy (&ip6, mp->address, sizeof (ip6));
8469   vat_json_object_add_ip6 (node, "host", ip6);
8470 }
8471
8472 static int
8473 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
8474 {
8475   unformat_input_t *i = vam->input;
8476   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
8477   u32 sw_if_index;
8478   u8 sw_if_index_set = 0;
8479   u32 address_length = 0;
8480   u8 v6_address_set = 0;
8481   ip6_address_t v6address;
8482   u8 use_default = 0;
8483   u8 no_advertise = 0;
8484   u8 off_link = 0;
8485   u8 no_autoconfig = 0;
8486   u8 no_onlink = 0;
8487   u8 is_no = 0;
8488   u32 val_lifetime = 0;
8489   u32 pref_lifetime = 0;
8490   int ret;
8491
8492   /* Parse args required to build the message */
8493   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8494     {
8495       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8496         sw_if_index_set = 1;
8497       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8498         sw_if_index_set = 1;
8499       else if (unformat (i, "%U/%d",
8500                          unformat_ip6_address, &v6address, &address_length))
8501         v6_address_set = 1;
8502       else if (unformat (i, "val_life %d", &val_lifetime))
8503         ;
8504       else if (unformat (i, "pref_life %d", &pref_lifetime))
8505         ;
8506       else if (unformat (i, "def"))
8507         use_default = 1;
8508       else if (unformat (i, "noadv"))
8509         no_advertise = 1;
8510       else if (unformat (i, "offl"))
8511         off_link = 1;
8512       else if (unformat (i, "noauto"))
8513         no_autoconfig = 1;
8514       else if (unformat (i, "nolink"))
8515         no_onlink = 1;
8516       else if (unformat (i, "isno"))
8517         is_no = 1;
8518       else
8519         {
8520           clib_warning ("parse error '%U'", format_unformat_error, i);
8521           return -99;
8522         }
8523     }
8524
8525   if (sw_if_index_set == 0)
8526     {
8527       errmsg ("missing interface name or sw_if_index");
8528       return -99;
8529     }
8530   if (!v6_address_set)
8531     {
8532       errmsg ("no address set");
8533       return -99;
8534     }
8535
8536   /* Construct the API message */
8537   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
8538
8539   mp->sw_if_index = ntohl (sw_if_index);
8540   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8541   mp->address_length = address_length;
8542   mp->use_default = use_default;
8543   mp->no_advertise = no_advertise;
8544   mp->off_link = off_link;
8545   mp->no_autoconfig = no_autoconfig;
8546   mp->no_onlink = no_onlink;
8547   mp->is_no = is_no;
8548   mp->val_lifetime = ntohl (val_lifetime);
8549   mp->pref_lifetime = ntohl (pref_lifetime);
8550
8551   /* send it... */
8552   S (mp);
8553
8554   /* Wait for a reply, return good/bad news  */
8555   W (ret);
8556   return ret;
8557 }
8558
8559 static int
8560 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
8561 {
8562   unformat_input_t *i = vam->input;
8563   vl_api_sw_interface_ip6nd_ra_config_t *mp;
8564   u32 sw_if_index;
8565   u8 sw_if_index_set = 0;
8566   u8 suppress = 0;
8567   u8 managed = 0;
8568   u8 other = 0;
8569   u8 ll_option = 0;
8570   u8 send_unicast = 0;
8571   u8 cease = 0;
8572   u8 is_no = 0;
8573   u8 default_router = 0;
8574   u32 max_interval = 0;
8575   u32 min_interval = 0;
8576   u32 lifetime = 0;
8577   u32 initial_count = 0;
8578   u32 initial_interval = 0;
8579   int ret;
8580
8581
8582   /* Parse args required to build the message */
8583   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8584     {
8585       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8586         sw_if_index_set = 1;
8587       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8588         sw_if_index_set = 1;
8589       else if (unformat (i, "maxint %d", &max_interval))
8590         ;
8591       else if (unformat (i, "minint %d", &min_interval))
8592         ;
8593       else if (unformat (i, "life %d", &lifetime))
8594         ;
8595       else if (unformat (i, "count %d", &initial_count))
8596         ;
8597       else if (unformat (i, "interval %d", &initial_interval))
8598         ;
8599       else if (unformat (i, "suppress") || unformat (i, "surpress"))
8600         suppress = 1;
8601       else if (unformat (i, "managed"))
8602         managed = 1;
8603       else if (unformat (i, "other"))
8604         other = 1;
8605       else if (unformat (i, "ll"))
8606         ll_option = 1;
8607       else if (unformat (i, "send"))
8608         send_unicast = 1;
8609       else if (unformat (i, "cease"))
8610         cease = 1;
8611       else if (unformat (i, "isno"))
8612         is_no = 1;
8613       else if (unformat (i, "def"))
8614         default_router = 1;
8615       else
8616         {
8617           clib_warning ("parse error '%U'", format_unformat_error, i);
8618           return -99;
8619         }
8620     }
8621
8622   if (sw_if_index_set == 0)
8623     {
8624       errmsg ("missing interface name or sw_if_index");
8625       return -99;
8626     }
8627
8628   /* Construct the API message */
8629   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
8630
8631   mp->sw_if_index = ntohl (sw_if_index);
8632   mp->max_interval = ntohl (max_interval);
8633   mp->min_interval = ntohl (min_interval);
8634   mp->lifetime = ntohl (lifetime);
8635   mp->initial_count = ntohl (initial_count);
8636   mp->initial_interval = ntohl (initial_interval);
8637   mp->suppress = suppress;
8638   mp->managed = managed;
8639   mp->other = other;
8640   mp->ll_option = ll_option;
8641   mp->send_unicast = send_unicast;
8642   mp->cease = cease;
8643   mp->is_no = is_no;
8644   mp->default_router = default_router;
8645
8646   /* send it... */
8647   S (mp);
8648
8649   /* Wait for a reply, return good/bad news  */
8650   W (ret);
8651   return ret;
8652 }
8653
8654 static int
8655 api_set_arp_neighbor_limit (vat_main_t * vam)
8656 {
8657   unformat_input_t *i = vam->input;
8658   vl_api_set_arp_neighbor_limit_t *mp;
8659   u32 arp_nbr_limit;
8660   u8 limit_set = 0;
8661   u8 is_ipv6 = 0;
8662   int ret;
8663
8664   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8665     {
8666       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
8667         limit_set = 1;
8668       else if (unformat (i, "ipv6"))
8669         is_ipv6 = 1;
8670       else
8671         {
8672           clib_warning ("parse error '%U'", format_unformat_error, i);
8673           return -99;
8674         }
8675     }
8676
8677   if (limit_set == 0)
8678     {
8679       errmsg ("missing limit value");
8680       return -99;
8681     }
8682
8683   M (SET_ARP_NEIGHBOR_LIMIT, mp);
8684
8685   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
8686   mp->is_ipv6 = is_ipv6;
8687
8688   S (mp);
8689   W (ret);
8690   return ret;
8691 }
8692
8693 static int
8694 api_l2_patch_add_del (vat_main_t * vam)
8695 {
8696   unformat_input_t *i = vam->input;
8697   vl_api_l2_patch_add_del_t *mp;
8698   u32 rx_sw_if_index;
8699   u8 rx_sw_if_index_set = 0;
8700   u32 tx_sw_if_index;
8701   u8 tx_sw_if_index_set = 0;
8702   u8 is_add = 1;
8703   int ret;
8704
8705   /* Parse args required to build the message */
8706   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8707     {
8708       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
8709         rx_sw_if_index_set = 1;
8710       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
8711         tx_sw_if_index_set = 1;
8712       else if (unformat (i, "rx"))
8713         {
8714           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8715             {
8716               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8717                             &rx_sw_if_index))
8718                 rx_sw_if_index_set = 1;
8719             }
8720           else
8721             break;
8722         }
8723       else if (unformat (i, "tx"))
8724         {
8725           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8726             {
8727               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8728                             &tx_sw_if_index))
8729                 tx_sw_if_index_set = 1;
8730             }
8731           else
8732             break;
8733         }
8734       else if (unformat (i, "del"))
8735         is_add = 0;
8736       else
8737         break;
8738     }
8739
8740   if (rx_sw_if_index_set == 0)
8741     {
8742       errmsg ("missing rx interface name or rx_sw_if_index");
8743       return -99;
8744     }
8745
8746   if (tx_sw_if_index_set == 0)
8747     {
8748       errmsg ("missing tx interface name or tx_sw_if_index");
8749       return -99;
8750     }
8751
8752   M (L2_PATCH_ADD_DEL, mp);
8753
8754   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
8755   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
8756   mp->is_add = is_add;
8757
8758   S (mp);
8759   W (ret);
8760   return ret;
8761 }
8762
8763 u8 is_del;
8764 u8 localsid_addr[16];
8765 u8 end_psp;
8766 u8 behavior;
8767 u32 sw_if_index;
8768 u32 vlan_index;
8769 u32 fib_table;
8770 u8 nh_addr[16];
8771
8772 static int
8773 api_sr_localsid_add_del (vat_main_t * vam)
8774 {
8775   unformat_input_t *i = vam->input;
8776   vl_api_sr_localsid_add_del_t *mp;
8777
8778   u8 is_del;
8779   ip6_address_t localsid;
8780   u8 end_psp = 0;
8781   u8 behavior = ~0;
8782   u32 sw_if_index;
8783   u32 fib_table = ~(u32) 0;
8784   ip6_address_t next_hop;
8785
8786   bool nexthop_set = 0;
8787
8788   int ret;
8789
8790   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8791     {
8792       if (unformat (i, "del"))
8793         is_del = 1;
8794       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
8795       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
8796         nexthop_set = 1;
8797       else if (unformat (i, "behavior %u", &behavior));
8798       else if (unformat (i, "sw_if_index %u", &sw_if_index));
8799       else if (unformat (i, "fib-table %u", &fib_table));
8800       else if (unformat (i, "end.psp %u", &behavior));
8801       else
8802         break;
8803     }
8804
8805   M (SR_LOCALSID_ADD_DEL, mp);
8806
8807   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
8808   if (nexthop_set)
8809     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
8810   mp->behavior = behavior;
8811   mp->sw_if_index = ntohl (sw_if_index);
8812   mp->fib_table = ntohl (fib_table);
8813   mp->end_psp = end_psp;
8814   mp->is_del = is_del;
8815
8816   S (mp);
8817   W (ret);
8818   return ret;
8819 }
8820
8821 static int
8822 api_ioam_enable (vat_main_t * vam)
8823 {
8824   unformat_input_t *input = vam->input;
8825   vl_api_ioam_enable_t *mp;
8826   u32 id = 0;
8827   int has_trace_option = 0;
8828   int has_pot_option = 0;
8829   int has_seqno_option = 0;
8830   int has_analyse_option = 0;
8831   int ret;
8832
8833   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8834     {
8835       if (unformat (input, "trace"))
8836         has_trace_option = 1;
8837       else if (unformat (input, "pot"))
8838         has_pot_option = 1;
8839       else if (unformat (input, "seqno"))
8840         has_seqno_option = 1;
8841       else if (unformat (input, "analyse"))
8842         has_analyse_option = 1;
8843       else
8844         break;
8845     }
8846   M (IOAM_ENABLE, mp);
8847   mp->id = htons (id);
8848   mp->seqno = has_seqno_option;
8849   mp->analyse = has_analyse_option;
8850   mp->pot_enable = has_pot_option;
8851   mp->trace_enable = has_trace_option;
8852
8853   S (mp);
8854   W (ret);
8855   return ret;
8856 }
8857
8858
8859 static int
8860 api_ioam_disable (vat_main_t * vam)
8861 {
8862   vl_api_ioam_disable_t *mp;
8863   int ret;
8864
8865   M (IOAM_DISABLE, mp);
8866   S (mp);
8867   W (ret);
8868   return ret;
8869 }
8870
8871 #define foreach_tcp_proto_field                 \
8872 _(src_port)                                     \
8873 _(dst_port)
8874
8875 #define foreach_udp_proto_field                 \
8876 _(src_port)                                     \
8877 _(dst_port)
8878
8879 #define foreach_ip4_proto_field                 \
8880 _(src_address)                                  \
8881 _(dst_address)                                  \
8882 _(tos)                                          \
8883 _(length)                                       \
8884 _(fragment_id)                                  \
8885 _(ttl)                                          \
8886 _(protocol)                                     \
8887 _(checksum)
8888
8889 typedef struct
8890 {
8891   u16 src_port, dst_port;
8892 } tcpudp_header_t;
8893
8894 #if VPP_API_TEST_BUILTIN == 0
8895 uword
8896 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8897 {
8898   u8 **maskp = va_arg (*args, u8 **);
8899   u8 *mask = 0;
8900   u8 found_something = 0;
8901   tcp_header_t *tcp;
8902
8903 #define _(a) u8 a=0;
8904   foreach_tcp_proto_field;
8905 #undef _
8906
8907   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8908     {
8909       if (0);
8910 #define _(a) else if (unformat (input, #a)) a=1;
8911       foreach_tcp_proto_field
8912 #undef _
8913         else
8914         break;
8915     }
8916
8917 #define _(a) found_something += a;
8918   foreach_tcp_proto_field;
8919 #undef _
8920
8921   if (found_something == 0)
8922     return 0;
8923
8924   vec_validate (mask, sizeof (*tcp) - 1);
8925
8926   tcp = (tcp_header_t *) mask;
8927
8928 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8929   foreach_tcp_proto_field;
8930 #undef _
8931
8932   *maskp = mask;
8933   return 1;
8934 }
8935
8936 uword
8937 unformat_udp_mask (unformat_input_t * input, va_list * args)
8938 {
8939   u8 **maskp = va_arg (*args, u8 **);
8940   u8 *mask = 0;
8941   u8 found_something = 0;
8942   udp_header_t *udp;
8943
8944 #define _(a) u8 a=0;
8945   foreach_udp_proto_field;
8946 #undef _
8947
8948   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8949     {
8950       if (0);
8951 #define _(a) else if (unformat (input, #a)) a=1;
8952       foreach_udp_proto_field
8953 #undef _
8954         else
8955         break;
8956     }
8957
8958 #define _(a) found_something += a;
8959   foreach_udp_proto_field;
8960 #undef _
8961
8962   if (found_something == 0)
8963     return 0;
8964
8965   vec_validate (mask, sizeof (*udp) - 1);
8966
8967   udp = (udp_header_t *) mask;
8968
8969 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8970   foreach_udp_proto_field;
8971 #undef _
8972
8973   *maskp = mask;
8974   return 1;
8975 }
8976
8977 uword
8978 unformat_l4_mask (unformat_input_t * input, va_list * args)
8979 {
8980   u8 **maskp = va_arg (*args, u8 **);
8981   u16 src_port = 0, dst_port = 0;
8982   tcpudp_header_t *tcpudp;
8983
8984   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8985     {
8986       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8987         return 1;
8988       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8989         return 1;
8990       else if (unformat (input, "src_port"))
8991         src_port = 0xFFFF;
8992       else if (unformat (input, "dst_port"))
8993         dst_port = 0xFFFF;
8994       else
8995         return 0;
8996     }
8997
8998   if (!src_port && !dst_port)
8999     return 0;
9000
9001   u8 *mask = 0;
9002   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9003
9004   tcpudp = (tcpudp_header_t *) mask;
9005   tcpudp->src_port = src_port;
9006   tcpudp->dst_port = dst_port;
9007
9008   *maskp = mask;
9009
9010   return 1;
9011 }
9012
9013 uword
9014 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9015 {
9016   u8 **maskp = va_arg (*args, u8 **);
9017   u8 *mask = 0;
9018   u8 found_something = 0;
9019   ip4_header_t *ip;
9020
9021 #define _(a) u8 a=0;
9022   foreach_ip4_proto_field;
9023 #undef _
9024   u8 version = 0;
9025   u8 hdr_length = 0;
9026
9027
9028   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9029     {
9030       if (unformat (input, "version"))
9031         version = 1;
9032       else if (unformat (input, "hdr_length"))
9033         hdr_length = 1;
9034       else if (unformat (input, "src"))
9035         src_address = 1;
9036       else if (unformat (input, "dst"))
9037         dst_address = 1;
9038       else if (unformat (input, "proto"))
9039         protocol = 1;
9040
9041 #define _(a) else if (unformat (input, #a)) a=1;
9042       foreach_ip4_proto_field
9043 #undef _
9044         else
9045         break;
9046     }
9047
9048 #define _(a) found_something += a;
9049   foreach_ip4_proto_field;
9050 #undef _
9051
9052   if (found_something == 0)
9053     return 0;
9054
9055   vec_validate (mask, sizeof (*ip) - 1);
9056
9057   ip = (ip4_header_t *) mask;
9058
9059 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9060   foreach_ip4_proto_field;
9061 #undef _
9062
9063   ip->ip_version_and_header_length = 0;
9064
9065   if (version)
9066     ip->ip_version_and_header_length |= 0xF0;
9067
9068   if (hdr_length)
9069     ip->ip_version_and_header_length |= 0x0F;
9070
9071   *maskp = mask;
9072   return 1;
9073 }
9074
9075 #define foreach_ip6_proto_field                 \
9076 _(src_address)                                  \
9077 _(dst_address)                                  \
9078 _(payload_length)                               \
9079 _(hop_limit)                                    \
9080 _(protocol)
9081
9082 uword
9083 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9084 {
9085   u8 **maskp = va_arg (*args, u8 **);
9086   u8 *mask = 0;
9087   u8 found_something = 0;
9088   ip6_header_t *ip;
9089   u32 ip_version_traffic_class_and_flow_label;
9090
9091 #define _(a) u8 a=0;
9092   foreach_ip6_proto_field;
9093 #undef _
9094   u8 version = 0;
9095   u8 traffic_class = 0;
9096   u8 flow_label = 0;
9097
9098   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9099     {
9100       if (unformat (input, "version"))
9101         version = 1;
9102       else if (unformat (input, "traffic-class"))
9103         traffic_class = 1;
9104       else if (unformat (input, "flow-label"))
9105         flow_label = 1;
9106       else if (unformat (input, "src"))
9107         src_address = 1;
9108       else if (unformat (input, "dst"))
9109         dst_address = 1;
9110       else if (unformat (input, "proto"))
9111         protocol = 1;
9112
9113 #define _(a) else if (unformat (input, #a)) a=1;
9114       foreach_ip6_proto_field
9115 #undef _
9116         else
9117         break;
9118     }
9119
9120 #define _(a) found_something += a;
9121   foreach_ip6_proto_field;
9122 #undef _
9123
9124   if (found_something == 0)
9125     return 0;
9126
9127   vec_validate (mask, sizeof (*ip) - 1);
9128
9129   ip = (ip6_header_t *) mask;
9130
9131 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9132   foreach_ip6_proto_field;
9133 #undef _
9134
9135   ip_version_traffic_class_and_flow_label = 0;
9136
9137   if (version)
9138     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9139
9140   if (traffic_class)
9141     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9142
9143   if (flow_label)
9144     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9145
9146   ip->ip_version_traffic_class_and_flow_label =
9147     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9148
9149   *maskp = mask;
9150   return 1;
9151 }
9152
9153 uword
9154 unformat_l3_mask (unformat_input_t * input, va_list * args)
9155 {
9156   u8 **maskp = va_arg (*args, u8 **);
9157
9158   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9159     {
9160       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9161         return 1;
9162       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9163         return 1;
9164       else
9165         break;
9166     }
9167   return 0;
9168 }
9169
9170 uword
9171 unformat_l2_mask (unformat_input_t * input, va_list * args)
9172 {
9173   u8 **maskp = va_arg (*args, u8 **);
9174   u8 *mask = 0;
9175   u8 src = 0;
9176   u8 dst = 0;
9177   u8 proto = 0;
9178   u8 tag1 = 0;
9179   u8 tag2 = 0;
9180   u8 ignore_tag1 = 0;
9181   u8 ignore_tag2 = 0;
9182   u8 cos1 = 0;
9183   u8 cos2 = 0;
9184   u8 dot1q = 0;
9185   u8 dot1ad = 0;
9186   int len = 14;
9187
9188   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9189     {
9190       if (unformat (input, "src"))
9191         src = 1;
9192       else if (unformat (input, "dst"))
9193         dst = 1;
9194       else if (unformat (input, "proto"))
9195         proto = 1;
9196       else if (unformat (input, "tag1"))
9197         tag1 = 1;
9198       else if (unformat (input, "tag2"))
9199         tag2 = 1;
9200       else if (unformat (input, "ignore-tag1"))
9201         ignore_tag1 = 1;
9202       else if (unformat (input, "ignore-tag2"))
9203         ignore_tag2 = 1;
9204       else if (unformat (input, "cos1"))
9205         cos1 = 1;
9206       else if (unformat (input, "cos2"))
9207         cos2 = 1;
9208       else if (unformat (input, "dot1q"))
9209         dot1q = 1;
9210       else if (unformat (input, "dot1ad"))
9211         dot1ad = 1;
9212       else
9213         break;
9214     }
9215   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9216        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9217     return 0;
9218
9219   if (tag1 || ignore_tag1 || cos1 || dot1q)
9220     len = 18;
9221   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9222     len = 22;
9223
9224   vec_validate (mask, len - 1);
9225
9226   if (dst)
9227     memset (mask, 0xff, 6);
9228
9229   if (src)
9230     memset (mask + 6, 0xff, 6);
9231
9232   if (tag2 || dot1ad)
9233     {
9234       /* inner vlan tag */
9235       if (tag2)
9236         {
9237           mask[19] = 0xff;
9238           mask[18] = 0x0f;
9239         }
9240       if (cos2)
9241         mask[18] |= 0xe0;
9242       if (proto)
9243         mask[21] = mask[20] = 0xff;
9244       if (tag1)
9245         {
9246           mask[15] = 0xff;
9247           mask[14] = 0x0f;
9248         }
9249       if (cos1)
9250         mask[14] |= 0xe0;
9251       *maskp = mask;
9252       return 1;
9253     }
9254   if (tag1 | dot1q)
9255     {
9256       if (tag1)
9257         {
9258           mask[15] = 0xff;
9259           mask[14] = 0x0f;
9260         }
9261       if (cos1)
9262         mask[14] |= 0xe0;
9263       if (proto)
9264         mask[16] = mask[17] = 0xff;
9265
9266       *maskp = mask;
9267       return 1;
9268     }
9269   if (cos2)
9270     mask[18] |= 0xe0;
9271   if (cos1)
9272     mask[14] |= 0xe0;
9273   if (proto)
9274     mask[12] = mask[13] = 0xff;
9275
9276   *maskp = mask;
9277   return 1;
9278 }
9279
9280 uword
9281 unformat_classify_mask (unformat_input_t * input, va_list * args)
9282 {
9283   u8 **maskp = va_arg (*args, u8 **);
9284   u32 *skipp = va_arg (*args, u32 *);
9285   u32 *matchp = va_arg (*args, u32 *);
9286   u32 match;
9287   u8 *mask = 0;
9288   u8 *l2 = 0;
9289   u8 *l3 = 0;
9290   u8 *l4 = 0;
9291   int i;
9292
9293   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9294     {
9295       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9296         ;
9297       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9298         ;
9299       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9300         ;
9301       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9302         ;
9303       else
9304         break;
9305     }
9306
9307   if (l4 && !l3)
9308     {
9309       vec_free (mask);
9310       vec_free (l2);
9311       vec_free (l4);
9312       return 0;
9313     }
9314
9315   if (mask || l2 || l3 || l4)
9316     {
9317       if (l2 || l3 || l4)
9318         {
9319           /* "With a free Ethernet header in every package" */
9320           if (l2 == 0)
9321             vec_validate (l2, 13);
9322           mask = l2;
9323           if (vec_len (l3))
9324             {
9325               vec_append (mask, l3);
9326               vec_free (l3);
9327             }
9328           if (vec_len (l4))
9329             {
9330               vec_append (mask, l4);
9331               vec_free (l4);
9332             }
9333         }
9334
9335       /* Scan forward looking for the first significant mask octet */
9336       for (i = 0; i < vec_len (mask); i++)
9337         if (mask[i])
9338           break;
9339
9340       /* compute (skip, match) params */
9341       *skipp = i / sizeof (u32x4);
9342       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9343
9344       /* Pad mask to an even multiple of the vector size */
9345       while (vec_len (mask) % sizeof (u32x4))
9346         vec_add1 (mask, 0);
9347
9348       match = vec_len (mask) / sizeof (u32x4);
9349
9350       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9351         {
9352           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9353           if (*tmp || *(tmp + 1))
9354             break;
9355           match--;
9356         }
9357       if (match == 0)
9358         clib_warning ("BUG: match 0");
9359
9360       _vec_len (mask) = match * sizeof (u32x4);
9361
9362       *matchp = match;
9363       *maskp = mask;
9364
9365       return 1;
9366     }
9367
9368   return 0;
9369 }
9370 #endif /* VPP_API_TEST_BUILTIN */
9371
9372 #define foreach_l2_next                         \
9373 _(drop, DROP)                                   \
9374 _(ethernet, ETHERNET_INPUT)                     \
9375 _(ip4, IP4_INPUT)                               \
9376 _(ip6, IP6_INPUT)
9377
9378 uword
9379 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9380 {
9381   u32 *miss_next_indexp = va_arg (*args, u32 *);
9382   u32 next_index = 0;
9383   u32 tmp;
9384
9385 #define _(n,N) \
9386   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9387   foreach_l2_next;
9388 #undef _
9389
9390   if (unformat (input, "%d", &tmp))
9391     {
9392       next_index = tmp;
9393       goto out;
9394     }
9395
9396   return 0;
9397
9398 out:
9399   *miss_next_indexp = next_index;
9400   return 1;
9401 }
9402
9403 #define foreach_ip_next                         \
9404 _(drop, DROP)                                   \
9405 _(local, LOCAL)                                 \
9406 _(rewrite, REWRITE)
9407
9408 uword
9409 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9410 {
9411   u32 *miss_next_indexp = va_arg (*args, u32 *);
9412   u32 next_index = 0;
9413   u32 tmp;
9414
9415 #define _(n,N) \
9416   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9417   foreach_ip_next;
9418 #undef _
9419
9420   if (unformat (input, "%d", &tmp))
9421     {
9422       next_index = tmp;
9423       goto out;
9424     }
9425
9426   return 0;
9427
9428 out:
9429   *miss_next_indexp = next_index;
9430   return 1;
9431 }
9432
9433 #define foreach_acl_next                        \
9434 _(deny, DENY)
9435
9436 uword
9437 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9438 {
9439   u32 *miss_next_indexp = va_arg (*args, u32 *);
9440   u32 next_index = 0;
9441   u32 tmp;
9442
9443 #define _(n,N) \
9444   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9445   foreach_acl_next;
9446 #undef _
9447
9448   if (unformat (input, "permit"))
9449     {
9450       next_index = ~0;
9451       goto out;
9452     }
9453   else if (unformat (input, "%d", &tmp))
9454     {
9455       next_index = tmp;
9456       goto out;
9457     }
9458
9459   return 0;
9460
9461 out:
9462   *miss_next_indexp = next_index;
9463   return 1;
9464 }
9465
9466 uword
9467 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9468 {
9469   u32 *r = va_arg (*args, u32 *);
9470
9471   if (unformat (input, "conform-color"))
9472     *r = POLICE_CONFORM;
9473   else if (unformat (input, "exceed-color"))
9474     *r = POLICE_EXCEED;
9475   else
9476     return 0;
9477
9478   return 1;
9479 }
9480
9481 static int
9482 api_classify_add_del_table (vat_main_t * vam)
9483 {
9484   unformat_input_t *i = vam->input;
9485   vl_api_classify_add_del_table_t *mp;
9486
9487   u32 nbuckets = 2;
9488   u32 skip = ~0;
9489   u32 match = ~0;
9490   int is_add = 1;
9491   int del_chain = 0;
9492   u32 table_index = ~0;
9493   u32 next_table_index = ~0;
9494   u32 miss_next_index = ~0;
9495   u32 memory_size = 32 << 20;
9496   u8 *mask = 0;
9497   u32 current_data_flag = 0;
9498   int current_data_offset = 0;
9499   int ret;
9500
9501   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9502     {
9503       if (unformat (i, "del"))
9504         is_add = 0;
9505       else if (unformat (i, "del-chain"))
9506         {
9507           is_add = 0;
9508           del_chain = 1;
9509         }
9510       else if (unformat (i, "buckets %d", &nbuckets))
9511         ;
9512       else if (unformat (i, "memory_size %d", &memory_size))
9513         ;
9514       else if (unformat (i, "skip %d", &skip))
9515         ;
9516       else if (unformat (i, "match %d", &match))
9517         ;
9518       else if (unformat (i, "table %d", &table_index))
9519         ;
9520       else if (unformat (i, "mask %U", unformat_classify_mask,
9521                          &mask, &skip, &match))
9522         ;
9523       else if (unformat (i, "next-table %d", &next_table_index))
9524         ;
9525       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
9526                          &miss_next_index))
9527         ;
9528       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
9529                          &miss_next_index))
9530         ;
9531       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
9532                          &miss_next_index))
9533         ;
9534       else if (unformat (i, "current-data-flag %d", &current_data_flag))
9535         ;
9536       else if (unformat (i, "current-data-offset %d", &current_data_offset))
9537         ;
9538       else
9539         break;
9540     }
9541
9542   if (is_add && mask == 0)
9543     {
9544       errmsg ("Mask required");
9545       return -99;
9546     }
9547
9548   if (is_add && skip == ~0)
9549     {
9550       errmsg ("skip count required");
9551       return -99;
9552     }
9553
9554   if (is_add && match == ~0)
9555     {
9556       errmsg ("match count required");
9557       return -99;
9558     }
9559
9560   if (!is_add && table_index == ~0)
9561     {
9562       errmsg ("table index required for delete");
9563       return -99;
9564     }
9565
9566   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
9567
9568   mp->is_add = is_add;
9569   mp->del_chain = del_chain;
9570   mp->table_index = ntohl (table_index);
9571   mp->nbuckets = ntohl (nbuckets);
9572   mp->memory_size = ntohl (memory_size);
9573   mp->skip_n_vectors = ntohl (skip);
9574   mp->match_n_vectors = ntohl (match);
9575   mp->next_table_index = ntohl (next_table_index);
9576   mp->miss_next_index = ntohl (miss_next_index);
9577   mp->current_data_flag = ntohl (current_data_flag);
9578   mp->current_data_offset = ntohl (current_data_offset);
9579   clib_memcpy (mp->mask, mask, vec_len (mask));
9580
9581   vec_free (mask);
9582
9583   S (mp);
9584   W (ret);
9585   return ret;
9586 }
9587
9588 #if VPP_API_TEST_BUILTIN == 0
9589 uword
9590 unformat_l4_match (unformat_input_t * input, va_list * args)
9591 {
9592   u8 **matchp = va_arg (*args, u8 **);
9593
9594   u8 *proto_header = 0;
9595   int src_port = 0;
9596   int dst_port = 0;
9597
9598   tcpudp_header_t h;
9599
9600   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9601     {
9602       if (unformat (input, "src_port %d", &src_port))
9603         ;
9604       else if (unformat (input, "dst_port %d", &dst_port))
9605         ;
9606       else
9607         return 0;
9608     }
9609
9610   h.src_port = clib_host_to_net_u16 (src_port);
9611   h.dst_port = clib_host_to_net_u16 (dst_port);
9612   vec_validate (proto_header, sizeof (h) - 1);
9613   memcpy (proto_header, &h, sizeof (h));
9614
9615   *matchp = proto_header;
9616
9617   return 1;
9618 }
9619
9620 uword
9621 unformat_ip4_match (unformat_input_t * input, va_list * args)
9622 {
9623   u8 **matchp = va_arg (*args, u8 **);
9624   u8 *match = 0;
9625   ip4_header_t *ip;
9626   int version = 0;
9627   u32 version_val;
9628   int hdr_length = 0;
9629   u32 hdr_length_val;
9630   int src = 0, dst = 0;
9631   ip4_address_t src_val, dst_val;
9632   int proto = 0;
9633   u32 proto_val;
9634   int tos = 0;
9635   u32 tos_val;
9636   int length = 0;
9637   u32 length_val;
9638   int fragment_id = 0;
9639   u32 fragment_id_val;
9640   int ttl = 0;
9641   int ttl_val;
9642   int checksum = 0;
9643   u32 checksum_val;
9644
9645   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9646     {
9647       if (unformat (input, "version %d", &version_val))
9648         version = 1;
9649       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9650         hdr_length = 1;
9651       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9652         src = 1;
9653       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9654         dst = 1;
9655       else if (unformat (input, "proto %d", &proto_val))
9656         proto = 1;
9657       else if (unformat (input, "tos %d", &tos_val))
9658         tos = 1;
9659       else if (unformat (input, "length %d", &length_val))
9660         length = 1;
9661       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9662         fragment_id = 1;
9663       else if (unformat (input, "ttl %d", &ttl_val))
9664         ttl = 1;
9665       else if (unformat (input, "checksum %d", &checksum_val))
9666         checksum = 1;
9667       else
9668         break;
9669     }
9670
9671   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9672       + ttl + checksum == 0)
9673     return 0;
9674
9675   /*
9676    * Aligned because we use the real comparison functions
9677    */
9678   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9679
9680   ip = (ip4_header_t *) match;
9681
9682   /* These are realistically matched in practice */
9683   if (src)
9684     ip->src_address.as_u32 = src_val.as_u32;
9685
9686   if (dst)
9687     ip->dst_address.as_u32 = dst_val.as_u32;
9688
9689   if (proto)
9690     ip->protocol = proto_val;
9691
9692
9693   /* These are not, but they're included for completeness */
9694   if (version)
9695     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9696
9697   if (hdr_length)
9698     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9699
9700   if (tos)
9701     ip->tos = tos_val;
9702
9703   if (length)
9704     ip->length = clib_host_to_net_u16 (length_val);
9705
9706   if (ttl)
9707     ip->ttl = ttl_val;
9708
9709   if (checksum)
9710     ip->checksum = clib_host_to_net_u16 (checksum_val);
9711
9712   *matchp = match;
9713   return 1;
9714 }
9715
9716 uword
9717 unformat_ip6_match (unformat_input_t * input, va_list * args)
9718 {
9719   u8 **matchp = va_arg (*args, u8 **);
9720   u8 *match = 0;
9721   ip6_header_t *ip;
9722   int version = 0;
9723   u32 version_val;
9724   u8 traffic_class = 0;
9725   u32 traffic_class_val = 0;
9726   u8 flow_label = 0;
9727   u8 flow_label_val;
9728   int src = 0, dst = 0;
9729   ip6_address_t src_val, dst_val;
9730   int proto = 0;
9731   u32 proto_val;
9732   int payload_length = 0;
9733   u32 payload_length_val;
9734   int hop_limit = 0;
9735   int hop_limit_val;
9736   u32 ip_version_traffic_class_and_flow_label;
9737
9738   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9739     {
9740       if (unformat (input, "version %d", &version_val))
9741         version = 1;
9742       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9743         traffic_class = 1;
9744       else if (unformat (input, "flow_label %d", &flow_label_val))
9745         flow_label = 1;
9746       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9747         src = 1;
9748       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9749         dst = 1;
9750       else if (unformat (input, "proto %d", &proto_val))
9751         proto = 1;
9752       else if (unformat (input, "payload_length %d", &payload_length_val))
9753         payload_length = 1;
9754       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9755         hop_limit = 1;
9756       else
9757         break;
9758     }
9759
9760   if (version + traffic_class + flow_label + src + dst + proto +
9761       payload_length + hop_limit == 0)
9762     return 0;
9763
9764   /*
9765    * Aligned because we use the real comparison functions
9766    */
9767   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9768
9769   ip = (ip6_header_t *) match;
9770
9771   if (src)
9772     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9773
9774   if (dst)
9775     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9776
9777   if (proto)
9778     ip->protocol = proto_val;
9779
9780   ip_version_traffic_class_and_flow_label = 0;
9781
9782   if (version)
9783     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9784
9785   if (traffic_class)
9786     ip_version_traffic_class_and_flow_label |=
9787       (traffic_class_val & 0xFF) << 20;
9788
9789   if (flow_label)
9790     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9791
9792   ip->ip_version_traffic_class_and_flow_label =
9793     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9794
9795   if (payload_length)
9796     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9797
9798   if (hop_limit)
9799     ip->hop_limit = hop_limit_val;
9800
9801   *matchp = match;
9802   return 1;
9803 }
9804
9805 uword
9806 unformat_l3_match (unformat_input_t * input, va_list * args)
9807 {
9808   u8 **matchp = va_arg (*args, u8 **);
9809
9810   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9811     {
9812       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9813         return 1;
9814       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9815         return 1;
9816       else
9817         break;
9818     }
9819   return 0;
9820 }
9821
9822 uword
9823 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9824 {
9825   u8 *tagp = va_arg (*args, u8 *);
9826   u32 tag;
9827
9828   if (unformat (input, "%d", &tag))
9829     {
9830       tagp[0] = (tag >> 8) & 0x0F;
9831       tagp[1] = tag & 0xFF;
9832       return 1;
9833     }
9834
9835   return 0;
9836 }
9837
9838 uword
9839 unformat_l2_match (unformat_input_t * input, va_list * args)
9840 {
9841   u8 **matchp = va_arg (*args, u8 **);
9842   u8 *match = 0;
9843   u8 src = 0;
9844   u8 src_val[6];
9845   u8 dst = 0;
9846   u8 dst_val[6];
9847   u8 proto = 0;
9848   u16 proto_val;
9849   u8 tag1 = 0;
9850   u8 tag1_val[2];
9851   u8 tag2 = 0;
9852   u8 tag2_val[2];
9853   int len = 14;
9854   u8 ignore_tag1 = 0;
9855   u8 ignore_tag2 = 0;
9856   u8 cos1 = 0;
9857   u8 cos2 = 0;
9858   u32 cos1_val = 0;
9859   u32 cos2_val = 0;
9860
9861   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9862     {
9863       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9864         src = 1;
9865       else
9866         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9867         dst = 1;
9868       else if (unformat (input, "proto %U",
9869                          unformat_ethernet_type_host_byte_order, &proto_val))
9870         proto = 1;
9871       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9872         tag1 = 1;
9873       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9874         tag2 = 1;
9875       else if (unformat (input, "ignore-tag1"))
9876         ignore_tag1 = 1;
9877       else if (unformat (input, "ignore-tag2"))
9878         ignore_tag2 = 1;
9879       else if (unformat (input, "cos1 %d", &cos1_val))
9880         cos1 = 1;
9881       else if (unformat (input, "cos2 %d", &cos2_val))
9882         cos2 = 1;
9883       else
9884         break;
9885     }
9886   if ((src + dst + proto + tag1 + tag2 +
9887        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9888     return 0;
9889
9890   if (tag1 || ignore_tag1 || cos1)
9891     len = 18;
9892   if (tag2 || ignore_tag2 || cos2)
9893     len = 22;
9894
9895   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9896
9897   if (dst)
9898     clib_memcpy (match, dst_val, 6);
9899
9900   if (src)
9901     clib_memcpy (match + 6, src_val, 6);
9902
9903   if (tag2)
9904     {
9905       /* inner vlan tag */
9906       match[19] = tag2_val[1];
9907       match[18] = tag2_val[0];
9908       if (cos2)
9909         match[18] |= (cos2_val & 0x7) << 5;
9910       if (proto)
9911         {
9912           match[21] = proto_val & 0xff;
9913           match[20] = proto_val >> 8;
9914         }
9915       if (tag1)
9916         {
9917           match[15] = tag1_val[1];
9918           match[14] = tag1_val[0];
9919         }
9920       if (cos1)
9921         match[14] |= (cos1_val & 0x7) << 5;
9922       *matchp = match;
9923       return 1;
9924     }
9925   if (tag1)
9926     {
9927       match[15] = tag1_val[1];
9928       match[14] = tag1_val[0];
9929       if (proto)
9930         {
9931           match[17] = proto_val & 0xff;
9932           match[16] = proto_val >> 8;
9933         }
9934       if (cos1)
9935         match[14] |= (cos1_val & 0x7) << 5;
9936
9937       *matchp = match;
9938       return 1;
9939     }
9940   if (cos2)
9941     match[18] |= (cos2_val & 0x7) << 5;
9942   if (cos1)
9943     match[14] |= (cos1_val & 0x7) << 5;
9944   if (proto)
9945     {
9946       match[13] = proto_val & 0xff;
9947       match[12] = proto_val >> 8;
9948     }
9949
9950   *matchp = match;
9951   return 1;
9952 }
9953 #endif
9954
9955 uword
9956 api_unformat_classify_match (unformat_input_t * input, va_list * args)
9957 {
9958   u8 **matchp = va_arg (*args, u8 **);
9959   u32 skip_n_vectors = va_arg (*args, u32);
9960   u32 match_n_vectors = va_arg (*args, u32);
9961
9962   u8 *match = 0;
9963   u8 *l2 = 0;
9964   u8 *l3 = 0;
9965   u8 *l4 = 0;
9966
9967   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9968     {
9969       if (unformat (input, "hex %U", unformat_hex_string, &match))
9970         ;
9971       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9972         ;
9973       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9974         ;
9975       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9976         ;
9977       else
9978         break;
9979     }
9980
9981   if (l4 && !l3)
9982     {
9983       vec_free (match);
9984       vec_free (l2);
9985       vec_free (l4);
9986       return 0;
9987     }
9988
9989   if (match || l2 || l3 || l4)
9990     {
9991       if (l2 || l3 || l4)
9992         {
9993           /* "Win a free Ethernet header in every packet" */
9994           if (l2 == 0)
9995             vec_validate_aligned (l2, 13, sizeof (u32x4));
9996           match = l2;
9997           if (vec_len (l3))
9998             {
9999               vec_append_aligned (match, l3, sizeof (u32x4));
10000               vec_free (l3);
10001             }
10002           if (vec_len (l4))
10003             {
10004               vec_append_aligned (match, l4, sizeof (u32x4));
10005               vec_free (l4);
10006             }
10007         }
10008
10009       /* Make sure the vector is big enough even if key is all 0's */
10010       vec_validate_aligned
10011         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10012          sizeof (u32x4));
10013
10014       /* Set size, include skipped vectors */
10015       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10016
10017       *matchp = match;
10018
10019       return 1;
10020     }
10021
10022   return 0;
10023 }
10024
10025 static int
10026 api_classify_add_del_session (vat_main_t * vam)
10027 {
10028   unformat_input_t *i = vam->input;
10029   vl_api_classify_add_del_session_t *mp;
10030   int is_add = 1;
10031   u32 table_index = ~0;
10032   u32 hit_next_index = ~0;
10033   u32 opaque_index = ~0;
10034   u8 *match = 0;
10035   i32 advance = 0;
10036   u32 skip_n_vectors = 0;
10037   u32 match_n_vectors = 0;
10038   u32 action = 0;
10039   u32 metadata = 0;
10040   int ret;
10041
10042   /*
10043    * Warning: you have to supply skip_n and match_n
10044    * because the API client cant simply look at the classify
10045    * table object.
10046    */
10047
10048   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10049     {
10050       if (unformat (i, "del"))
10051         is_add = 0;
10052       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10053                          &hit_next_index))
10054         ;
10055       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10056                          &hit_next_index))
10057         ;
10058       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10059                          &hit_next_index))
10060         ;
10061       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10062         ;
10063       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10064         ;
10065       else if (unformat (i, "opaque-index %d", &opaque_index))
10066         ;
10067       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10068         ;
10069       else if (unformat (i, "match_n %d", &match_n_vectors))
10070         ;
10071       else if (unformat (i, "match %U", api_unformat_classify_match,
10072                          &match, skip_n_vectors, match_n_vectors))
10073         ;
10074       else if (unformat (i, "advance %d", &advance))
10075         ;
10076       else if (unformat (i, "table-index %d", &table_index))
10077         ;
10078       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10079         action = 1;
10080       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10081         action = 2;
10082       else if (unformat (i, "action %d", &action))
10083         ;
10084       else if (unformat (i, "metadata %d", &metadata))
10085         ;
10086       else
10087         break;
10088     }
10089
10090   if (table_index == ~0)
10091     {
10092       errmsg ("Table index required");
10093       return -99;
10094     }
10095
10096   if (is_add && match == 0)
10097     {
10098       errmsg ("Match value required");
10099       return -99;
10100     }
10101
10102   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10103
10104   mp->is_add = is_add;
10105   mp->table_index = ntohl (table_index);
10106   mp->hit_next_index = ntohl (hit_next_index);
10107   mp->opaque_index = ntohl (opaque_index);
10108   mp->advance = ntohl (advance);
10109   mp->action = action;
10110   mp->metadata = ntohl (metadata);
10111   clib_memcpy (mp->match, match, vec_len (match));
10112   vec_free (match);
10113
10114   S (mp);
10115   W (ret);
10116   return ret;
10117 }
10118
10119 static int
10120 api_classify_set_interface_ip_table (vat_main_t * vam)
10121 {
10122   unformat_input_t *i = vam->input;
10123   vl_api_classify_set_interface_ip_table_t *mp;
10124   u32 sw_if_index;
10125   int sw_if_index_set;
10126   u32 table_index = ~0;
10127   u8 is_ipv6 = 0;
10128   int ret;
10129
10130   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10131     {
10132       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10133         sw_if_index_set = 1;
10134       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10135         sw_if_index_set = 1;
10136       else if (unformat (i, "table %d", &table_index))
10137         ;
10138       else
10139         {
10140           clib_warning ("parse error '%U'", format_unformat_error, i);
10141           return -99;
10142         }
10143     }
10144
10145   if (sw_if_index_set == 0)
10146     {
10147       errmsg ("missing interface name or sw_if_index");
10148       return -99;
10149     }
10150
10151
10152   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10153
10154   mp->sw_if_index = ntohl (sw_if_index);
10155   mp->table_index = ntohl (table_index);
10156   mp->is_ipv6 = is_ipv6;
10157
10158   S (mp);
10159   W (ret);
10160   return ret;
10161 }
10162
10163 static int
10164 api_classify_set_interface_l2_tables (vat_main_t * vam)
10165 {
10166   unformat_input_t *i = vam->input;
10167   vl_api_classify_set_interface_l2_tables_t *mp;
10168   u32 sw_if_index;
10169   int sw_if_index_set;
10170   u32 ip4_table_index = ~0;
10171   u32 ip6_table_index = ~0;
10172   u32 other_table_index = ~0;
10173   u32 is_input = 1;
10174   int ret;
10175
10176   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10177     {
10178       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10179         sw_if_index_set = 1;
10180       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10181         sw_if_index_set = 1;
10182       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10183         ;
10184       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10185         ;
10186       else if (unformat (i, "other-table %d", &other_table_index))
10187         ;
10188       else if (unformat (i, "is-input %d", &is_input))
10189         ;
10190       else
10191         {
10192           clib_warning ("parse error '%U'", format_unformat_error, i);
10193           return -99;
10194         }
10195     }
10196
10197   if (sw_if_index_set == 0)
10198     {
10199       errmsg ("missing interface name or sw_if_index");
10200       return -99;
10201     }
10202
10203
10204   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10205
10206   mp->sw_if_index = ntohl (sw_if_index);
10207   mp->ip4_table_index = ntohl (ip4_table_index);
10208   mp->ip6_table_index = ntohl (ip6_table_index);
10209   mp->other_table_index = ntohl (other_table_index);
10210   mp->is_input = (u8) is_input;
10211
10212   S (mp);
10213   W (ret);
10214   return ret;
10215 }
10216
10217 static int
10218 api_set_ipfix_exporter (vat_main_t * vam)
10219 {
10220   unformat_input_t *i = vam->input;
10221   vl_api_set_ipfix_exporter_t *mp;
10222   ip4_address_t collector_address;
10223   u8 collector_address_set = 0;
10224   u32 collector_port = ~0;
10225   ip4_address_t src_address;
10226   u8 src_address_set = 0;
10227   u32 vrf_id = ~0;
10228   u32 path_mtu = ~0;
10229   u32 template_interval = ~0;
10230   u8 udp_checksum = 0;
10231   int ret;
10232
10233   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10234     {
10235       if (unformat (i, "collector_address %U", unformat_ip4_address,
10236                     &collector_address))
10237         collector_address_set = 1;
10238       else if (unformat (i, "collector_port %d", &collector_port))
10239         ;
10240       else if (unformat (i, "src_address %U", unformat_ip4_address,
10241                          &src_address))
10242         src_address_set = 1;
10243       else if (unformat (i, "vrf_id %d", &vrf_id))
10244         ;
10245       else if (unformat (i, "path_mtu %d", &path_mtu))
10246         ;
10247       else if (unformat (i, "template_interval %d", &template_interval))
10248         ;
10249       else if (unformat (i, "udp_checksum"))
10250         udp_checksum = 1;
10251       else
10252         break;
10253     }
10254
10255   if (collector_address_set == 0)
10256     {
10257       errmsg ("collector_address required");
10258       return -99;
10259     }
10260
10261   if (src_address_set == 0)
10262     {
10263       errmsg ("src_address required");
10264       return -99;
10265     }
10266
10267   M (SET_IPFIX_EXPORTER, mp);
10268
10269   memcpy (mp->collector_address, collector_address.data,
10270           sizeof (collector_address.data));
10271   mp->collector_port = htons ((u16) collector_port);
10272   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
10273   mp->vrf_id = htonl (vrf_id);
10274   mp->path_mtu = htonl (path_mtu);
10275   mp->template_interval = htonl (template_interval);
10276   mp->udp_checksum = udp_checksum;
10277
10278   S (mp);
10279   W (ret);
10280   return ret;
10281 }
10282
10283 static int
10284 api_set_ipfix_classify_stream (vat_main_t * vam)
10285 {
10286   unformat_input_t *i = vam->input;
10287   vl_api_set_ipfix_classify_stream_t *mp;
10288   u32 domain_id = 0;
10289   u32 src_port = UDP_DST_PORT_ipfix;
10290   int ret;
10291
10292   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10293     {
10294       if (unformat (i, "domain %d", &domain_id))
10295         ;
10296       else if (unformat (i, "src_port %d", &src_port))
10297         ;
10298       else
10299         {
10300           errmsg ("unknown input `%U'", format_unformat_error, i);
10301           return -99;
10302         }
10303     }
10304
10305   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10306
10307   mp->domain_id = htonl (domain_id);
10308   mp->src_port = htons ((u16) src_port);
10309
10310   S (mp);
10311   W (ret);
10312   return ret;
10313 }
10314
10315 static int
10316 api_ipfix_classify_table_add_del (vat_main_t * vam)
10317 {
10318   unformat_input_t *i = vam->input;
10319   vl_api_ipfix_classify_table_add_del_t *mp;
10320   int is_add = -1;
10321   u32 classify_table_index = ~0;
10322   u8 ip_version = 0;
10323   u8 transport_protocol = 255;
10324   int ret;
10325
10326   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10327     {
10328       if (unformat (i, "add"))
10329         is_add = 1;
10330       else if (unformat (i, "del"))
10331         is_add = 0;
10332       else if (unformat (i, "table %d", &classify_table_index))
10333         ;
10334       else if (unformat (i, "ip4"))
10335         ip_version = 4;
10336       else if (unformat (i, "ip6"))
10337         ip_version = 6;
10338       else if (unformat (i, "tcp"))
10339         transport_protocol = 6;
10340       else if (unformat (i, "udp"))
10341         transport_protocol = 17;
10342       else
10343         {
10344           errmsg ("unknown input `%U'", format_unformat_error, i);
10345           return -99;
10346         }
10347     }
10348
10349   if (is_add == -1)
10350     {
10351       errmsg ("expecting: add|del");
10352       return -99;
10353     }
10354   if (classify_table_index == ~0)
10355     {
10356       errmsg ("classifier table not specified");
10357       return -99;
10358     }
10359   if (ip_version == 0)
10360     {
10361       errmsg ("IP version not specified");
10362       return -99;
10363     }
10364
10365   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10366
10367   mp->is_add = is_add;
10368   mp->table_id = htonl (classify_table_index);
10369   mp->ip_version = ip_version;
10370   mp->transport_protocol = transport_protocol;
10371
10372   S (mp);
10373   W (ret);
10374   return ret;
10375 }
10376
10377 static int
10378 api_get_node_index (vat_main_t * vam)
10379 {
10380   unformat_input_t *i = vam->input;
10381   vl_api_get_node_index_t *mp;
10382   u8 *name = 0;
10383   int ret;
10384
10385   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10386     {
10387       if (unformat (i, "node %s", &name))
10388         ;
10389       else
10390         break;
10391     }
10392   if (name == 0)
10393     {
10394       errmsg ("node name required");
10395       return -99;
10396     }
10397   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10398     {
10399       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10400       return -99;
10401     }
10402
10403   M (GET_NODE_INDEX, mp);
10404   clib_memcpy (mp->node_name, name, vec_len (name));
10405   vec_free (name);
10406
10407   S (mp);
10408   W (ret);
10409   return ret;
10410 }
10411
10412 static int
10413 api_get_next_index (vat_main_t * vam)
10414 {
10415   unformat_input_t *i = vam->input;
10416   vl_api_get_next_index_t *mp;
10417   u8 *node_name = 0, *next_node_name = 0;
10418   int ret;
10419
10420   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10421     {
10422       if (unformat (i, "node-name %s", &node_name))
10423         ;
10424       else if (unformat (i, "next-node-name %s", &next_node_name))
10425         break;
10426     }
10427
10428   if (node_name == 0)
10429     {
10430       errmsg ("node name required");
10431       return -99;
10432     }
10433   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10434     {
10435       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10436       return -99;
10437     }
10438
10439   if (next_node_name == 0)
10440     {
10441       errmsg ("next node name required");
10442       return -99;
10443     }
10444   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10445     {
10446       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10447       return -99;
10448     }
10449
10450   M (GET_NEXT_INDEX, mp);
10451   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10452   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10453   vec_free (node_name);
10454   vec_free (next_node_name);
10455
10456   S (mp);
10457   W (ret);
10458   return ret;
10459 }
10460
10461 static int
10462 api_add_node_next (vat_main_t * vam)
10463 {
10464   unformat_input_t *i = vam->input;
10465   vl_api_add_node_next_t *mp;
10466   u8 *name = 0;
10467   u8 *next = 0;
10468   int ret;
10469
10470   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10471     {
10472       if (unformat (i, "node %s", &name))
10473         ;
10474       else if (unformat (i, "next %s", &next))
10475         ;
10476       else
10477         break;
10478     }
10479   if (name == 0)
10480     {
10481       errmsg ("node name required");
10482       return -99;
10483     }
10484   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10485     {
10486       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10487       return -99;
10488     }
10489   if (next == 0)
10490     {
10491       errmsg ("next node required");
10492       return -99;
10493     }
10494   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10495     {
10496       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10497       return -99;
10498     }
10499
10500   M (ADD_NODE_NEXT, mp);
10501   clib_memcpy (mp->node_name, name, vec_len (name));
10502   clib_memcpy (mp->next_name, next, vec_len (next));
10503   vec_free (name);
10504   vec_free (next);
10505
10506   S (mp);
10507   W (ret);
10508   return ret;
10509 }
10510
10511 static int
10512 api_l2tpv3_create_tunnel (vat_main_t * vam)
10513 {
10514   unformat_input_t *i = vam->input;
10515   ip6_address_t client_address, our_address;
10516   int client_address_set = 0;
10517   int our_address_set = 0;
10518   u32 local_session_id = 0;
10519   u32 remote_session_id = 0;
10520   u64 local_cookie = 0;
10521   u64 remote_cookie = 0;
10522   u8 l2_sublayer_present = 0;
10523   vl_api_l2tpv3_create_tunnel_t *mp;
10524   int ret;
10525
10526   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10527     {
10528       if (unformat (i, "client_address %U", unformat_ip6_address,
10529                     &client_address))
10530         client_address_set = 1;
10531       else if (unformat (i, "our_address %U", unformat_ip6_address,
10532                          &our_address))
10533         our_address_set = 1;
10534       else if (unformat (i, "local_session_id %d", &local_session_id))
10535         ;
10536       else if (unformat (i, "remote_session_id %d", &remote_session_id))
10537         ;
10538       else if (unformat (i, "local_cookie %lld", &local_cookie))
10539         ;
10540       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10541         ;
10542       else if (unformat (i, "l2-sublayer-present"))
10543         l2_sublayer_present = 1;
10544       else
10545         break;
10546     }
10547
10548   if (client_address_set == 0)
10549     {
10550       errmsg ("client_address required");
10551       return -99;
10552     }
10553
10554   if (our_address_set == 0)
10555     {
10556       errmsg ("our_address required");
10557       return -99;
10558     }
10559
10560   M (L2TPV3_CREATE_TUNNEL, mp);
10561
10562   clib_memcpy (mp->client_address, client_address.as_u8,
10563                sizeof (mp->client_address));
10564
10565   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10566
10567   mp->local_session_id = ntohl (local_session_id);
10568   mp->remote_session_id = ntohl (remote_session_id);
10569   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10570   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10571   mp->l2_sublayer_present = l2_sublayer_present;
10572   mp->is_ipv6 = 1;
10573
10574   S (mp);
10575   W (ret);
10576   return ret;
10577 }
10578
10579 static int
10580 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10581 {
10582   unformat_input_t *i = vam->input;
10583   u32 sw_if_index;
10584   u8 sw_if_index_set = 0;
10585   u64 new_local_cookie = 0;
10586   u64 new_remote_cookie = 0;
10587   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10588   int ret;
10589
10590   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10591     {
10592       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10593         sw_if_index_set = 1;
10594       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10595         sw_if_index_set = 1;
10596       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10597         ;
10598       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10599         ;
10600       else
10601         break;
10602     }
10603
10604   if (sw_if_index_set == 0)
10605     {
10606       errmsg ("missing interface name or sw_if_index");
10607       return -99;
10608     }
10609
10610   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
10611
10612   mp->sw_if_index = ntohl (sw_if_index);
10613   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10614   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10615
10616   S (mp);
10617   W (ret);
10618   return ret;
10619 }
10620
10621 static int
10622 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10623 {
10624   unformat_input_t *i = vam->input;
10625   vl_api_l2tpv3_interface_enable_disable_t *mp;
10626   u32 sw_if_index;
10627   u8 sw_if_index_set = 0;
10628   u8 enable_disable = 1;
10629   int ret;
10630
10631   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10632     {
10633       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10634         sw_if_index_set = 1;
10635       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10636         sw_if_index_set = 1;
10637       else if (unformat (i, "enable"))
10638         enable_disable = 1;
10639       else if (unformat (i, "disable"))
10640         enable_disable = 0;
10641       else
10642         break;
10643     }
10644
10645   if (sw_if_index_set == 0)
10646     {
10647       errmsg ("missing interface name or sw_if_index");
10648       return -99;
10649     }
10650
10651   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
10652
10653   mp->sw_if_index = ntohl (sw_if_index);
10654   mp->enable_disable = enable_disable;
10655
10656   S (mp);
10657   W (ret);
10658   return ret;
10659 }
10660
10661 static int
10662 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10663 {
10664   unformat_input_t *i = vam->input;
10665   vl_api_l2tpv3_set_lookup_key_t *mp;
10666   u8 key = ~0;
10667   int ret;
10668
10669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10670     {
10671       if (unformat (i, "lookup_v6_src"))
10672         key = L2T_LOOKUP_SRC_ADDRESS;
10673       else if (unformat (i, "lookup_v6_dst"))
10674         key = L2T_LOOKUP_DST_ADDRESS;
10675       else if (unformat (i, "lookup_session_id"))
10676         key = L2T_LOOKUP_SESSION_ID;
10677       else
10678         break;
10679     }
10680
10681   if (key == (u8) ~ 0)
10682     {
10683       errmsg ("l2tp session lookup key unset");
10684       return -99;
10685     }
10686
10687   M (L2TPV3_SET_LOOKUP_KEY, mp);
10688
10689   mp->key = key;
10690
10691   S (mp);
10692   W (ret);
10693   return ret;
10694 }
10695
10696 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10697   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10698 {
10699   vat_main_t *vam = &vat_main;
10700
10701   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10702          format_ip6_address, mp->our_address,
10703          format_ip6_address, mp->client_address,
10704          clib_net_to_host_u32 (mp->sw_if_index));
10705
10706   print (vam->ofp,
10707          "   local cookies %016llx %016llx remote cookie %016llx",
10708          clib_net_to_host_u64 (mp->local_cookie[0]),
10709          clib_net_to_host_u64 (mp->local_cookie[1]),
10710          clib_net_to_host_u64 (mp->remote_cookie));
10711
10712   print (vam->ofp, "   local session-id %d remote session-id %d",
10713          clib_net_to_host_u32 (mp->local_session_id),
10714          clib_net_to_host_u32 (mp->remote_session_id));
10715
10716   print (vam->ofp, "   l2 specific sublayer %s\n",
10717          mp->l2_sublayer_present ? "preset" : "absent");
10718
10719 }
10720
10721 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10722   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10723 {
10724   vat_main_t *vam = &vat_main;
10725   vat_json_node_t *node = NULL;
10726   struct in6_addr addr;
10727
10728   if (VAT_JSON_ARRAY != vam->json_tree.type)
10729     {
10730       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10731       vat_json_init_array (&vam->json_tree);
10732     }
10733   node = vat_json_array_add (&vam->json_tree);
10734
10735   vat_json_init_object (node);
10736
10737   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10738   vat_json_object_add_ip6 (node, "our_address", addr);
10739   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10740   vat_json_object_add_ip6 (node, "client_address", addr);
10741
10742   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10743   vat_json_init_array (lc);
10744   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10745   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10746   vat_json_object_add_uint (node, "remote_cookie",
10747                             clib_net_to_host_u64 (mp->remote_cookie));
10748
10749   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10750   vat_json_object_add_uint (node, "local_session_id",
10751                             clib_net_to_host_u32 (mp->local_session_id));
10752   vat_json_object_add_uint (node, "remote_session_id",
10753                             clib_net_to_host_u32 (mp->remote_session_id));
10754   vat_json_object_add_string_copy (node, "l2_sublayer",
10755                                    mp->l2_sublayer_present ? (u8 *) "present"
10756                                    : (u8 *) "absent");
10757 }
10758
10759 static int
10760 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10761 {
10762   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10763   vl_api_control_ping_t *mp_ping;
10764   int ret;
10765
10766   /* Get list of l2tpv3-tunnel interfaces */
10767   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
10768   S (mp);
10769
10770   /* Use a control ping for synchronization */
10771   M (CONTROL_PING, mp_ping);
10772   S (mp_ping);
10773
10774   W (ret);
10775   return ret;
10776 }
10777
10778
10779 static void vl_api_sw_interface_tap_details_t_handler
10780   (vl_api_sw_interface_tap_details_t * mp)
10781 {
10782   vat_main_t *vam = &vat_main;
10783
10784   print (vam->ofp, "%-16s %d",
10785          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10786 }
10787
10788 static void vl_api_sw_interface_tap_details_t_handler_json
10789   (vl_api_sw_interface_tap_details_t * mp)
10790 {
10791   vat_main_t *vam = &vat_main;
10792   vat_json_node_t *node = NULL;
10793
10794   if (VAT_JSON_ARRAY != vam->json_tree.type)
10795     {
10796       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10797       vat_json_init_array (&vam->json_tree);
10798     }
10799   node = vat_json_array_add (&vam->json_tree);
10800
10801   vat_json_init_object (node);
10802   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10803   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10804 }
10805
10806 static int
10807 api_sw_interface_tap_dump (vat_main_t * vam)
10808 {
10809   vl_api_sw_interface_tap_dump_t *mp;
10810   vl_api_control_ping_t *mp_ping;
10811   int ret;
10812
10813   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10814   /* Get list of tap interfaces */
10815   M (SW_INTERFACE_TAP_DUMP, mp);
10816   S (mp);
10817
10818   /* Use a control ping for synchronization */
10819   M (CONTROL_PING, mp_ping);
10820   S (mp_ping);
10821
10822   W (ret);
10823   return ret;
10824 }
10825
10826 static uword unformat_vxlan_decap_next
10827   (unformat_input_t * input, va_list * args)
10828 {
10829   u32 *result = va_arg (*args, u32 *);
10830   u32 tmp;
10831
10832   if (unformat (input, "l2"))
10833     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10834   else if (unformat (input, "%d", &tmp))
10835     *result = tmp;
10836   else
10837     return 0;
10838   return 1;
10839 }
10840
10841 static int
10842 api_vxlan_add_del_tunnel (vat_main_t * vam)
10843 {
10844   unformat_input_t *line_input = vam->input;
10845   vl_api_vxlan_add_del_tunnel_t *mp;
10846   ip46_address_t src, dst;
10847   u8 is_add = 1;
10848   u8 ipv4_set = 0, ipv6_set = 0;
10849   u8 src_set = 0;
10850   u8 dst_set = 0;
10851   u8 grp_set = 0;
10852   u32 mcast_sw_if_index = ~0;
10853   u32 encap_vrf_id = 0;
10854   u32 decap_next_index = ~0;
10855   u32 vni = 0;
10856   int ret;
10857
10858   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10859   memset (&src, 0, sizeof src);
10860   memset (&dst, 0, sizeof dst);
10861
10862   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10863     {
10864       if (unformat (line_input, "del"))
10865         is_add = 0;
10866       else
10867         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10868         {
10869           ipv4_set = 1;
10870           src_set = 1;
10871         }
10872       else
10873         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10874         {
10875           ipv4_set = 1;
10876           dst_set = 1;
10877         }
10878       else
10879         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10880         {
10881           ipv6_set = 1;
10882           src_set = 1;
10883         }
10884       else
10885         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10886         {
10887           ipv6_set = 1;
10888           dst_set = 1;
10889         }
10890       else if (unformat (line_input, "group %U %U",
10891                          unformat_ip4_address, &dst.ip4,
10892                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10893         {
10894           grp_set = dst_set = 1;
10895           ipv4_set = 1;
10896         }
10897       else if (unformat (line_input, "group %U",
10898                          unformat_ip4_address, &dst.ip4))
10899         {
10900           grp_set = dst_set = 1;
10901           ipv4_set = 1;
10902         }
10903       else if (unformat (line_input, "group %U %U",
10904                          unformat_ip6_address, &dst.ip6,
10905                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10906         {
10907           grp_set = dst_set = 1;
10908           ipv6_set = 1;
10909         }
10910       else if (unformat (line_input, "group %U",
10911                          unformat_ip6_address, &dst.ip6))
10912         {
10913           grp_set = dst_set = 1;
10914           ipv6_set = 1;
10915         }
10916       else
10917         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10918         ;
10919       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10920         ;
10921       else if (unformat (line_input, "decap-next %U",
10922                          unformat_vxlan_decap_next, &decap_next_index))
10923         ;
10924       else if (unformat (line_input, "vni %d", &vni))
10925         ;
10926       else
10927         {
10928           errmsg ("parse error '%U'", format_unformat_error, line_input);
10929           return -99;
10930         }
10931     }
10932
10933   if (src_set == 0)
10934     {
10935       errmsg ("tunnel src address not specified");
10936       return -99;
10937     }
10938   if (dst_set == 0)
10939     {
10940       errmsg ("tunnel dst address not specified");
10941       return -99;
10942     }
10943
10944   if (grp_set && !ip46_address_is_multicast (&dst))
10945     {
10946       errmsg ("tunnel group address not multicast");
10947       return -99;
10948     }
10949   if (grp_set && mcast_sw_if_index == ~0)
10950     {
10951       errmsg ("tunnel nonexistent multicast device");
10952       return -99;
10953     }
10954   if (grp_set == 0 && ip46_address_is_multicast (&dst))
10955     {
10956       errmsg ("tunnel dst address must be unicast");
10957       return -99;
10958     }
10959
10960
10961   if (ipv4_set && ipv6_set)
10962     {
10963       errmsg ("both IPv4 and IPv6 addresses specified");
10964       return -99;
10965     }
10966
10967   if ((vni == 0) || (vni >> 24))
10968     {
10969       errmsg ("vni not specified or out of range");
10970       return -99;
10971     }
10972
10973   M (VXLAN_ADD_DEL_TUNNEL, mp);
10974
10975   if (ipv6_set)
10976     {
10977       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10978       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10979     }
10980   else
10981     {
10982       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10983       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10984     }
10985   mp->encap_vrf_id = ntohl (encap_vrf_id);
10986   mp->decap_next_index = ntohl (decap_next_index);
10987   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10988   mp->vni = ntohl (vni);
10989   mp->is_add = is_add;
10990   mp->is_ipv6 = ipv6_set;
10991
10992   S (mp);
10993   W (ret);
10994   return ret;
10995 }
10996
10997 static void vl_api_vxlan_tunnel_details_t_handler
10998   (vl_api_vxlan_tunnel_details_t * mp)
10999 {
11000   vat_main_t *vam = &vat_main;
11001   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
11002   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
11003
11004   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
11005          ntohl (mp->sw_if_index),
11006          format_ip46_address, &src, IP46_TYPE_ANY,
11007          format_ip46_address, &dst, IP46_TYPE_ANY,
11008          ntohl (mp->encap_vrf_id),
11009          ntohl (mp->decap_next_index), ntohl (mp->vni),
11010          ntohl (mp->mcast_sw_if_index));
11011 }
11012
11013 static void vl_api_vxlan_tunnel_details_t_handler_json
11014   (vl_api_vxlan_tunnel_details_t * mp)
11015 {
11016   vat_main_t *vam = &vat_main;
11017   vat_json_node_t *node = NULL;
11018
11019   if (VAT_JSON_ARRAY != vam->json_tree.type)
11020     {
11021       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11022       vat_json_init_array (&vam->json_tree);
11023     }
11024   node = vat_json_array_add (&vam->json_tree);
11025
11026   vat_json_init_object (node);
11027   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11028   if (mp->is_ipv6)
11029     {
11030       struct in6_addr ip6;
11031
11032       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
11033       vat_json_object_add_ip6 (node, "src_address", ip6);
11034       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
11035       vat_json_object_add_ip6 (node, "dst_address", ip6);
11036     }
11037   else
11038     {
11039       struct in_addr ip4;
11040
11041       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
11042       vat_json_object_add_ip4 (node, "src_address", ip4);
11043       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
11044       vat_json_object_add_ip4 (node, "dst_address", ip4);
11045     }
11046   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11047   vat_json_object_add_uint (node, "decap_next_index",
11048                             ntohl (mp->decap_next_index));
11049   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11050   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11051   vat_json_object_add_uint (node, "mcast_sw_if_index",
11052                             ntohl (mp->mcast_sw_if_index));
11053 }
11054
11055 static int
11056 api_vxlan_tunnel_dump (vat_main_t * vam)
11057 {
11058   unformat_input_t *i = vam->input;
11059   vl_api_vxlan_tunnel_dump_t *mp;
11060   vl_api_control_ping_t *mp_ping;
11061   u32 sw_if_index;
11062   u8 sw_if_index_set = 0;
11063   int ret;
11064
11065   /* Parse args required to build the message */
11066   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11067     {
11068       if (unformat (i, "sw_if_index %d", &sw_if_index))
11069         sw_if_index_set = 1;
11070       else
11071         break;
11072     }
11073
11074   if (sw_if_index_set == 0)
11075     {
11076       sw_if_index = ~0;
11077     }
11078
11079   if (!vam->json_output)
11080     {
11081       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
11082              "sw_if_index", "src_address", "dst_address",
11083              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11084     }
11085
11086   /* Get list of vxlan-tunnel interfaces */
11087   M (VXLAN_TUNNEL_DUMP, mp);
11088
11089   mp->sw_if_index = htonl (sw_if_index);
11090
11091   S (mp);
11092
11093   /* Use a control ping for synchronization */
11094   M (CONTROL_PING, mp_ping);
11095   S (mp_ping);
11096
11097   W (ret);
11098   return ret;
11099 }
11100
11101 static int
11102 api_gre_add_del_tunnel (vat_main_t * vam)
11103 {
11104   unformat_input_t *line_input = vam->input;
11105   vl_api_gre_add_del_tunnel_t *mp;
11106   ip4_address_t src4, dst4;
11107   ip6_address_t src6, dst6;
11108   u8 is_add = 1;
11109   u8 ipv4_set = 0;
11110   u8 ipv6_set = 0;
11111   u8 teb = 0;
11112   u8 src_set = 0;
11113   u8 dst_set = 0;
11114   u32 outer_fib_id = 0;
11115   int ret;
11116
11117   memset (&src4, 0, sizeof src4);
11118   memset (&dst4, 0, sizeof dst4);
11119   memset (&src6, 0, sizeof src6);
11120   memset (&dst6, 0, sizeof dst6);
11121
11122   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11123     {
11124       if (unformat (line_input, "del"))
11125         is_add = 0;
11126       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
11127         {
11128           src_set = 1;
11129           ipv4_set = 1;
11130         }
11131       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
11132         {
11133           dst_set = 1;
11134           ipv4_set = 1;
11135         }
11136       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
11137         {
11138           src_set = 1;
11139           ipv6_set = 1;
11140         }
11141       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
11142         {
11143           dst_set = 1;
11144           ipv6_set = 1;
11145         }
11146       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
11147         ;
11148       else if (unformat (line_input, "teb"))
11149         teb = 1;
11150       else
11151         {
11152           errmsg ("parse error '%U'", format_unformat_error, line_input);
11153           return -99;
11154         }
11155     }
11156
11157   if (src_set == 0)
11158     {
11159       errmsg ("tunnel src address not specified");
11160       return -99;
11161     }
11162   if (dst_set == 0)
11163     {
11164       errmsg ("tunnel dst address not specified");
11165       return -99;
11166     }
11167   if (ipv4_set && ipv6_set)
11168     {
11169       errmsg ("both IPv4 and IPv6 addresses specified");
11170       return -99;
11171     }
11172
11173
11174   M (GRE_ADD_DEL_TUNNEL, mp);
11175
11176   if (ipv4_set)
11177     {
11178       clib_memcpy (&mp->src_address, &src4, 4);
11179       clib_memcpy (&mp->dst_address, &dst4, 4);
11180     }
11181   else
11182     {
11183       clib_memcpy (&mp->src_address, &src6, 16);
11184       clib_memcpy (&mp->dst_address, &dst6, 16);
11185     }
11186   mp->outer_fib_id = ntohl (outer_fib_id);
11187   mp->is_add = is_add;
11188   mp->teb = teb;
11189   mp->is_ipv6 = ipv6_set;
11190
11191   S (mp);
11192   W (ret);
11193   return ret;
11194 }
11195
11196 static void vl_api_gre_tunnel_details_t_handler
11197   (vl_api_gre_tunnel_details_t * mp)
11198 {
11199   vat_main_t *vam = &vat_main;
11200   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
11201   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
11202
11203   print (vam->ofp, "%11d%24U%24U%6d%14d",
11204          ntohl (mp->sw_if_index),
11205          format_ip46_address, &src, IP46_TYPE_ANY,
11206          format_ip46_address, &dst, IP46_TYPE_ANY,
11207          mp->teb, ntohl (mp->outer_fib_id));
11208 }
11209
11210 static void vl_api_gre_tunnel_details_t_handler_json
11211   (vl_api_gre_tunnel_details_t * mp)
11212 {
11213   vat_main_t *vam = &vat_main;
11214   vat_json_node_t *node = NULL;
11215   struct in_addr ip4;
11216   struct in6_addr ip6;
11217
11218   if (VAT_JSON_ARRAY != vam->json_tree.type)
11219     {
11220       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11221       vat_json_init_array (&vam->json_tree);
11222     }
11223   node = vat_json_array_add (&vam->json_tree);
11224
11225   vat_json_init_object (node);
11226   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11227   if (!mp->is_ipv6)
11228     {
11229       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
11230       vat_json_object_add_ip4 (node, "src_address", ip4);
11231       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
11232       vat_json_object_add_ip4 (node, "dst_address", ip4);
11233     }
11234   else
11235     {
11236       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
11237       vat_json_object_add_ip6 (node, "src_address", ip6);
11238       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
11239       vat_json_object_add_ip6 (node, "dst_address", ip6);
11240     }
11241   vat_json_object_add_uint (node, "teb", mp->teb);
11242   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
11243   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
11244 }
11245
11246 static int
11247 api_gre_tunnel_dump (vat_main_t * vam)
11248 {
11249   unformat_input_t *i = vam->input;
11250   vl_api_gre_tunnel_dump_t *mp;
11251   vl_api_control_ping_t *mp_ping;
11252   u32 sw_if_index;
11253   u8 sw_if_index_set = 0;
11254   int ret;
11255
11256   /* Parse args required to build the message */
11257   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11258     {
11259       if (unformat (i, "sw_if_index %d", &sw_if_index))
11260         sw_if_index_set = 1;
11261       else
11262         break;
11263     }
11264
11265   if (sw_if_index_set == 0)
11266     {
11267       sw_if_index = ~0;
11268     }
11269
11270   if (!vam->json_output)
11271     {
11272       print (vam->ofp, "%11s%24s%24s%6s%14s",
11273              "sw_if_index", "src_address", "dst_address", "teb",
11274              "outer_fib_id");
11275     }
11276
11277   /* Get list of gre-tunnel interfaces */
11278   M (GRE_TUNNEL_DUMP, mp);
11279
11280   mp->sw_if_index = htonl (sw_if_index);
11281
11282   S (mp);
11283
11284   /* Use a control ping for synchronization */
11285   M (CONTROL_PING, mp_ping);
11286   S (mp_ping);
11287
11288   W (ret);
11289   return ret;
11290 }
11291
11292 static int
11293 api_l2_fib_clear_table (vat_main_t * vam)
11294 {
11295 //  unformat_input_t * i = vam->input;
11296   vl_api_l2_fib_clear_table_t *mp;
11297   int ret;
11298
11299   M (L2_FIB_CLEAR_TABLE, mp);
11300
11301   S (mp);
11302   W (ret);
11303   return ret;
11304 }
11305
11306 static int
11307 api_l2_interface_efp_filter (vat_main_t * vam)
11308 {
11309   unformat_input_t *i = vam->input;
11310   vl_api_l2_interface_efp_filter_t *mp;
11311   u32 sw_if_index;
11312   u8 enable = 1;
11313   u8 sw_if_index_set = 0;
11314   int ret;
11315
11316   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11317     {
11318       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11319         sw_if_index_set = 1;
11320       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11321         sw_if_index_set = 1;
11322       else if (unformat (i, "enable"))
11323         enable = 1;
11324       else if (unformat (i, "disable"))
11325         enable = 0;
11326       else
11327         {
11328           clib_warning ("parse error '%U'", format_unformat_error, i);
11329           return -99;
11330         }
11331     }
11332
11333   if (sw_if_index_set == 0)
11334     {
11335       errmsg ("missing sw_if_index");
11336       return -99;
11337     }
11338
11339   M (L2_INTERFACE_EFP_FILTER, mp);
11340
11341   mp->sw_if_index = ntohl (sw_if_index);
11342   mp->enable_disable = enable;
11343
11344   S (mp);
11345   W (ret);
11346   return ret;
11347 }
11348
11349 #define foreach_vtr_op                          \
11350 _("disable",  L2_VTR_DISABLED)                  \
11351 _("push-1",  L2_VTR_PUSH_1)                     \
11352 _("push-2",  L2_VTR_PUSH_2)                     \
11353 _("pop-1",  L2_VTR_POP_1)                       \
11354 _("pop-2",  L2_VTR_POP_2)                       \
11355 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
11356 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
11357 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
11358 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
11359
11360 static int
11361 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
11362 {
11363   unformat_input_t *i = vam->input;
11364   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
11365   u32 sw_if_index;
11366   u8 sw_if_index_set = 0;
11367   u8 vtr_op_set = 0;
11368   u32 vtr_op = 0;
11369   u32 push_dot1q = 1;
11370   u32 tag1 = ~0;
11371   u32 tag2 = ~0;
11372   int ret;
11373
11374   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11375     {
11376       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11377         sw_if_index_set = 1;
11378       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11379         sw_if_index_set = 1;
11380       else if (unformat (i, "vtr_op %d", &vtr_op))
11381         vtr_op_set = 1;
11382 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
11383       foreach_vtr_op
11384 #undef _
11385         else if (unformat (i, "push_dot1q %d", &push_dot1q))
11386         ;
11387       else if (unformat (i, "tag1 %d", &tag1))
11388         ;
11389       else if (unformat (i, "tag2 %d", &tag2))
11390         ;
11391       else
11392         {
11393           clib_warning ("parse error '%U'", format_unformat_error, i);
11394           return -99;
11395         }
11396     }
11397
11398   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
11399     {
11400       errmsg ("missing vtr operation or sw_if_index");
11401       return -99;
11402     }
11403
11404   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
11405   mp->sw_if_index = ntohl (sw_if_index);
11406   mp->vtr_op = ntohl (vtr_op);
11407   mp->push_dot1q = ntohl (push_dot1q);
11408   mp->tag1 = ntohl (tag1);
11409   mp->tag2 = ntohl (tag2);
11410
11411   S (mp);
11412   W (ret);
11413   return ret;
11414 }
11415
11416 static int
11417 api_create_vhost_user_if (vat_main_t * vam)
11418 {
11419   unformat_input_t *i = vam->input;
11420   vl_api_create_vhost_user_if_t *mp;
11421   u8 *file_name;
11422   u8 is_server = 0;
11423   u8 file_name_set = 0;
11424   u32 custom_dev_instance = ~0;
11425   u8 hwaddr[6];
11426   u8 use_custom_mac = 0;
11427   u8 *tag = 0;
11428   int ret;
11429   u8 operation_mode = VHOST_USER_POLLING_MODE;
11430
11431   /* Shut up coverity */
11432   memset (hwaddr, 0, sizeof (hwaddr));
11433
11434   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11435     {
11436       if (unformat (i, "socket %s", &file_name))
11437         {
11438           file_name_set = 1;
11439         }
11440       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11441         ;
11442       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
11443         use_custom_mac = 1;
11444       else if (unformat (i, "server"))
11445         is_server = 1;
11446       else if (unformat (i, "tag %s", &tag))
11447         ;
11448       else if (unformat (i, "mode %U",
11449                          api_unformat_vhost_user_operation_mode,
11450                          &operation_mode))
11451         ;
11452       else
11453         break;
11454     }
11455
11456   if (file_name_set == 0)
11457     {
11458       errmsg ("missing socket file name");
11459       return -99;
11460     }
11461
11462   if (vec_len (file_name) > 255)
11463     {
11464       errmsg ("socket file name too long");
11465       return -99;
11466     }
11467   vec_add1 (file_name, 0);
11468
11469   M (CREATE_VHOST_USER_IF, mp);
11470
11471   mp->operation_mode = operation_mode;
11472   mp->is_server = is_server;
11473   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11474   vec_free (file_name);
11475   if (custom_dev_instance != ~0)
11476     {
11477       mp->renumber = 1;
11478       mp->custom_dev_instance = ntohl (custom_dev_instance);
11479     }
11480   mp->use_custom_mac = use_custom_mac;
11481   clib_memcpy (mp->mac_address, hwaddr, 6);
11482   if (tag)
11483     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
11484   vec_free (tag);
11485
11486   S (mp);
11487   W (ret);
11488   return ret;
11489 }
11490
11491 static int
11492 api_modify_vhost_user_if (vat_main_t * vam)
11493 {
11494   unformat_input_t *i = vam->input;
11495   vl_api_modify_vhost_user_if_t *mp;
11496   u8 *file_name;
11497   u8 is_server = 0;
11498   u8 file_name_set = 0;
11499   u32 custom_dev_instance = ~0;
11500   u8 sw_if_index_set = 0;
11501   u32 sw_if_index = (u32) ~ 0;
11502   int ret;
11503   u8 operation_mode = VHOST_USER_POLLING_MODE;
11504
11505   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11506     {
11507       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11508         sw_if_index_set = 1;
11509       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11510         sw_if_index_set = 1;
11511       else if (unformat (i, "socket %s", &file_name))
11512         {
11513           file_name_set = 1;
11514         }
11515       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11516         ;
11517       else if (unformat (i, "server"))
11518         is_server = 1;
11519       else if (unformat (i, "mode %U",
11520                          api_unformat_vhost_user_operation_mode,
11521                          &operation_mode))
11522         ;
11523       else
11524         break;
11525     }
11526
11527   if (sw_if_index_set == 0)
11528     {
11529       errmsg ("missing sw_if_index or interface name");
11530       return -99;
11531     }
11532
11533   if (file_name_set == 0)
11534     {
11535       errmsg ("missing socket file name");
11536       return -99;
11537     }
11538
11539   if (vec_len (file_name) > 255)
11540     {
11541       errmsg ("socket file name too long");
11542       return -99;
11543     }
11544   vec_add1 (file_name, 0);
11545
11546   M (MODIFY_VHOST_USER_IF, mp);
11547
11548   mp->operation_mode = operation_mode;
11549   mp->sw_if_index = ntohl (sw_if_index);
11550   mp->is_server = is_server;
11551   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11552   vec_free (file_name);
11553   if (custom_dev_instance != ~0)
11554     {
11555       mp->renumber = 1;
11556       mp->custom_dev_instance = ntohl (custom_dev_instance);
11557     }
11558
11559   S (mp);
11560   W (ret);
11561   return ret;
11562 }
11563
11564 static int
11565 api_delete_vhost_user_if (vat_main_t * vam)
11566 {
11567   unformat_input_t *i = vam->input;
11568   vl_api_delete_vhost_user_if_t *mp;
11569   u32 sw_if_index = ~0;
11570   u8 sw_if_index_set = 0;
11571   int ret;
11572
11573   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11574     {
11575       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11576         sw_if_index_set = 1;
11577       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11578         sw_if_index_set = 1;
11579       else
11580         break;
11581     }
11582
11583   if (sw_if_index_set == 0)
11584     {
11585       errmsg ("missing sw_if_index or interface name");
11586       return -99;
11587     }
11588
11589
11590   M (DELETE_VHOST_USER_IF, mp);
11591
11592   mp->sw_if_index = ntohl (sw_if_index);
11593
11594   S (mp);
11595   W (ret);
11596   return ret;
11597 }
11598
11599 static void vl_api_sw_interface_vhost_user_details_t_handler
11600   (vl_api_sw_interface_vhost_user_details_t * mp)
11601 {
11602   vat_main_t *vam = &vat_main;
11603
11604   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %U %s",
11605          (char *) mp->interface_name,
11606          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11607          clib_net_to_host_u64 (mp->features), mp->is_server,
11608          ntohl (mp->num_regions), api_format_vhost_user_operation_mode,
11609          mp->operation_mode, (char *) mp->sock_filename);
11610   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
11611 }
11612
11613 static void vl_api_sw_interface_vhost_user_details_t_handler_json
11614   (vl_api_sw_interface_vhost_user_details_t * mp)
11615 {
11616   vat_main_t *vam = &vat_main;
11617   vat_json_node_t *node = NULL;
11618
11619   if (VAT_JSON_ARRAY != vam->json_tree.type)
11620     {
11621       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11622       vat_json_init_array (&vam->json_tree);
11623     }
11624   node = vat_json_array_add (&vam->json_tree);
11625
11626   vat_json_init_object (node);
11627   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11628   vat_json_object_add_string_copy (node, "interface_name",
11629                                    mp->interface_name);
11630   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11631                             ntohl (mp->virtio_net_hdr_sz));
11632   vat_json_object_add_uint (node, "features",
11633                             clib_net_to_host_u64 (mp->features));
11634   vat_json_object_add_uint (node, "is_server", mp->is_server);
11635   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11636   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11637   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11638   vat_json_object_add_uint (node, "mode", mp->operation_mode);
11639 }
11640
11641 static int
11642 api_sw_interface_vhost_user_dump (vat_main_t * vam)
11643 {
11644   vl_api_sw_interface_vhost_user_dump_t *mp;
11645   vl_api_control_ping_t *mp_ping;
11646   int ret;
11647   print (vam->ofp,
11648          "Interface name            idx hdr_sz features server regions mode"
11649          "      filename");
11650
11651   /* Get list of vhost-user interfaces */
11652   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
11653   S (mp);
11654
11655   /* Use a control ping for synchronization */
11656   M (CONTROL_PING, mp_ping);
11657   S (mp_ping);
11658
11659   W (ret);
11660   return ret;
11661 }
11662
11663 static int
11664 api_show_version (vat_main_t * vam)
11665 {
11666   vl_api_show_version_t *mp;
11667   int ret;
11668
11669   M (SHOW_VERSION, mp);
11670
11671   S (mp);
11672   W (ret);
11673   return ret;
11674 }
11675
11676
11677 static int
11678 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11679 {
11680   unformat_input_t *line_input = vam->input;
11681   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11682   ip4_address_t local4, remote4;
11683   ip6_address_t local6, remote6;
11684   u8 is_add = 1;
11685   u8 ipv4_set = 0, ipv6_set = 0;
11686   u8 local_set = 0;
11687   u8 remote_set = 0;
11688   u32 encap_vrf_id = 0;
11689   u32 decap_vrf_id = 0;
11690   u8 protocol = ~0;
11691   u32 vni;
11692   u8 vni_set = 0;
11693   int ret;
11694
11695   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11696     {
11697       if (unformat (line_input, "del"))
11698         is_add = 0;
11699       else if (unformat (line_input, "local %U",
11700                          unformat_ip4_address, &local4))
11701         {
11702           local_set = 1;
11703           ipv4_set = 1;
11704         }
11705       else if (unformat (line_input, "remote %U",
11706                          unformat_ip4_address, &remote4))
11707         {
11708           remote_set = 1;
11709           ipv4_set = 1;
11710         }
11711       else if (unformat (line_input, "local %U",
11712                          unformat_ip6_address, &local6))
11713         {
11714           local_set = 1;
11715           ipv6_set = 1;
11716         }
11717       else if (unformat (line_input, "remote %U",
11718                          unformat_ip6_address, &remote6))
11719         {
11720           remote_set = 1;
11721           ipv6_set = 1;
11722         }
11723       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11724         ;
11725       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11726         ;
11727       else if (unformat (line_input, "vni %d", &vni))
11728         vni_set = 1;
11729       else if (unformat (line_input, "next-ip4"))
11730         protocol = 1;
11731       else if (unformat (line_input, "next-ip6"))
11732         protocol = 2;
11733       else if (unformat (line_input, "next-ethernet"))
11734         protocol = 3;
11735       else if (unformat (line_input, "next-nsh"))
11736         protocol = 4;
11737       else
11738         {
11739           errmsg ("parse error '%U'", format_unformat_error, line_input);
11740           return -99;
11741         }
11742     }
11743
11744   if (local_set == 0)
11745     {
11746       errmsg ("tunnel local address not specified");
11747       return -99;
11748     }
11749   if (remote_set == 0)
11750     {
11751       errmsg ("tunnel remote address not specified");
11752       return -99;
11753     }
11754   if (ipv4_set && ipv6_set)
11755     {
11756       errmsg ("both IPv4 and IPv6 addresses specified");
11757       return -99;
11758     }
11759
11760   if (vni_set == 0)
11761     {
11762       errmsg ("vni not specified");
11763       return -99;
11764     }
11765
11766   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
11767
11768
11769   if (ipv6_set)
11770     {
11771       clib_memcpy (&mp->local, &local6, sizeof (local6));
11772       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11773     }
11774   else
11775     {
11776       clib_memcpy (&mp->local, &local4, sizeof (local4));
11777       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11778     }
11779
11780   mp->encap_vrf_id = ntohl (encap_vrf_id);
11781   mp->decap_vrf_id = ntohl (decap_vrf_id);
11782   mp->protocol = protocol;
11783   mp->vni = ntohl (vni);
11784   mp->is_add = is_add;
11785   mp->is_ipv6 = ipv6_set;
11786
11787   S (mp);
11788   W (ret);
11789   return ret;
11790 }
11791
11792 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11793   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11794 {
11795   vat_main_t *vam = &vat_main;
11796
11797   print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11798          ntohl (mp->sw_if_index),
11799          format_ip46_address, &(mp->local[0]),
11800          format_ip46_address, &(mp->remote[0]),
11801          ntohl (mp->vni),
11802          ntohl (mp->protocol),
11803          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11804 }
11805
11806 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11807   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11808 {
11809   vat_main_t *vam = &vat_main;
11810   vat_json_node_t *node = NULL;
11811   struct in_addr ip4;
11812   struct in6_addr ip6;
11813
11814   if (VAT_JSON_ARRAY != vam->json_tree.type)
11815     {
11816       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11817       vat_json_init_array (&vam->json_tree);
11818     }
11819   node = vat_json_array_add (&vam->json_tree);
11820
11821   vat_json_init_object (node);
11822   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11823   if (mp->is_ipv6)
11824     {
11825       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11826       vat_json_object_add_ip6 (node, "local", ip6);
11827       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11828       vat_json_object_add_ip6 (node, "remote", ip6);
11829     }
11830   else
11831     {
11832       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11833       vat_json_object_add_ip4 (node, "local", ip4);
11834       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11835       vat_json_object_add_ip4 (node, "remote", ip4);
11836     }
11837   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11838   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11839   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11840   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11841   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11842 }
11843
11844 static int
11845 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11846 {
11847   unformat_input_t *i = vam->input;
11848   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11849   vl_api_control_ping_t *mp_ping;
11850   u32 sw_if_index;
11851   u8 sw_if_index_set = 0;
11852   int ret;
11853
11854   /* Parse args required to build the message */
11855   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11856     {
11857       if (unformat (i, "sw_if_index %d", &sw_if_index))
11858         sw_if_index_set = 1;
11859       else
11860         break;
11861     }
11862
11863   if (sw_if_index_set == 0)
11864     {
11865       sw_if_index = ~0;
11866     }
11867
11868   if (!vam->json_output)
11869     {
11870       print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11871              "sw_if_index", "local", "remote", "vni",
11872              "protocol", "encap_vrf_id", "decap_vrf_id");
11873     }
11874
11875   /* Get list of vxlan-tunnel interfaces */
11876   M (VXLAN_GPE_TUNNEL_DUMP, mp);
11877
11878   mp->sw_if_index = htonl (sw_if_index);
11879
11880   S (mp);
11881
11882   /* Use a control ping for synchronization */
11883   M (CONTROL_PING, mp_ping);
11884   S (mp_ping);
11885
11886   W (ret);
11887   return ret;
11888 }
11889
11890 u8 *
11891 format_l2_fib_mac_address (u8 * s, va_list * args)
11892 {
11893   u8 *a = va_arg (*args, u8 *);
11894
11895   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11896                  a[2], a[3], a[4], a[5], a[6], a[7]);
11897 }
11898
11899 static void vl_api_l2_fib_table_entry_t_handler
11900   (vl_api_l2_fib_table_entry_t * mp)
11901 {
11902   vat_main_t *vam = &vat_main;
11903
11904   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11905          "       %d       %d     %d",
11906          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11907          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11908          mp->bvi_mac);
11909 }
11910
11911 static void vl_api_l2_fib_table_entry_t_handler_json
11912   (vl_api_l2_fib_table_entry_t * mp)
11913 {
11914   vat_main_t *vam = &vat_main;
11915   vat_json_node_t *node = NULL;
11916
11917   if (VAT_JSON_ARRAY != vam->json_tree.type)
11918     {
11919       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11920       vat_json_init_array (&vam->json_tree);
11921     }
11922   node = vat_json_array_add (&vam->json_tree);
11923
11924   vat_json_init_object (node);
11925   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11926   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11927   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11928   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11929   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11930   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11931 }
11932
11933 static int
11934 api_l2_fib_table_dump (vat_main_t * vam)
11935 {
11936   unformat_input_t *i = vam->input;
11937   vl_api_l2_fib_table_dump_t *mp;
11938   vl_api_control_ping_t *mp_ping;
11939   u32 bd_id;
11940   u8 bd_id_set = 0;
11941   int ret;
11942
11943   /* Parse args required to build the message */
11944   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11945     {
11946       if (unformat (i, "bd_id %d", &bd_id))
11947         bd_id_set = 1;
11948       else
11949         break;
11950     }
11951
11952   if (bd_id_set == 0)
11953     {
11954       errmsg ("missing bridge domain");
11955       return -99;
11956     }
11957
11958   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
11959
11960   /* Get list of l2 fib entries */
11961   M (L2_FIB_TABLE_DUMP, mp);
11962
11963   mp->bd_id = ntohl (bd_id);
11964   S (mp);
11965
11966   /* Use a control ping for synchronization */
11967   M (CONTROL_PING, mp_ping);
11968   S (mp_ping);
11969
11970   W (ret);
11971   return ret;
11972 }
11973
11974
11975 static int
11976 api_interface_name_renumber (vat_main_t * vam)
11977 {
11978   unformat_input_t *line_input = vam->input;
11979   vl_api_interface_name_renumber_t *mp;
11980   u32 sw_if_index = ~0;
11981   u32 new_show_dev_instance = ~0;
11982   int ret;
11983
11984   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11985     {
11986       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
11987                     &sw_if_index))
11988         ;
11989       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11990         ;
11991       else if (unformat (line_input, "new_show_dev_instance %d",
11992                          &new_show_dev_instance))
11993         ;
11994       else
11995         break;
11996     }
11997
11998   if (sw_if_index == ~0)
11999     {
12000       errmsg ("missing interface name or sw_if_index");
12001       return -99;
12002     }
12003
12004   if (new_show_dev_instance == ~0)
12005     {
12006       errmsg ("missing new_show_dev_instance");
12007       return -99;
12008     }
12009
12010   M (INTERFACE_NAME_RENUMBER, mp);
12011
12012   mp->sw_if_index = ntohl (sw_if_index);
12013   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
12014
12015   S (mp);
12016   W (ret);
12017   return ret;
12018 }
12019
12020 static int
12021 api_want_ip4_arp_events (vat_main_t * vam)
12022 {
12023   unformat_input_t *line_input = vam->input;
12024   vl_api_want_ip4_arp_events_t *mp;
12025   ip4_address_t address;
12026   int address_set = 0;
12027   u32 enable_disable = 1;
12028   int ret;
12029
12030   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12031     {
12032       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
12033         address_set = 1;
12034       else if (unformat (line_input, "del"))
12035         enable_disable = 0;
12036       else
12037         break;
12038     }
12039
12040   if (address_set == 0)
12041     {
12042       errmsg ("missing addresses");
12043       return -99;
12044     }
12045
12046   M (WANT_IP4_ARP_EVENTS, mp);
12047   mp->enable_disable = enable_disable;
12048   mp->pid = htonl (getpid ());
12049   mp->address = address.as_u32;
12050
12051   S (mp);
12052   W (ret);
12053   return ret;
12054 }
12055
12056 static int
12057 api_want_ip6_nd_events (vat_main_t * vam)
12058 {
12059   unformat_input_t *line_input = vam->input;
12060   vl_api_want_ip6_nd_events_t *mp;
12061   ip6_address_t address;
12062   int address_set = 0;
12063   u32 enable_disable = 1;
12064   int ret;
12065
12066   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12067     {
12068       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
12069         address_set = 1;
12070       else if (unformat (line_input, "del"))
12071         enable_disable = 0;
12072       else
12073         break;
12074     }
12075
12076   if (address_set == 0)
12077     {
12078       errmsg ("missing addresses");
12079       return -99;
12080     }
12081
12082   M (WANT_IP6_ND_EVENTS, mp);
12083   mp->enable_disable = enable_disable;
12084   mp->pid = htonl (getpid ());
12085   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
12086
12087   S (mp);
12088   W (ret);
12089   return ret;
12090 }
12091
12092 static int
12093 api_input_acl_set_interface (vat_main_t * vam)
12094 {
12095   unformat_input_t *i = vam->input;
12096   vl_api_input_acl_set_interface_t *mp;
12097   u32 sw_if_index;
12098   int sw_if_index_set;
12099   u32 ip4_table_index = ~0;
12100   u32 ip6_table_index = ~0;
12101   u32 l2_table_index = ~0;
12102   u8 is_add = 1;
12103   int ret;
12104
12105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12106     {
12107       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12108         sw_if_index_set = 1;
12109       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12110         sw_if_index_set = 1;
12111       else if (unformat (i, "del"))
12112         is_add = 0;
12113       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12114         ;
12115       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12116         ;
12117       else if (unformat (i, "l2-table %d", &l2_table_index))
12118         ;
12119       else
12120         {
12121           clib_warning ("parse error '%U'", format_unformat_error, i);
12122           return -99;
12123         }
12124     }
12125
12126   if (sw_if_index_set == 0)
12127     {
12128       errmsg ("missing interface name or sw_if_index");
12129       return -99;
12130     }
12131
12132   M (INPUT_ACL_SET_INTERFACE, mp);
12133
12134   mp->sw_if_index = ntohl (sw_if_index);
12135   mp->ip4_table_index = ntohl (ip4_table_index);
12136   mp->ip6_table_index = ntohl (ip6_table_index);
12137   mp->l2_table_index = ntohl (l2_table_index);
12138   mp->is_add = is_add;
12139
12140   S (mp);
12141   W (ret);
12142   return ret;
12143 }
12144
12145 static int
12146 api_ip_address_dump (vat_main_t * vam)
12147 {
12148   unformat_input_t *i = vam->input;
12149   vl_api_ip_address_dump_t *mp;
12150   vl_api_control_ping_t *mp_ping;
12151   u32 sw_if_index = ~0;
12152   u8 sw_if_index_set = 0;
12153   u8 ipv4_set = 0;
12154   u8 ipv6_set = 0;
12155   int ret;
12156
12157   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12158     {
12159       if (unformat (i, "sw_if_index %d", &sw_if_index))
12160         sw_if_index_set = 1;
12161       else
12162         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12163         sw_if_index_set = 1;
12164       else if (unformat (i, "ipv4"))
12165         ipv4_set = 1;
12166       else if (unformat (i, "ipv6"))
12167         ipv6_set = 1;
12168       else
12169         break;
12170     }
12171
12172   if (ipv4_set && ipv6_set)
12173     {
12174       errmsg ("ipv4 and ipv6 flags cannot be both set");
12175       return -99;
12176     }
12177
12178   if ((!ipv4_set) && (!ipv6_set))
12179     {
12180       errmsg ("no ipv4 nor ipv6 flag set");
12181       return -99;
12182     }
12183
12184   if (sw_if_index_set == 0)
12185     {
12186       errmsg ("missing interface name or sw_if_index");
12187       return -99;
12188     }
12189
12190   vam->current_sw_if_index = sw_if_index;
12191   vam->is_ipv6 = ipv6_set;
12192
12193   M (IP_ADDRESS_DUMP, mp);
12194   mp->sw_if_index = ntohl (sw_if_index);
12195   mp->is_ipv6 = ipv6_set;
12196   S (mp);
12197
12198   /* Use a control ping for synchronization */
12199   M (CONTROL_PING, mp_ping);
12200   S (mp_ping);
12201
12202   W (ret);
12203   return ret;
12204 }
12205
12206 static int
12207 api_ip_dump (vat_main_t * vam)
12208 {
12209   vl_api_ip_dump_t *mp;
12210   vl_api_control_ping_t *mp_ping;
12211   unformat_input_t *in = vam->input;
12212   int ipv4_set = 0;
12213   int ipv6_set = 0;
12214   int is_ipv6;
12215   int i;
12216   int ret;
12217
12218   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
12219     {
12220       if (unformat (in, "ipv4"))
12221         ipv4_set = 1;
12222       else if (unformat (in, "ipv6"))
12223         ipv6_set = 1;
12224       else
12225         break;
12226     }
12227
12228   if (ipv4_set && ipv6_set)
12229     {
12230       errmsg ("ipv4 and ipv6 flags cannot be both set");
12231       return -99;
12232     }
12233
12234   if ((!ipv4_set) && (!ipv6_set))
12235     {
12236       errmsg ("no ipv4 nor ipv6 flag set");
12237       return -99;
12238     }
12239
12240   is_ipv6 = ipv6_set;
12241   vam->is_ipv6 = is_ipv6;
12242
12243   /* free old data */
12244   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
12245     {
12246       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
12247     }
12248   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
12249
12250   M (IP_DUMP, mp);
12251   mp->is_ipv6 = ipv6_set;
12252   S (mp);
12253
12254   /* Use a control ping for synchronization */
12255   M (CONTROL_PING, mp_ping);
12256   S (mp_ping);
12257
12258   W (ret);
12259   return ret;
12260 }
12261
12262 static int
12263 api_ipsec_spd_add_del (vat_main_t * vam)
12264 {
12265   unformat_input_t *i = vam->input;
12266   vl_api_ipsec_spd_add_del_t *mp;
12267   u32 spd_id = ~0;
12268   u8 is_add = 1;
12269   int ret;
12270
12271   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12272     {
12273       if (unformat (i, "spd_id %d", &spd_id))
12274         ;
12275       else if (unformat (i, "del"))
12276         is_add = 0;
12277       else
12278         {
12279           clib_warning ("parse error '%U'", format_unformat_error, i);
12280           return -99;
12281         }
12282     }
12283   if (spd_id == ~0)
12284     {
12285       errmsg ("spd_id must be set");
12286       return -99;
12287     }
12288
12289   M (IPSEC_SPD_ADD_DEL, mp);
12290
12291   mp->spd_id = ntohl (spd_id);
12292   mp->is_add = is_add;
12293
12294   S (mp);
12295   W (ret);
12296   return ret;
12297 }
12298
12299 static int
12300 api_ipsec_interface_add_del_spd (vat_main_t * vam)
12301 {
12302   unformat_input_t *i = vam->input;
12303   vl_api_ipsec_interface_add_del_spd_t *mp;
12304   u32 sw_if_index;
12305   u8 sw_if_index_set = 0;
12306   u32 spd_id = (u32) ~ 0;
12307   u8 is_add = 1;
12308   int ret;
12309
12310   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12311     {
12312       if (unformat (i, "del"))
12313         is_add = 0;
12314       else if (unformat (i, "spd_id %d", &spd_id))
12315         ;
12316       else
12317         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12318         sw_if_index_set = 1;
12319       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12320         sw_if_index_set = 1;
12321       else
12322         {
12323           clib_warning ("parse error '%U'", format_unformat_error, i);
12324           return -99;
12325         }
12326
12327     }
12328
12329   if (spd_id == (u32) ~ 0)
12330     {
12331       errmsg ("spd_id must be set");
12332       return -99;
12333     }
12334
12335   if (sw_if_index_set == 0)
12336     {
12337       errmsg ("missing interface name or sw_if_index");
12338       return -99;
12339     }
12340
12341   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
12342
12343   mp->spd_id = ntohl (spd_id);
12344   mp->sw_if_index = ntohl (sw_if_index);
12345   mp->is_add = is_add;
12346
12347   S (mp);
12348   W (ret);
12349   return ret;
12350 }
12351
12352 static int
12353 api_ipsec_spd_add_del_entry (vat_main_t * vam)
12354 {
12355   unformat_input_t *i = vam->input;
12356   vl_api_ipsec_spd_add_del_entry_t *mp;
12357   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
12358   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
12359   i32 priority = 0;
12360   u32 rport_start = 0, rport_stop = (u32) ~ 0;
12361   u32 lport_start = 0, lport_stop = (u32) ~ 0;
12362   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
12363   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
12364   int ret;
12365
12366   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
12367   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
12368   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
12369   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
12370   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
12371   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
12372
12373   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12374     {
12375       if (unformat (i, "del"))
12376         is_add = 0;
12377       if (unformat (i, "outbound"))
12378         is_outbound = 1;
12379       if (unformat (i, "inbound"))
12380         is_outbound = 0;
12381       else if (unformat (i, "spd_id %d", &spd_id))
12382         ;
12383       else if (unformat (i, "sa_id %d", &sa_id))
12384         ;
12385       else if (unformat (i, "priority %d", &priority))
12386         ;
12387       else if (unformat (i, "protocol %d", &protocol))
12388         ;
12389       else if (unformat (i, "lport_start %d", &lport_start))
12390         ;
12391       else if (unformat (i, "lport_stop %d", &lport_stop))
12392         ;
12393       else if (unformat (i, "rport_start %d", &rport_start))
12394         ;
12395       else if (unformat (i, "rport_stop %d", &rport_stop))
12396         ;
12397       else
12398         if (unformat
12399             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
12400         {
12401           is_ipv6 = 0;
12402           is_ip_any = 0;
12403         }
12404       else
12405         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
12406         {
12407           is_ipv6 = 0;
12408           is_ip_any = 0;
12409         }
12410       else
12411         if (unformat
12412             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
12413         {
12414           is_ipv6 = 0;
12415           is_ip_any = 0;
12416         }
12417       else
12418         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
12419         {
12420           is_ipv6 = 0;
12421           is_ip_any = 0;
12422         }
12423       else
12424         if (unformat
12425             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
12426         {
12427           is_ipv6 = 1;
12428           is_ip_any = 0;
12429         }
12430       else
12431         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
12432         {
12433           is_ipv6 = 1;
12434           is_ip_any = 0;
12435         }
12436       else
12437         if (unformat
12438             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
12439         {
12440           is_ipv6 = 1;
12441           is_ip_any = 0;
12442         }
12443       else
12444         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
12445         {
12446           is_ipv6 = 1;
12447           is_ip_any = 0;
12448         }
12449       else
12450         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
12451         {
12452           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
12453             {
12454               clib_warning ("unsupported action: 'resolve'");
12455               return -99;
12456             }
12457         }
12458       else
12459         {
12460           clib_warning ("parse error '%U'", format_unformat_error, i);
12461           return -99;
12462         }
12463
12464     }
12465
12466   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
12467
12468   mp->spd_id = ntohl (spd_id);
12469   mp->priority = ntohl (priority);
12470   mp->is_outbound = is_outbound;
12471
12472   mp->is_ipv6 = is_ipv6;
12473   if (is_ipv6 || is_ip_any)
12474     {
12475       clib_memcpy (mp->remote_address_start, &raddr6_start,
12476                    sizeof (ip6_address_t));
12477       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
12478                    sizeof (ip6_address_t));
12479       clib_memcpy (mp->local_address_start, &laddr6_start,
12480                    sizeof (ip6_address_t));
12481       clib_memcpy (mp->local_address_stop, &laddr6_stop,
12482                    sizeof (ip6_address_t));
12483     }
12484   else
12485     {
12486       clib_memcpy (mp->remote_address_start, &raddr4_start,
12487                    sizeof (ip4_address_t));
12488       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
12489                    sizeof (ip4_address_t));
12490       clib_memcpy (mp->local_address_start, &laddr4_start,
12491                    sizeof (ip4_address_t));
12492       clib_memcpy (mp->local_address_stop, &laddr4_stop,
12493                    sizeof (ip4_address_t));
12494     }
12495   mp->protocol = (u8) protocol;
12496   mp->local_port_start = ntohs ((u16) lport_start);
12497   mp->local_port_stop = ntohs ((u16) lport_stop);
12498   mp->remote_port_start = ntohs ((u16) rport_start);
12499   mp->remote_port_stop = ntohs ((u16) rport_stop);
12500   mp->policy = (u8) policy;
12501   mp->sa_id = ntohl (sa_id);
12502   mp->is_add = is_add;
12503   mp->is_ip_any = is_ip_any;
12504   S (mp);
12505   W (ret);
12506   return ret;
12507 }
12508
12509 static int
12510 api_ipsec_sad_add_del_entry (vat_main_t * vam)
12511 {
12512   unformat_input_t *i = vam->input;
12513   vl_api_ipsec_sad_add_del_entry_t *mp;
12514   u32 sad_id = 0, spi = 0;
12515   u8 *ck = 0, *ik = 0;
12516   u8 is_add = 1;
12517
12518   u8 protocol = IPSEC_PROTOCOL_AH;
12519   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
12520   u32 crypto_alg = 0, integ_alg = 0;
12521   ip4_address_t tun_src4;
12522   ip4_address_t tun_dst4;
12523   ip6_address_t tun_src6;
12524   ip6_address_t tun_dst6;
12525   int ret;
12526
12527   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12528     {
12529       if (unformat (i, "del"))
12530         is_add = 0;
12531       else if (unformat (i, "sad_id %d", &sad_id))
12532         ;
12533       else if (unformat (i, "spi %d", &spi))
12534         ;
12535       else if (unformat (i, "esp"))
12536         protocol = IPSEC_PROTOCOL_ESP;
12537       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
12538         {
12539           is_tunnel = 1;
12540           is_tunnel_ipv6 = 0;
12541         }
12542       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
12543         {
12544           is_tunnel = 1;
12545           is_tunnel_ipv6 = 0;
12546         }
12547       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
12548         {
12549           is_tunnel = 1;
12550           is_tunnel_ipv6 = 1;
12551         }
12552       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
12553         {
12554           is_tunnel = 1;
12555           is_tunnel_ipv6 = 1;
12556         }
12557       else
12558         if (unformat
12559             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12560         {
12561           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12562               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12563             {
12564               clib_warning ("unsupported crypto-alg: '%U'",
12565                             format_ipsec_crypto_alg, crypto_alg);
12566               return -99;
12567             }
12568         }
12569       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12570         ;
12571       else
12572         if (unformat
12573             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12574         {
12575           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12576               integ_alg >= IPSEC_INTEG_N_ALG)
12577             {
12578               clib_warning ("unsupported integ-alg: '%U'",
12579                             format_ipsec_integ_alg, integ_alg);
12580               return -99;
12581             }
12582         }
12583       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12584         ;
12585       else
12586         {
12587           clib_warning ("parse error '%U'", format_unformat_error, i);
12588           return -99;
12589         }
12590
12591     }
12592
12593   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
12594
12595   mp->sad_id = ntohl (sad_id);
12596   mp->is_add = is_add;
12597   mp->protocol = protocol;
12598   mp->spi = ntohl (spi);
12599   mp->is_tunnel = is_tunnel;
12600   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12601   mp->crypto_algorithm = crypto_alg;
12602   mp->integrity_algorithm = integ_alg;
12603   mp->crypto_key_length = vec_len (ck);
12604   mp->integrity_key_length = vec_len (ik);
12605
12606   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12607     mp->crypto_key_length = sizeof (mp->crypto_key);
12608
12609   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12610     mp->integrity_key_length = sizeof (mp->integrity_key);
12611
12612   if (ck)
12613     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12614   if (ik)
12615     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12616
12617   if (is_tunnel)
12618     {
12619       if (is_tunnel_ipv6)
12620         {
12621           clib_memcpy (mp->tunnel_src_address, &tun_src6,
12622                        sizeof (ip6_address_t));
12623           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12624                        sizeof (ip6_address_t));
12625         }
12626       else
12627         {
12628           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12629                        sizeof (ip4_address_t));
12630           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12631                        sizeof (ip4_address_t));
12632         }
12633     }
12634
12635   S (mp);
12636   W (ret);
12637   return ret;
12638 }
12639
12640 static int
12641 api_ipsec_sa_set_key (vat_main_t * vam)
12642 {
12643   unformat_input_t *i = vam->input;
12644   vl_api_ipsec_sa_set_key_t *mp;
12645   u32 sa_id;
12646   u8 *ck = 0, *ik = 0;
12647   int ret;
12648
12649   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12650     {
12651       if (unformat (i, "sa_id %d", &sa_id))
12652         ;
12653       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12654         ;
12655       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12656         ;
12657       else
12658         {
12659           clib_warning ("parse error '%U'", format_unformat_error, i);
12660           return -99;
12661         }
12662     }
12663
12664   M (IPSEC_SA_SET_KEY, mp);
12665
12666   mp->sa_id = ntohl (sa_id);
12667   mp->crypto_key_length = vec_len (ck);
12668   mp->integrity_key_length = vec_len (ik);
12669
12670   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12671     mp->crypto_key_length = sizeof (mp->crypto_key);
12672
12673   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12674     mp->integrity_key_length = sizeof (mp->integrity_key);
12675
12676   if (ck)
12677     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12678   if (ik)
12679     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12680
12681   S (mp);
12682   W (ret);
12683   return ret;
12684 }
12685
12686 static int
12687 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
12688 {
12689   unformat_input_t *i = vam->input;
12690   vl_api_ipsec_tunnel_if_add_del_t *mp;
12691   u32 local_spi = 0, remote_spi = 0;
12692   u32 crypto_alg = 0, integ_alg = 0;
12693   u8 *lck = NULL, *rck = NULL;
12694   u8 *lik = NULL, *rik = NULL;
12695   ip4_address_t local_ip = { {0} };
12696   ip4_address_t remote_ip = { {0} };
12697   u8 is_add = 1;
12698   u8 esn = 0;
12699   u8 anti_replay = 0;
12700   int ret;
12701
12702   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12703     {
12704       if (unformat (i, "del"))
12705         is_add = 0;
12706       else if (unformat (i, "esn"))
12707         esn = 1;
12708       else if (unformat (i, "anti_replay"))
12709         anti_replay = 1;
12710       else if (unformat (i, "local_spi %d", &local_spi))
12711         ;
12712       else if (unformat (i, "remote_spi %d", &remote_spi))
12713         ;
12714       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
12715         ;
12716       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
12717         ;
12718       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
12719         ;
12720       else
12721         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
12722         ;
12723       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
12724         ;
12725       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
12726         ;
12727       else
12728         if (unformat
12729             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12730         {
12731           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12732               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12733             {
12734               errmsg ("unsupported crypto-alg: '%U'\n",
12735                       format_ipsec_crypto_alg, crypto_alg);
12736               return -99;
12737             }
12738         }
12739       else
12740         if (unformat
12741             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12742         {
12743           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12744               integ_alg >= IPSEC_INTEG_N_ALG)
12745             {
12746               errmsg ("unsupported integ-alg: '%U'\n",
12747                       format_ipsec_integ_alg, integ_alg);
12748               return -99;
12749             }
12750         }
12751       else
12752         {
12753           errmsg ("parse error '%U'\n", format_unformat_error, i);
12754           return -99;
12755         }
12756     }
12757
12758   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
12759
12760   mp->is_add = is_add;
12761   mp->esn = esn;
12762   mp->anti_replay = anti_replay;
12763
12764   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
12765   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
12766
12767   mp->local_spi = htonl (local_spi);
12768   mp->remote_spi = htonl (remote_spi);
12769   mp->crypto_alg = (u8) crypto_alg;
12770
12771   mp->local_crypto_key_len = 0;
12772   if (lck)
12773     {
12774       mp->local_crypto_key_len = vec_len (lck);
12775       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
12776         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
12777       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
12778     }
12779
12780   mp->remote_crypto_key_len = 0;
12781   if (rck)
12782     {
12783       mp->remote_crypto_key_len = vec_len (rck);
12784       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
12785         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
12786       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
12787     }
12788
12789   mp->integ_alg = (u8) integ_alg;
12790
12791   mp->local_integ_key_len = 0;
12792   if (lik)
12793     {
12794       mp->local_integ_key_len = vec_len (lik);
12795       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
12796         mp->local_integ_key_len = sizeof (mp->local_integ_key);
12797       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
12798     }
12799
12800   mp->remote_integ_key_len = 0;
12801   if (rik)
12802     {
12803       mp->remote_integ_key_len = vec_len (rik);
12804       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
12805         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
12806       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
12807     }
12808
12809   S (mp);
12810   W (ret);
12811   return ret;
12812 }
12813
12814 static int
12815 api_ikev2_profile_add_del (vat_main_t * vam)
12816 {
12817   unformat_input_t *i = vam->input;
12818   vl_api_ikev2_profile_add_del_t *mp;
12819   u8 is_add = 1;
12820   u8 *name = 0;
12821   int ret;
12822
12823   const char *valid_chars = "a-zA-Z0-9_";
12824
12825   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12826     {
12827       if (unformat (i, "del"))
12828         is_add = 0;
12829       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12830         vec_add1 (name, 0);
12831       else
12832         {
12833           errmsg ("parse error '%U'", format_unformat_error, i);
12834           return -99;
12835         }
12836     }
12837
12838   if (!vec_len (name))
12839     {
12840       errmsg ("profile name must be specified");
12841       return -99;
12842     }
12843
12844   if (vec_len (name) > 64)
12845     {
12846       errmsg ("profile name too long");
12847       return -99;
12848     }
12849
12850   M (IKEV2_PROFILE_ADD_DEL, mp);
12851
12852   clib_memcpy (mp->name, name, vec_len (name));
12853   mp->is_add = is_add;
12854   vec_free (name);
12855
12856   S (mp);
12857   W (ret);
12858   return ret;
12859 }
12860
12861 static int
12862 api_ikev2_profile_set_auth (vat_main_t * vam)
12863 {
12864   unformat_input_t *i = vam->input;
12865   vl_api_ikev2_profile_set_auth_t *mp;
12866   u8 *name = 0;
12867   u8 *data = 0;
12868   u32 auth_method = 0;
12869   u8 is_hex = 0;
12870   int ret;
12871
12872   const char *valid_chars = "a-zA-Z0-9_";
12873
12874   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12875     {
12876       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12877         vec_add1 (name, 0);
12878       else if (unformat (i, "auth_method %U",
12879                          unformat_ikev2_auth_method, &auth_method))
12880         ;
12881       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12882         is_hex = 1;
12883       else if (unformat (i, "auth_data %v", &data))
12884         ;
12885       else
12886         {
12887           errmsg ("parse error '%U'", format_unformat_error, i);
12888           return -99;
12889         }
12890     }
12891
12892   if (!vec_len (name))
12893     {
12894       errmsg ("profile name must be specified");
12895       return -99;
12896     }
12897
12898   if (vec_len (name) > 64)
12899     {
12900       errmsg ("profile name too long");
12901       return -99;
12902     }
12903
12904   if (!vec_len (data))
12905     {
12906       errmsg ("auth_data must be specified");
12907       return -99;
12908     }
12909
12910   if (!auth_method)
12911     {
12912       errmsg ("auth_method must be specified");
12913       return -99;
12914     }
12915
12916   M (IKEV2_PROFILE_SET_AUTH, mp);
12917
12918   mp->is_hex = is_hex;
12919   mp->auth_method = (u8) auth_method;
12920   mp->data_len = vec_len (data);
12921   clib_memcpy (mp->name, name, vec_len (name));
12922   clib_memcpy (mp->data, data, vec_len (data));
12923   vec_free (name);
12924   vec_free (data);
12925
12926   S (mp);
12927   W (ret);
12928   return ret;
12929 }
12930
12931 static int
12932 api_ikev2_profile_set_id (vat_main_t * vam)
12933 {
12934   unformat_input_t *i = vam->input;
12935   vl_api_ikev2_profile_set_id_t *mp;
12936   u8 *name = 0;
12937   u8 *data = 0;
12938   u8 is_local = 0;
12939   u32 id_type = 0;
12940   ip4_address_t ip4;
12941   int ret;
12942
12943   const char *valid_chars = "a-zA-Z0-9_";
12944
12945   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12946     {
12947       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12948         vec_add1 (name, 0);
12949       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12950         ;
12951       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12952         {
12953           data = vec_new (u8, 4);
12954           clib_memcpy (data, ip4.as_u8, 4);
12955         }
12956       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12957         ;
12958       else if (unformat (i, "id_data %v", &data))
12959         ;
12960       else if (unformat (i, "local"))
12961         is_local = 1;
12962       else if (unformat (i, "remote"))
12963         is_local = 0;
12964       else
12965         {
12966           errmsg ("parse error '%U'", format_unformat_error, i);
12967           return -99;
12968         }
12969     }
12970
12971   if (!vec_len (name))
12972     {
12973       errmsg ("profile name must be specified");
12974       return -99;
12975     }
12976
12977   if (vec_len (name) > 64)
12978     {
12979       errmsg ("profile name too long");
12980       return -99;
12981     }
12982
12983   if (!vec_len (data))
12984     {
12985       errmsg ("id_data must be specified");
12986       return -99;
12987     }
12988
12989   if (!id_type)
12990     {
12991       errmsg ("id_type must be specified");
12992       return -99;
12993     }
12994
12995   M (IKEV2_PROFILE_SET_ID, mp);
12996
12997   mp->is_local = is_local;
12998   mp->id_type = (u8) id_type;
12999   mp->data_len = vec_len (data);
13000   clib_memcpy (mp->name, name, vec_len (name));
13001   clib_memcpy (mp->data, data, vec_len (data));
13002   vec_free (name);
13003   vec_free (data);
13004
13005   S (mp);
13006   W (ret);
13007   return ret;
13008 }
13009
13010 static int
13011 api_ikev2_profile_set_ts (vat_main_t * vam)
13012 {
13013   unformat_input_t *i = vam->input;
13014   vl_api_ikev2_profile_set_ts_t *mp;
13015   u8 *name = 0;
13016   u8 is_local = 0;
13017   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
13018   ip4_address_t start_addr, end_addr;
13019
13020   const char *valid_chars = "a-zA-Z0-9_";
13021   int ret;
13022
13023   start_addr.as_u32 = 0;
13024   end_addr.as_u32 = (u32) ~ 0;
13025
13026   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13027     {
13028       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13029         vec_add1 (name, 0);
13030       else if (unformat (i, "protocol %d", &proto))
13031         ;
13032       else if (unformat (i, "start_port %d", &start_port))
13033         ;
13034       else if (unformat (i, "end_port %d", &end_port))
13035         ;
13036       else
13037         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
13038         ;
13039       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
13040         ;
13041       else if (unformat (i, "local"))
13042         is_local = 1;
13043       else if (unformat (i, "remote"))
13044         is_local = 0;
13045       else
13046         {
13047           errmsg ("parse error '%U'", format_unformat_error, i);
13048           return -99;
13049         }
13050     }
13051
13052   if (!vec_len (name))
13053     {
13054       errmsg ("profile name must be specified");
13055       return -99;
13056     }
13057
13058   if (vec_len (name) > 64)
13059     {
13060       errmsg ("profile name too long");
13061       return -99;
13062     }
13063
13064   M (IKEV2_PROFILE_SET_TS, mp);
13065
13066   mp->is_local = is_local;
13067   mp->proto = (u8) proto;
13068   mp->start_port = (u16) start_port;
13069   mp->end_port = (u16) end_port;
13070   mp->start_addr = start_addr.as_u32;
13071   mp->end_addr = end_addr.as_u32;
13072   clib_memcpy (mp->name, name, vec_len (name));
13073   vec_free (name);
13074
13075   S (mp);
13076   W (ret);
13077   return ret;
13078 }
13079
13080 static int
13081 api_ikev2_set_local_key (vat_main_t * vam)
13082 {
13083   unformat_input_t *i = vam->input;
13084   vl_api_ikev2_set_local_key_t *mp;
13085   u8 *file = 0;
13086   int ret;
13087
13088   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13089     {
13090       if (unformat (i, "file %v", &file))
13091         vec_add1 (file, 0);
13092       else
13093         {
13094           errmsg ("parse error '%U'", format_unformat_error, i);
13095           return -99;
13096         }
13097     }
13098
13099   if (!vec_len (file))
13100     {
13101       errmsg ("RSA key file must be specified");
13102       return -99;
13103     }
13104
13105   if (vec_len (file) > 256)
13106     {
13107       errmsg ("file name too long");
13108       return -99;
13109     }
13110
13111   M (IKEV2_SET_LOCAL_KEY, mp);
13112
13113   clib_memcpy (mp->key_file, file, vec_len (file));
13114   vec_free (file);
13115
13116   S (mp);
13117   W (ret);
13118   return ret;
13119 }
13120
13121 static int
13122 api_ikev2_set_responder (vat_main_t * vam)
13123 {
13124   unformat_input_t *i = vam->input;
13125   vl_api_ikev2_set_responder_t *mp;
13126   int ret;
13127   u8 *name = 0;
13128   u32 sw_if_index = ~0;
13129   ip4_address_t address;
13130
13131   const char *valid_chars = "a-zA-Z0-9_";
13132
13133   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13134     {
13135       if (unformat
13136           (i, "%U interface %d address %U", unformat_token, valid_chars,
13137            &name, &sw_if_index, unformat_ip4_address, &address))
13138         vec_add1 (name, 0);
13139       else
13140         {
13141           errmsg ("parse error '%U'", format_unformat_error, i);
13142           return -99;
13143         }
13144     }
13145
13146   if (!vec_len (name))
13147     {
13148       errmsg ("profile name must be specified");
13149       return -99;
13150     }
13151
13152   if (vec_len (name) > 64)
13153     {
13154       errmsg ("profile name too long");
13155       return -99;
13156     }
13157
13158   M (IKEV2_SET_RESPONDER, mp);
13159
13160   clib_memcpy (mp->name, name, vec_len (name));
13161   vec_free (name);
13162
13163   mp->sw_if_index = sw_if_index;
13164   clib_memcpy (mp->address, &address, sizeof (address));
13165
13166   S (mp);
13167   W (ret);
13168   return ret;
13169 }
13170
13171 static int
13172 api_ikev2_set_ike_transforms (vat_main_t * vam)
13173 {
13174   unformat_input_t *i = vam->input;
13175   vl_api_ikev2_set_ike_transforms_t *mp;
13176   int ret;
13177   u8 *name = 0;
13178   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13179
13180   const char *valid_chars = "a-zA-Z0-9_";
13181
13182   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13183     {
13184       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13185                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13186         vec_add1 (name, 0);
13187       else
13188         {
13189           errmsg ("parse error '%U'", format_unformat_error, i);
13190           return -99;
13191         }
13192     }
13193
13194   if (!vec_len (name))
13195     {
13196       errmsg ("profile name must be specified");
13197       return -99;
13198     }
13199
13200   if (vec_len (name) > 64)
13201     {
13202       errmsg ("profile name too long");
13203       return -99;
13204     }
13205
13206   M (IKEV2_SET_IKE_TRANSFORMS, mp);
13207
13208   clib_memcpy (mp->name, name, vec_len (name));
13209   vec_free (name);
13210   mp->crypto_alg = crypto_alg;
13211   mp->crypto_key_size = crypto_key_size;
13212   mp->integ_alg = integ_alg;
13213   mp->dh_group = dh_group;
13214
13215   S (mp);
13216   W (ret);
13217   return ret;
13218 }
13219
13220
13221 static int
13222 api_ikev2_set_esp_transforms (vat_main_t * vam)
13223 {
13224   unformat_input_t *i = vam->input;
13225   vl_api_ikev2_set_esp_transforms_t *mp;
13226   int ret;
13227   u8 *name = 0;
13228   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13229
13230   const char *valid_chars = "a-zA-Z0-9_";
13231
13232   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13233     {
13234       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13235                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13236         vec_add1 (name, 0);
13237       else
13238         {
13239           errmsg ("parse error '%U'", format_unformat_error, i);
13240           return -99;
13241         }
13242     }
13243
13244   if (!vec_len (name))
13245     {
13246       errmsg ("profile name must be specified");
13247       return -99;
13248     }
13249
13250   if (vec_len (name) > 64)
13251     {
13252       errmsg ("profile name too long");
13253       return -99;
13254     }
13255
13256   M (IKEV2_SET_ESP_TRANSFORMS, mp);
13257
13258   clib_memcpy (mp->name, name, vec_len (name));
13259   vec_free (name);
13260   mp->crypto_alg = crypto_alg;
13261   mp->crypto_key_size = crypto_key_size;
13262   mp->integ_alg = integ_alg;
13263   mp->dh_group = dh_group;
13264
13265   S (mp);
13266   W (ret);
13267   return ret;
13268 }
13269
13270 static int
13271 api_ikev2_set_sa_lifetime (vat_main_t * vam)
13272 {
13273   unformat_input_t *i = vam->input;
13274   vl_api_ikev2_set_sa_lifetime_t *mp;
13275   int ret;
13276   u8 *name = 0;
13277   u64 lifetime, lifetime_maxdata;
13278   u32 lifetime_jitter, handover;
13279
13280   const char *valid_chars = "a-zA-Z0-9_";
13281
13282   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13283     {
13284       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
13285                     &lifetime, &lifetime_jitter, &handover,
13286                     &lifetime_maxdata))
13287         vec_add1 (name, 0);
13288       else
13289         {
13290           errmsg ("parse error '%U'", format_unformat_error, i);
13291           return -99;
13292         }
13293     }
13294
13295   if (!vec_len (name))
13296     {
13297       errmsg ("profile name must be specified");
13298       return -99;
13299     }
13300
13301   if (vec_len (name) > 64)
13302     {
13303       errmsg ("profile name too long");
13304       return -99;
13305     }
13306
13307   M (IKEV2_SET_SA_LIFETIME, mp);
13308
13309   clib_memcpy (mp->name, name, vec_len (name));
13310   vec_free (name);
13311   mp->lifetime = lifetime;
13312   mp->lifetime_jitter = lifetime_jitter;
13313   mp->handover = handover;
13314   mp->lifetime_maxdata = lifetime_maxdata;
13315
13316   S (mp);
13317   W (ret);
13318   return ret;
13319 }
13320
13321 static int
13322 api_ikev2_initiate_sa_init (vat_main_t * vam)
13323 {
13324   unformat_input_t *i = vam->input;
13325   vl_api_ikev2_initiate_sa_init_t *mp;
13326   int ret;
13327   u8 *name = 0;
13328
13329   const char *valid_chars = "a-zA-Z0-9_";
13330
13331   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13332     {
13333       if (unformat (i, "%U", unformat_token, valid_chars, &name))
13334         vec_add1 (name, 0);
13335       else
13336         {
13337           errmsg ("parse error '%U'", format_unformat_error, i);
13338           return -99;
13339         }
13340     }
13341
13342   if (!vec_len (name))
13343     {
13344       errmsg ("profile name must be specified");
13345       return -99;
13346     }
13347
13348   if (vec_len (name) > 64)
13349     {
13350       errmsg ("profile name too long");
13351       return -99;
13352     }
13353
13354   M (IKEV2_INITIATE_SA_INIT, mp);
13355
13356   clib_memcpy (mp->name, name, vec_len (name));
13357   vec_free (name);
13358
13359   S (mp);
13360   W (ret);
13361   return ret;
13362 }
13363
13364 static int
13365 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
13366 {
13367   unformat_input_t *i = vam->input;
13368   vl_api_ikev2_initiate_del_ike_sa_t *mp;
13369   int ret;
13370   u64 ispi;
13371
13372
13373   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13374     {
13375       if (unformat (i, "%lx", &ispi))
13376         ;
13377       else
13378         {
13379           errmsg ("parse error '%U'", format_unformat_error, i);
13380           return -99;
13381         }
13382     }
13383
13384   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
13385
13386   mp->ispi = ispi;
13387
13388   S (mp);
13389   W (ret);
13390   return ret;
13391 }
13392
13393 static int
13394 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
13395 {
13396   unformat_input_t *i = vam->input;
13397   vl_api_ikev2_initiate_del_child_sa_t *mp;
13398   int ret;
13399   u32 ispi;
13400
13401
13402   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13403     {
13404       if (unformat (i, "%x", &ispi))
13405         ;
13406       else
13407         {
13408           errmsg ("parse error '%U'", format_unformat_error, i);
13409           return -99;
13410         }
13411     }
13412
13413   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
13414
13415   mp->ispi = ispi;
13416
13417   S (mp);
13418   W (ret);
13419   return ret;
13420 }
13421
13422 static int
13423 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
13424 {
13425   unformat_input_t *i = vam->input;
13426   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
13427   int ret;
13428   u32 ispi;
13429
13430
13431   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13432     {
13433       if (unformat (i, "%x", &ispi))
13434         ;
13435       else
13436         {
13437           errmsg ("parse error '%U'", format_unformat_error, i);
13438           return -99;
13439         }
13440     }
13441
13442   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
13443
13444   mp->ispi = ispi;
13445
13446   S (mp);
13447   W (ret);
13448   return ret;
13449 }
13450
13451 /*
13452  * MAP
13453  */
13454 static int
13455 api_map_add_domain (vat_main_t * vam)
13456 {
13457   unformat_input_t *i = vam->input;
13458   vl_api_map_add_domain_t *mp;
13459
13460   ip4_address_t ip4_prefix;
13461   ip6_address_t ip6_prefix;
13462   ip6_address_t ip6_src;
13463   u32 num_m_args = 0;
13464   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
13465     0, psid_length = 0;
13466   u8 is_translation = 0;
13467   u32 mtu = 0;
13468   u32 ip6_src_len = 128;
13469   int ret;
13470
13471   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13472     {
13473       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
13474                     &ip4_prefix, &ip4_prefix_len))
13475         num_m_args++;
13476       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
13477                          &ip6_prefix, &ip6_prefix_len))
13478         num_m_args++;
13479       else
13480         if (unformat
13481             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
13482              &ip6_src_len))
13483         num_m_args++;
13484       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
13485         num_m_args++;
13486       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
13487         num_m_args++;
13488       else if (unformat (i, "psid-offset %d", &psid_offset))
13489         num_m_args++;
13490       else if (unformat (i, "psid-len %d", &psid_length))
13491         num_m_args++;
13492       else if (unformat (i, "mtu %d", &mtu))
13493         num_m_args++;
13494       else if (unformat (i, "map-t"))
13495         is_translation = 1;
13496       else
13497         {
13498           clib_warning ("parse error '%U'", format_unformat_error, i);
13499           return -99;
13500         }
13501     }
13502
13503   if (num_m_args < 3)
13504     {
13505       errmsg ("mandatory argument(s) missing");
13506       return -99;
13507     }
13508
13509   /* Construct the API message */
13510   M (MAP_ADD_DOMAIN, mp);
13511
13512   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
13513   mp->ip4_prefix_len = ip4_prefix_len;
13514
13515   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
13516   mp->ip6_prefix_len = ip6_prefix_len;
13517
13518   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
13519   mp->ip6_src_prefix_len = ip6_src_len;
13520
13521   mp->ea_bits_len = ea_bits_len;
13522   mp->psid_offset = psid_offset;
13523   mp->psid_length = psid_length;
13524   mp->is_translation = is_translation;
13525   mp->mtu = htons (mtu);
13526
13527   /* send it... */
13528   S (mp);
13529
13530   /* Wait for a reply, return good/bad news  */
13531   W (ret);
13532   return ret;
13533 }
13534
13535 static int
13536 api_map_del_domain (vat_main_t * vam)
13537 {
13538   unformat_input_t *i = vam->input;
13539   vl_api_map_del_domain_t *mp;
13540
13541   u32 num_m_args = 0;
13542   u32 index;
13543   int ret;
13544
13545   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13546     {
13547       if (unformat (i, "index %d", &index))
13548         num_m_args++;
13549       else
13550         {
13551           clib_warning ("parse error '%U'", format_unformat_error, i);
13552           return -99;
13553         }
13554     }
13555
13556   if (num_m_args != 1)
13557     {
13558       errmsg ("mandatory argument(s) missing");
13559       return -99;
13560     }
13561
13562   /* Construct the API message */
13563   M (MAP_DEL_DOMAIN, mp);
13564
13565   mp->index = ntohl (index);
13566
13567   /* send it... */
13568   S (mp);
13569
13570   /* Wait for a reply, return good/bad news  */
13571   W (ret);
13572   return ret;
13573 }
13574
13575 static int
13576 api_map_add_del_rule (vat_main_t * vam)
13577 {
13578   unformat_input_t *i = vam->input;
13579   vl_api_map_add_del_rule_t *mp;
13580   u8 is_add = 1;
13581   ip6_address_t ip6_dst;
13582   u32 num_m_args = 0, index, psid = 0;
13583   int ret;
13584
13585   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13586     {
13587       if (unformat (i, "index %d", &index))
13588         num_m_args++;
13589       else if (unformat (i, "psid %d", &psid))
13590         num_m_args++;
13591       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
13592         num_m_args++;
13593       else if (unformat (i, "del"))
13594         {
13595           is_add = 0;
13596         }
13597       else
13598         {
13599           clib_warning ("parse error '%U'", format_unformat_error, i);
13600           return -99;
13601         }
13602     }
13603
13604   /* Construct the API message */
13605   M (MAP_ADD_DEL_RULE, mp);
13606
13607   mp->index = ntohl (index);
13608   mp->is_add = is_add;
13609   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
13610   mp->psid = ntohs (psid);
13611
13612   /* send it... */
13613   S (mp);
13614
13615   /* Wait for a reply, return good/bad news  */
13616   W (ret);
13617   return ret;
13618 }
13619
13620 static int
13621 api_map_domain_dump (vat_main_t * vam)
13622 {
13623   vl_api_map_domain_dump_t *mp;
13624   vl_api_control_ping_t *mp_ping;
13625   int ret;
13626
13627   /* Construct the API message */
13628   M (MAP_DOMAIN_DUMP, mp);
13629
13630   /* send it... */
13631   S (mp);
13632
13633   /* Use a control ping for synchronization */
13634   M (CONTROL_PING, mp_ping);
13635   S (mp_ping);
13636
13637   W (ret);
13638   return ret;
13639 }
13640
13641 static int
13642 api_map_rule_dump (vat_main_t * vam)
13643 {
13644   unformat_input_t *i = vam->input;
13645   vl_api_map_rule_dump_t *mp;
13646   vl_api_control_ping_t *mp_ping;
13647   u32 domain_index = ~0;
13648   int ret;
13649
13650   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13651     {
13652       if (unformat (i, "index %u", &domain_index))
13653         ;
13654       else
13655         break;
13656     }
13657
13658   if (domain_index == ~0)
13659     {
13660       clib_warning ("parse error: domain index expected");
13661       return -99;
13662     }
13663
13664   /* Construct the API message */
13665   M (MAP_RULE_DUMP, mp);
13666
13667   mp->domain_index = htonl (domain_index);
13668
13669   /* send it... */
13670   S (mp);
13671
13672   /* Use a control ping for synchronization */
13673   M (CONTROL_PING, mp_ping);
13674   S (mp_ping);
13675
13676   W (ret);
13677   return ret;
13678 }
13679
13680 static void vl_api_map_add_domain_reply_t_handler
13681   (vl_api_map_add_domain_reply_t * mp)
13682 {
13683   vat_main_t *vam = &vat_main;
13684   i32 retval = ntohl (mp->retval);
13685
13686   if (vam->async_mode)
13687     {
13688       vam->async_errors += (retval < 0);
13689     }
13690   else
13691     {
13692       vam->retval = retval;
13693       vam->result_ready = 1;
13694     }
13695 }
13696
13697 static void vl_api_map_add_domain_reply_t_handler_json
13698   (vl_api_map_add_domain_reply_t * mp)
13699 {
13700   vat_main_t *vam = &vat_main;
13701   vat_json_node_t node;
13702
13703   vat_json_init_object (&node);
13704   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
13705   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
13706
13707   vat_json_print (vam->ofp, &node);
13708   vat_json_free (&node);
13709
13710   vam->retval = ntohl (mp->retval);
13711   vam->result_ready = 1;
13712 }
13713
13714 static int
13715 api_get_first_msg_id (vat_main_t * vam)
13716 {
13717   vl_api_get_first_msg_id_t *mp;
13718   unformat_input_t *i = vam->input;
13719   u8 *name;
13720   u8 name_set = 0;
13721   int ret;
13722
13723   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13724     {
13725       if (unformat (i, "client %s", &name))
13726         name_set = 1;
13727       else
13728         break;
13729     }
13730
13731   if (name_set == 0)
13732     {
13733       errmsg ("missing client name");
13734       return -99;
13735     }
13736   vec_add1 (name, 0);
13737
13738   if (vec_len (name) > 63)
13739     {
13740       errmsg ("client name too long");
13741       return -99;
13742     }
13743
13744   M (GET_FIRST_MSG_ID, mp);
13745   clib_memcpy (mp->name, name, vec_len (name));
13746   S (mp);
13747   W (ret);
13748   return ret;
13749 }
13750
13751 static int
13752 api_cop_interface_enable_disable (vat_main_t * vam)
13753 {
13754   unformat_input_t *line_input = vam->input;
13755   vl_api_cop_interface_enable_disable_t *mp;
13756   u32 sw_if_index = ~0;
13757   u8 enable_disable = 1;
13758   int ret;
13759
13760   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13761     {
13762       if (unformat (line_input, "disable"))
13763         enable_disable = 0;
13764       if (unformat (line_input, "enable"))
13765         enable_disable = 1;
13766       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13767                          vam, &sw_if_index))
13768         ;
13769       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13770         ;
13771       else
13772         break;
13773     }
13774
13775   if (sw_if_index == ~0)
13776     {
13777       errmsg ("missing interface name or sw_if_index");
13778       return -99;
13779     }
13780
13781   /* Construct the API message */
13782   M (COP_INTERFACE_ENABLE_DISABLE, mp);
13783   mp->sw_if_index = ntohl (sw_if_index);
13784   mp->enable_disable = enable_disable;
13785
13786   /* send it... */
13787   S (mp);
13788   /* Wait for the reply */
13789   W (ret);
13790   return ret;
13791 }
13792
13793 static int
13794 api_cop_whitelist_enable_disable (vat_main_t * vam)
13795 {
13796   unformat_input_t *line_input = vam->input;
13797   vl_api_cop_whitelist_enable_disable_t *mp;
13798   u32 sw_if_index = ~0;
13799   u8 ip4 = 0, ip6 = 0, default_cop = 0;
13800   u32 fib_id = 0;
13801   int ret;
13802
13803   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13804     {
13805       if (unformat (line_input, "ip4"))
13806         ip4 = 1;
13807       else if (unformat (line_input, "ip6"))
13808         ip6 = 1;
13809       else if (unformat (line_input, "default"))
13810         default_cop = 1;
13811       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13812                          vam, &sw_if_index))
13813         ;
13814       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13815         ;
13816       else if (unformat (line_input, "fib-id %d", &fib_id))
13817         ;
13818       else
13819         break;
13820     }
13821
13822   if (sw_if_index == ~0)
13823     {
13824       errmsg ("missing interface name or sw_if_index");
13825       return -99;
13826     }
13827
13828   /* Construct the API message */
13829   M (COP_WHITELIST_ENABLE_DISABLE, mp);
13830   mp->sw_if_index = ntohl (sw_if_index);
13831   mp->fib_id = ntohl (fib_id);
13832   mp->ip4 = ip4;
13833   mp->ip6 = ip6;
13834   mp->default_cop = default_cop;
13835
13836   /* send it... */
13837   S (mp);
13838   /* Wait for the reply */
13839   W (ret);
13840   return ret;
13841 }
13842
13843 static int
13844 api_get_node_graph (vat_main_t * vam)
13845 {
13846   vl_api_get_node_graph_t *mp;
13847   int ret;
13848
13849   M (GET_NODE_GRAPH, mp);
13850
13851   /* send it... */
13852   S (mp);
13853   /* Wait for the reply */
13854   W (ret);
13855   return ret;
13856 }
13857
13858 /* *INDENT-OFF* */
13859 /** Used for parsing LISP eids */
13860 typedef CLIB_PACKED(struct{
13861   u8 addr[16];   /**< eid address */
13862   u32 len;       /**< prefix length if IP */
13863   u8 type;      /**< type of eid */
13864 }) lisp_eid_vat_t;
13865 /* *INDENT-ON* */
13866
13867 static uword
13868 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
13869 {
13870   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
13871
13872   memset (a, 0, sizeof (a[0]));
13873
13874   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
13875     {
13876       a->type = 0;              /* ipv4 type */
13877     }
13878   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
13879     {
13880       a->type = 1;              /* ipv6 type */
13881     }
13882   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
13883     {
13884       a->type = 2;              /* mac type */
13885     }
13886   else
13887     {
13888       return 0;
13889     }
13890
13891   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
13892     {
13893       return 0;
13894     }
13895
13896   return 1;
13897 }
13898
13899 static int
13900 lisp_eid_size_vat (u8 type)
13901 {
13902   switch (type)
13903     {
13904     case 0:
13905       return 4;
13906     case 1:
13907       return 16;
13908     case 2:
13909       return 6;
13910     }
13911   return 0;
13912 }
13913
13914 static void
13915 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
13916 {
13917   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
13918 }
13919
13920 static int
13921 api_one_add_del_locator_set (vat_main_t * vam)
13922 {
13923   unformat_input_t *input = vam->input;
13924   vl_api_one_add_del_locator_set_t *mp;
13925   u8 is_add = 1;
13926   u8 *locator_set_name = NULL;
13927   u8 locator_set_name_set = 0;
13928   vl_api_local_locator_t locator, *locators = 0;
13929   u32 sw_if_index, priority, weight;
13930   u32 data_len = 0;
13931
13932   int ret;
13933   /* Parse args required to build the message */
13934   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13935     {
13936       if (unformat (input, "del"))
13937         {
13938           is_add = 0;
13939         }
13940       else if (unformat (input, "locator-set %s", &locator_set_name))
13941         {
13942           locator_set_name_set = 1;
13943         }
13944       else if (unformat (input, "sw_if_index %u p %u w %u",
13945                          &sw_if_index, &priority, &weight))
13946         {
13947           locator.sw_if_index = htonl (sw_if_index);
13948           locator.priority = priority;
13949           locator.weight = weight;
13950           vec_add1 (locators, locator);
13951         }
13952       else
13953         if (unformat
13954             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
13955              &sw_if_index, &priority, &weight))
13956         {
13957           locator.sw_if_index = htonl (sw_if_index);
13958           locator.priority = priority;
13959           locator.weight = weight;
13960           vec_add1 (locators, locator);
13961         }
13962       else
13963         break;
13964     }
13965
13966   if (locator_set_name_set == 0)
13967     {
13968       errmsg ("missing locator-set name");
13969       vec_free (locators);
13970       return -99;
13971     }
13972
13973   if (vec_len (locator_set_name) > 64)
13974     {
13975       errmsg ("locator-set name too long");
13976       vec_free (locator_set_name);
13977       vec_free (locators);
13978       return -99;
13979     }
13980   vec_add1 (locator_set_name, 0);
13981
13982   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
13983
13984   /* Construct the API message */
13985   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
13986
13987   mp->is_add = is_add;
13988   clib_memcpy (mp->locator_set_name, locator_set_name,
13989                vec_len (locator_set_name));
13990   vec_free (locator_set_name);
13991
13992   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
13993   if (locators)
13994     clib_memcpy (mp->locators, locators, data_len);
13995   vec_free (locators);
13996
13997   /* send it... */
13998   S (mp);
13999
14000   /* Wait for a reply... */
14001   W (ret);
14002   return ret;
14003 }
14004
14005 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14006
14007 static int
14008 api_one_add_del_locator (vat_main_t * vam)
14009 {
14010   unformat_input_t *input = vam->input;
14011   vl_api_one_add_del_locator_t *mp;
14012   u32 tmp_if_index = ~0;
14013   u32 sw_if_index = ~0;
14014   u8 sw_if_index_set = 0;
14015   u8 sw_if_index_if_name_set = 0;
14016   u32 priority = ~0;
14017   u8 priority_set = 0;
14018   u32 weight = ~0;
14019   u8 weight_set = 0;
14020   u8 is_add = 1;
14021   u8 *locator_set_name = NULL;
14022   u8 locator_set_name_set = 0;
14023   int ret;
14024
14025   /* Parse args required to build the message */
14026   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14027     {
14028       if (unformat (input, "del"))
14029         {
14030           is_add = 0;
14031         }
14032       else if (unformat (input, "locator-set %s", &locator_set_name))
14033         {
14034           locator_set_name_set = 1;
14035         }
14036       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14037                          &tmp_if_index))
14038         {
14039           sw_if_index_if_name_set = 1;
14040           sw_if_index = tmp_if_index;
14041         }
14042       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14043         {
14044           sw_if_index_set = 1;
14045           sw_if_index = tmp_if_index;
14046         }
14047       else if (unformat (input, "p %d", &priority))
14048         {
14049           priority_set = 1;
14050         }
14051       else if (unformat (input, "w %d", &weight))
14052         {
14053           weight_set = 1;
14054         }
14055       else
14056         break;
14057     }
14058
14059   if (locator_set_name_set == 0)
14060     {
14061       errmsg ("missing locator-set name");
14062       return -99;
14063     }
14064
14065   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14066     {
14067       errmsg ("missing sw_if_index");
14068       vec_free (locator_set_name);
14069       return -99;
14070     }
14071
14072   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14073     {
14074       errmsg ("cannot use both params interface name and sw_if_index");
14075       vec_free (locator_set_name);
14076       return -99;
14077     }
14078
14079   if (priority_set == 0)
14080     {
14081       errmsg ("missing locator-set priority");
14082       vec_free (locator_set_name);
14083       return -99;
14084     }
14085
14086   if (weight_set == 0)
14087     {
14088       errmsg ("missing locator-set weight");
14089       vec_free (locator_set_name);
14090       return -99;
14091     }
14092
14093   if (vec_len (locator_set_name) > 64)
14094     {
14095       errmsg ("locator-set name too long");
14096       vec_free (locator_set_name);
14097       return -99;
14098     }
14099   vec_add1 (locator_set_name, 0);
14100
14101   /* Construct the API message */
14102   M (ONE_ADD_DEL_LOCATOR, mp);
14103
14104   mp->is_add = is_add;
14105   mp->sw_if_index = ntohl (sw_if_index);
14106   mp->priority = priority;
14107   mp->weight = weight;
14108   clib_memcpy (mp->locator_set_name, locator_set_name,
14109                vec_len (locator_set_name));
14110   vec_free (locator_set_name);
14111
14112   /* send it... */
14113   S (mp);
14114
14115   /* Wait for a reply... */
14116   W (ret);
14117   return ret;
14118 }
14119
14120 #define api_lisp_add_del_locator api_one_add_del_locator
14121
14122 uword
14123 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14124 {
14125   u32 *key_id = va_arg (*args, u32 *);
14126   u8 *s = 0;
14127
14128   if (unformat (input, "%s", &s))
14129     {
14130       if (!strcmp ((char *) s, "sha1"))
14131         key_id[0] = HMAC_SHA_1_96;
14132       else if (!strcmp ((char *) s, "sha256"))
14133         key_id[0] = HMAC_SHA_256_128;
14134       else
14135         {
14136           clib_warning ("invalid key_id: '%s'", s);
14137           key_id[0] = HMAC_NO_KEY;
14138         }
14139     }
14140   else
14141     return 0;
14142
14143   vec_free (s);
14144   return 1;
14145 }
14146
14147 static int
14148 api_one_add_del_local_eid (vat_main_t * vam)
14149 {
14150   unformat_input_t *input = vam->input;
14151   vl_api_one_add_del_local_eid_t *mp;
14152   u8 is_add = 1;
14153   u8 eid_set = 0;
14154   lisp_eid_vat_t _eid, *eid = &_eid;
14155   u8 *locator_set_name = 0;
14156   u8 locator_set_name_set = 0;
14157   u32 vni = 0;
14158   u16 key_id = 0;
14159   u8 *key = 0;
14160   int ret;
14161
14162   /* Parse args required to build the message */
14163   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14164     {
14165       if (unformat (input, "del"))
14166         {
14167           is_add = 0;
14168         }
14169       else if (unformat (input, "vni %d", &vni))
14170         {
14171           ;
14172         }
14173       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14174         {
14175           eid_set = 1;
14176         }
14177       else if (unformat (input, "locator-set %s", &locator_set_name))
14178         {
14179           locator_set_name_set = 1;
14180         }
14181       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14182         ;
14183       else if (unformat (input, "secret-key %_%v%_", &key))
14184         ;
14185       else
14186         break;
14187     }
14188
14189   if (locator_set_name_set == 0)
14190     {
14191       errmsg ("missing locator-set name");
14192       return -99;
14193     }
14194
14195   if (0 == eid_set)
14196     {
14197       errmsg ("EID address not set!");
14198       vec_free (locator_set_name);
14199       return -99;
14200     }
14201
14202   if (key && (0 == key_id))
14203     {
14204       errmsg ("invalid key_id!");
14205       return -99;
14206     }
14207
14208   if (vec_len (key) > 64)
14209     {
14210       errmsg ("key too long");
14211       vec_free (key);
14212       return -99;
14213     }
14214
14215   if (vec_len (locator_set_name) > 64)
14216     {
14217       errmsg ("locator-set name too long");
14218       vec_free (locator_set_name);
14219       return -99;
14220     }
14221   vec_add1 (locator_set_name, 0);
14222
14223   /* Construct the API message */
14224   M (ONE_ADD_DEL_LOCAL_EID, mp);
14225
14226   mp->is_add = is_add;
14227   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14228   mp->eid_type = eid->type;
14229   mp->prefix_len = eid->len;
14230   mp->vni = clib_host_to_net_u32 (vni);
14231   mp->key_id = clib_host_to_net_u16 (key_id);
14232   clib_memcpy (mp->locator_set_name, locator_set_name,
14233                vec_len (locator_set_name));
14234   clib_memcpy (mp->key, key, vec_len (key));
14235
14236   vec_free (locator_set_name);
14237   vec_free (key);
14238
14239   /* send it... */
14240   S (mp);
14241
14242   /* Wait for a reply... */
14243   W (ret);
14244   return ret;
14245 }
14246
14247 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14248
14249 static int
14250 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14251 {
14252   u32 dp_table = 0, vni = 0;;
14253   unformat_input_t *input = vam->input;
14254   vl_api_gpe_add_del_fwd_entry_t *mp;
14255   u8 is_add = 1;
14256   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14257   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14258   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14259   u32 action = ~0, w;
14260   ip4_address_t rmt_rloc4, lcl_rloc4;
14261   ip6_address_t rmt_rloc6, lcl_rloc6;
14262   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14263   int ret;
14264
14265   memset (&rloc, 0, sizeof (rloc));
14266
14267   /* Parse args required to build the message */
14268   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14269     {
14270       if (unformat (input, "del"))
14271         is_add = 0;
14272       else if (unformat (input, "add"))
14273         is_add = 1;
14274       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14275         {
14276           rmt_eid_set = 1;
14277         }
14278       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14279         {
14280           lcl_eid_set = 1;
14281         }
14282       else if (unformat (input, "vrf %d", &dp_table))
14283         ;
14284       else if (unformat (input, "bd %d", &dp_table))
14285         ;
14286       else if (unformat (input, "vni %d", &vni))
14287         ;
14288       else if (unformat (input, "w %d", &w))
14289         {
14290           if (!curr_rloc)
14291             {
14292               errmsg ("No RLOC configured for setting priority/weight!");
14293               return -99;
14294             }
14295           curr_rloc->weight = w;
14296         }
14297       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14298                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14299         {
14300           rloc.is_ip4 = 1;
14301
14302           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
14303           rloc.weight = 0;
14304           vec_add1 (lcl_locs, rloc);
14305
14306           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
14307           vec_add1 (rmt_locs, rloc);
14308           /* weight saved in rmt loc */
14309           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14310         }
14311       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14312                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14313         {
14314           rloc.is_ip4 = 0;
14315           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
14316           rloc.weight = 0;
14317           vec_add1 (lcl_locs, rloc);
14318
14319           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
14320           vec_add1 (rmt_locs, rloc);
14321           /* weight saved in rmt loc */
14322           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14323         }
14324       else if (unformat (input, "action %d", &action))
14325         {
14326           ;
14327         }
14328       else
14329         {
14330           clib_warning ("parse error '%U'", format_unformat_error, input);
14331           return -99;
14332         }
14333     }
14334
14335   if (!rmt_eid_set)
14336     {
14337       errmsg ("remote eid addresses not set");
14338       return -99;
14339     }
14340
14341   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14342     {
14343       errmsg ("eid types don't match");
14344       return -99;
14345     }
14346
14347   if (0 == rmt_locs && (u32) ~ 0 == action)
14348     {
14349       errmsg ("action not set for negative mapping");
14350       return -99;
14351     }
14352
14353   /* Construct the API message */
14354   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14355       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14356
14357   mp->is_add = is_add;
14358   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
14359   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
14360   mp->eid_type = rmt_eid->type;
14361   mp->dp_table = clib_host_to_net_u32 (dp_table);
14362   mp->vni = clib_host_to_net_u32 (vni);
14363   mp->rmt_len = rmt_eid->len;
14364   mp->lcl_len = lcl_eid->len;
14365   mp->action = action;
14366
14367   if (0 != rmt_locs && 0 != lcl_locs)
14368     {
14369       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14370       clib_memcpy (mp->locs, lcl_locs,
14371                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14372
14373       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14374       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14375                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14376     }
14377   vec_free (lcl_locs);
14378   vec_free (rmt_locs);
14379
14380   /* send it... */
14381   S (mp);
14382
14383   /* Wait for a reply... */
14384   W (ret);
14385   return ret;
14386 }
14387
14388 static int
14389 api_one_add_del_map_server (vat_main_t * vam)
14390 {
14391   unformat_input_t *input = vam->input;
14392   vl_api_one_add_del_map_server_t *mp;
14393   u8 is_add = 1;
14394   u8 ipv4_set = 0;
14395   u8 ipv6_set = 0;
14396   ip4_address_t ipv4;
14397   ip6_address_t ipv6;
14398   int ret;
14399
14400   /* Parse args required to build the message */
14401   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14402     {
14403       if (unformat (input, "del"))
14404         {
14405           is_add = 0;
14406         }
14407       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14408         {
14409           ipv4_set = 1;
14410         }
14411       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14412         {
14413           ipv6_set = 1;
14414         }
14415       else
14416         break;
14417     }
14418
14419   if (ipv4_set && ipv6_set)
14420     {
14421       errmsg ("both eid v4 and v6 addresses set");
14422       return -99;
14423     }
14424
14425   if (!ipv4_set && !ipv6_set)
14426     {
14427       errmsg ("eid addresses not set");
14428       return -99;
14429     }
14430
14431   /* Construct the API message */
14432   M (ONE_ADD_DEL_MAP_SERVER, mp);
14433
14434   mp->is_add = is_add;
14435   if (ipv6_set)
14436     {
14437       mp->is_ipv6 = 1;
14438       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14439     }
14440   else
14441     {
14442       mp->is_ipv6 = 0;
14443       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14444     }
14445
14446   /* send it... */
14447   S (mp);
14448
14449   /* Wait for a reply... */
14450   W (ret);
14451   return ret;
14452 }
14453
14454 #define api_lisp_add_del_map_server api_one_add_del_map_server
14455
14456 static int
14457 api_one_add_del_map_resolver (vat_main_t * vam)
14458 {
14459   unformat_input_t *input = vam->input;
14460   vl_api_one_add_del_map_resolver_t *mp;
14461   u8 is_add = 1;
14462   u8 ipv4_set = 0;
14463   u8 ipv6_set = 0;
14464   ip4_address_t ipv4;
14465   ip6_address_t ipv6;
14466   int ret;
14467
14468   /* Parse args required to build the message */
14469   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14470     {
14471       if (unformat (input, "del"))
14472         {
14473           is_add = 0;
14474         }
14475       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14476         {
14477           ipv4_set = 1;
14478         }
14479       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14480         {
14481           ipv6_set = 1;
14482         }
14483       else
14484         break;
14485     }
14486
14487   if (ipv4_set && ipv6_set)
14488     {
14489       errmsg ("both eid v4 and v6 addresses set");
14490       return -99;
14491     }
14492
14493   if (!ipv4_set && !ipv6_set)
14494     {
14495       errmsg ("eid addresses not set");
14496       return -99;
14497     }
14498
14499   /* Construct the API message */
14500   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14501
14502   mp->is_add = is_add;
14503   if (ipv6_set)
14504     {
14505       mp->is_ipv6 = 1;
14506       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14507     }
14508   else
14509     {
14510       mp->is_ipv6 = 0;
14511       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14512     }
14513
14514   /* send it... */
14515   S (mp);
14516
14517   /* Wait for a reply... */
14518   W (ret);
14519   return ret;
14520 }
14521
14522 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14523
14524 static int
14525 api_lisp_gpe_enable_disable (vat_main_t * vam)
14526 {
14527   unformat_input_t *input = vam->input;
14528   vl_api_gpe_enable_disable_t *mp;
14529   u8 is_set = 0;
14530   u8 is_en = 1;
14531   int ret;
14532
14533   /* Parse args required to build the message */
14534   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14535     {
14536       if (unformat (input, "enable"))
14537         {
14538           is_set = 1;
14539           is_en = 1;
14540         }
14541       else if (unformat (input, "disable"))
14542         {
14543           is_set = 1;
14544           is_en = 0;
14545         }
14546       else
14547         break;
14548     }
14549
14550   if (is_set == 0)
14551     {
14552       errmsg ("Value not set");
14553       return -99;
14554     }
14555
14556   /* Construct the API message */
14557   M (GPE_ENABLE_DISABLE, mp);
14558
14559   mp->is_en = is_en;
14560
14561   /* send it... */
14562   S (mp);
14563
14564   /* Wait for a reply... */
14565   W (ret);
14566   return ret;
14567 }
14568
14569 static int
14570 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14571 {
14572   unformat_input_t *input = vam->input;
14573   vl_api_one_rloc_probe_enable_disable_t *mp;
14574   u8 is_set = 0;
14575   u8 is_en = 0;
14576   int ret;
14577
14578   /* Parse args required to build the message */
14579   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14580     {
14581       if (unformat (input, "enable"))
14582         {
14583           is_set = 1;
14584           is_en = 1;
14585         }
14586       else if (unformat (input, "disable"))
14587         is_set = 1;
14588       else
14589         break;
14590     }
14591
14592   if (!is_set)
14593     {
14594       errmsg ("Value not set");
14595       return -99;
14596     }
14597
14598   /* Construct the API message */
14599   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14600
14601   mp->is_enabled = is_en;
14602
14603   /* send it... */
14604   S (mp);
14605
14606   /* Wait for a reply... */
14607   W (ret);
14608   return ret;
14609 }
14610
14611 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14612
14613 static int
14614 api_one_map_register_enable_disable (vat_main_t * vam)
14615 {
14616   unformat_input_t *input = vam->input;
14617   vl_api_one_map_register_enable_disable_t *mp;
14618   u8 is_set = 0;
14619   u8 is_en = 0;
14620   int ret;
14621
14622   /* Parse args required to build the message */
14623   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14624     {
14625       if (unformat (input, "enable"))
14626         {
14627           is_set = 1;
14628           is_en = 1;
14629         }
14630       else if (unformat (input, "disable"))
14631         is_set = 1;
14632       else
14633         break;
14634     }
14635
14636   if (!is_set)
14637     {
14638       errmsg ("Value not set");
14639       return -99;
14640     }
14641
14642   /* Construct the API message */
14643   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14644
14645   mp->is_enabled = is_en;
14646
14647   /* send it... */
14648   S (mp);
14649
14650   /* Wait for a reply... */
14651   W (ret);
14652   return ret;
14653 }
14654
14655 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14656
14657 static int
14658 api_one_enable_disable (vat_main_t * vam)
14659 {
14660   unformat_input_t *input = vam->input;
14661   vl_api_one_enable_disable_t *mp;
14662   u8 is_set = 0;
14663   u8 is_en = 0;
14664   int ret;
14665
14666   /* Parse args required to build the message */
14667   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14668     {
14669       if (unformat (input, "enable"))
14670         {
14671           is_set = 1;
14672           is_en = 1;
14673         }
14674       else if (unformat (input, "disable"))
14675         {
14676           is_set = 1;
14677         }
14678       else
14679         break;
14680     }
14681
14682   if (!is_set)
14683     {
14684       errmsg ("Value not set");
14685       return -99;
14686     }
14687
14688   /* Construct the API message */
14689   M (ONE_ENABLE_DISABLE, mp);
14690
14691   mp->is_en = is_en;
14692
14693   /* send it... */
14694   S (mp);
14695
14696   /* Wait for a reply... */
14697   W (ret);
14698   return ret;
14699 }
14700
14701 #define api_lisp_enable_disable api_one_enable_disable
14702
14703 static int
14704 api_show_one_map_register_state (vat_main_t * vam)
14705 {
14706   vl_api_show_one_map_register_state_t *mp;
14707   int ret;
14708
14709   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
14710
14711   /* send */
14712   S (mp);
14713
14714   /* wait for reply */
14715   W (ret);
14716   return ret;
14717 }
14718
14719 #define api_show_lisp_map_register_state api_show_one_map_register_state
14720
14721 static int
14722 api_show_one_rloc_probe_state (vat_main_t * vam)
14723 {
14724   vl_api_show_one_rloc_probe_state_t *mp;
14725   int ret;
14726
14727   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
14728
14729   /* send */
14730   S (mp);
14731
14732   /* wait for reply */
14733   W (ret);
14734   return ret;
14735 }
14736
14737 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
14738
14739 static int
14740 api_one_stats_enable_disable (vat_main_t * vam)
14741 {
14742   vl_api_one_stats_enable_disable_t *mp;
14743   unformat_input_t *input = vam->input;
14744   u8 is_set = 0;
14745   u8 is_en = 0;
14746   int ret;
14747
14748   /* Parse args required to build the message */
14749   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14750     {
14751       if (unformat (input, "enable"))
14752         {
14753           is_set = 1;
14754           is_en = 1;
14755         }
14756       else if (unformat (input, "disable"))
14757         {
14758           is_set = 1;
14759         }
14760       else
14761         break;
14762     }
14763
14764   if (!is_set)
14765     {
14766       errmsg ("Value not set");
14767       return -99;
14768     }
14769
14770   M (ONE_STATS_ENABLE_DISABLE, mp);
14771   mp->is_en = is_en;
14772
14773   /* send */
14774   S (mp);
14775
14776   /* wait for reply */
14777   W (ret);
14778   return ret;
14779 }
14780
14781 static int
14782 api_show_one_stats_enable_disable (vat_main_t * vam)
14783 {
14784   vl_api_show_one_stats_enable_disable_t *mp;
14785   int ret;
14786
14787   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
14788
14789   /* send */
14790   S (mp);
14791
14792   /* wait for reply */
14793   W (ret);
14794   return ret;
14795 }
14796
14797 static int
14798 api_show_one_map_request_mode (vat_main_t * vam)
14799 {
14800   vl_api_show_one_map_request_mode_t *mp;
14801   int ret;
14802
14803   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
14804
14805   /* send */
14806   S (mp);
14807
14808   /* wait for reply */
14809   W (ret);
14810   return ret;
14811 }
14812
14813 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
14814
14815 static int
14816 api_one_map_request_mode (vat_main_t * vam)
14817 {
14818   unformat_input_t *input = vam->input;
14819   vl_api_one_map_request_mode_t *mp;
14820   u8 mode = 0;
14821   int ret;
14822
14823   /* Parse args required to build the message */
14824   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14825     {
14826       if (unformat (input, "dst-only"))
14827         mode = 0;
14828       else if (unformat (input, "src-dst"))
14829         mode = 1;
14830       else
14831         {
14832           errmsg ("parse error '%U'", format_unformat_error, input);
14833           return -99;
14834         }
14835     }
14836
14837   M (ONE_MAP_REQUEST_MODE, mp);
14838
14839   mp->mode = mode;
14840
14841   /* send */
14842   S (mp);
14843
14844   /* wait for reply */
14845   W (ret);
14846   return ret;
14847 }
14848
14849 #define api_lisp_map_request_mode api_one_map_request_mode
14850
14851 /**
14852  * Enable/disable ONE proxy ITR.
14853  *
14854  * @param vam vpp API test context
14855  * @return return code
14856  */
14857 static int
14858 api_one_pitr_set_locator_set (vat_main_t * vam)
14859 {
14860   u8 ls_name_set = 0;
14861   unformat_input_t *input = vam->input;
14862   vl_api_one_pitr_set_locator_set_t *mp;
14863   u8 is_add = 1;
14864   u8 *ls_name = 0;
14865   int ret;
14866
14867   /* Parse args required to build the message */
14868   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14869     {
14870       if (unformat (input, "del"))
14871         is_add = 0;
14872       else if (unformat (input, "locator-set %s", &ls_name))
14873         ls_name_set = 1;
14874       else
14875         {
14876           errmsg ("parse error '%U'", format_unformat_error, input);
14877           return -99;
14878         }
14879     }
14880
14881   if (!ls_name_set)
14882     {
14883       errmsg ("locator-set name not set!");
14884       return -99;
14885     }
14886
14887   M (ONE_PITR_SET_LOCATOR_SET, mp);
14888
14889   mp->is_add = is_add;
14890   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
14891   vec_free (ls_name);
14892
14893   /* send */
14894   S (mp);
14895
14896   /* wait for reply */
14897   W (ret);
14898   return ret;
14899 }
14900
14901 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
14902
14903 static int
14904 api_show_one_pitr (vat_main_t * vam)
14905 {
14906   vl_api_show_one_pitr_t *mp;
14907   int ret;
14908
14909   if (!vam->json_output)
14910     {
14911       print (vam->ofp, "%=20s", "lisp status:");
14912     }
14913
14914   M (SHOW_ONE_PITR, mp);
14915   /* send it... */
14916   S (mp);
14917
14918   /* Wait for a reply... */
14919   W (ret);
14920   return ret;
14921 }
14922
14923 #define api_show_lisp_pitr api_show_one_pitr
14924
14925 static int
14926 api_one_use_petr (vat_main_t * vam)
14927 {
14928   unformat_input_t *input = vam->input;
14929   vl_api_one_use_petr_t *mp;
14930   u8 is_add = 0;
14931   ip_address_t ip;
14932   int ret;
14933
14934   memset (&ip, 0, sizeof (ip));
14935
14936   /* Parse args required to build the message */
14937   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14938     {
14939       if (unformat (input, "disable"))
14940         is_add = 0;
14941       else
14942         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
14943         {
14944           is_add = 1;
14945           ip_addr_version (&ip) = IP4;
14946         }
14947       else
14948         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
14949         {
14950           is_add = 1;
14951           ip_addr_version (&ip) = IP6;
14952         }
14953       else
14954         {
14955           errmsg ("parse error '%U'", format_unformat_error, input);
14956           return -99;
14957         }
14958     }
14959
14960   M (ONE_USE_PETR, mp);
14961
14962   mp->is_add = is_add;
14963   if (is_add)
14964     {
14965       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
14966       if (mp->is_ip4)
14967         clib_memcpy (mp->address, &ip, 4);
14968       else
14969         clib_memcpy (mp->address, &ip, 16);
14970     }
14971
14972   /* send */
14973   S (mp);
14974
14975   /* wait for reply */
14976   W (ret);
14977   return ret;
14978 }
14979
14980 #define api_lisp_use_petr api_one_use_petr
14981
14982 static int
14983 api_show_one_use_petr (vat_main_t * vam)
14984 {
14985   vl_api_show_one_use_petr_t *mp;
14986   int ret;
14987
14988   if (!vam->json_output)
14989     {
14990       print (vam->ofp, "%=20s", "Proxy-ETR status:");
14991     }
14992
14993   M (SHOW_ONE_USE_PETR, mp);
14994   /* send it... */
14995   S (mp);
14996
14997   /* Wait for a reply... */
14998   W (ret);
14999   return ret;
15000 }
15001
15002 #define api_show_lisp_use_petr api_show_one_use_petr
15003
15004 /**
15005  * Add/delete mapping between vni and vrf
15006  */
15007 static int
15008 api_one_eid_table_add_del_map (vat_main_t * vam)
15009 {
15010   unformat_input_t *input = vam->input;
15011   vl_api_one_eid_table_add_del_map_t *mp;
15012   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15013   u32 vni, vrf, bd_index;
15014   int ret;
15015
15016   /* Parse args required to build the message */
15017   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15018     {
15019       if (unformat (input, "del"))
15020         is_add = 0;
15021       else if (unformat (input, "vrf %d", &vrf))
15022         vrf_set = 1;
15023       else if (unformat (input, "bd_index %d", &bd_index))
15024         bd_index_set = 1;
15025       else if (unformat (input, "vni %d", &vni))
15026         vni_set = 1;
15027       else
15028         break;
15029     }
15030
15031   if (!vni_set || (!vrf_set && !bd_index_set))
15032     {
15033       errmsg ("missing arguments!");
15034       return -99;
15035     }
15036
15037   if (vrf_set && bd_index_set)
15038     {
15039       errmsg ("error: both vrf and bd entered!");
15040       return -99;
15041     }
15042
15043   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15044
15045   mp->is_add = is_add;
15046   mp->vni = htonl (vni);
15047   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15048   mp->is_l2 = bd_index_set;
15049
15050   /* send */
15051   S (mp);
15052
15053   /* wait for reply */
15054   W (ret);
15055   return ret;
15056 }
15057
15058 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15059
15060 uword
15061 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15062 {
15063   u32 *action = va_arg (*args, u32 *);
15064   u8 *s = 0;
15065
15066   if (unformat (input, "%s", &s))
15067     {
15068       if (!strcmp ((char *) s, "no-action"))
15069         action[0] = 0;
15070       else if (!strcmp ((char *) s, "natively-forward"))
15071         action[0] = 1;
15072       else if (!strcmp ((char *) s, "send-map-request"))
15073         action[0] = 2;
15074       else if (!strcmp ((char *) s, "drop"))
15075         action[0] = 3;
15076       else
15077         {
15078           clib_warning ("invalid action: '%s'", s);
15079           action[0] = 3;
15080         }
15081     }
15082   else
15083     return 0;
15084
15085   vec_free (s);
15086   return 1;
15087 }
15088
15089 /**
15090  * Add/del remote mapping to/from ONE control plane
15091  *
15092  * @param vam vpp API test context
15093  * @return return code
15094  */
15095 static int
15096 api_one_add_del_remote_mapping (vat_main_t * vam)
15097 {
15098   unformat_input_t *input = vam->input;
15099   vl_api_one_add_del_remote_mapping_t *mp;
15100   u32 vni = 0;
15101   lisp_eid_vat_t _eid, *eid = &_eid;
15102   lisp_eid_vat_t _seid, *seid = &_seid;
15103   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15104   u32 action = ~0, p, w, data_len;
15105   ip4_address_t rloc4;
15106   ip6_address_t rloc6;
15107   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15108   int ret;
15109
15110   memset (&rloc, 0, sizeof (rloc));
15111
15112   /* Parse args required to build the message */
15113   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15114     {
15115       if (unformat (input, "del-all"))
15116         {
15117           del_all = 1;
15118         }
15119       else if (unformat (input, "del"))
15120         {
15121           is_add = 0;
15122         }
15123       else if (unformat (input, "add"))
15124         {
15125           is_add = 1;
15126         }
15127       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15128         {
15129           eid_set = 1;
15130         }
15131       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15132         {
15133           seid_set = 1;
15134         }
15135       else if (unformat (input, "vni %d", &vni))
15136         {
15137           ;
15138         }
15139       else if (unformat (input, "p %d w %d", &p, &w))
15140         {
15141           if (!curr_rloc)
15142             {
15143               errmsg ("No RLOC configured for setting priority/weight!");
15144               return -99;
15145             }
15146           curr_rloc->priority = p;
15147           curr_rloc->weight = w;
15148         }
15149       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15150         {
15151           rloc.is_ip4 = 1;
15152           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
15153           vec_add1 (rlocs, rloc);
15154           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15155         }
15156       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15157         {
15158           rloc.is_ip4 = 0;
15159           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
15160           vec_add1 (rlocs, rloc);
15161           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15162         }
15163       else if (unformat (input, "action %U",
15164                          unformat_negative_mapping_action, &action))
15165         {
15166           ;
15167         }
15168       else
15169         {
15170           clib_warning ("parse error '%U'", format_unformat_error, input);
15171           return -99;
15172         }
15173     }
15174
15175   if (0 == eid_set)
15176     {
15177       errmsg ("missing params!");
15178       return -99;
15179     }
15180
15181   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15182     {
15183       errmsg ("no action set for negative map-reply!");
15184       return -99;
15185     }
15186
15187   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15188
15189   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15190   mp->is_add = is_add;
15191   mp->vni = htonl (vni);
15192   mp->action = (u8) action;
15193   mp->is_src_dst = seid_set;
15194   mp->eid_len = eid->len;
15195   mp->seid_len = seid->len;
15196   mp->del_all = del_all;
15197   mp->eid_type = eid->type;
15198   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15199   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
15200
15201   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15202   clib_memcpy (mp->rlocs, rlocs, data_len);
15203   vec_free (rlocs);
15204
15205   /* send it... */
15206   S (mp);
15207
15208   /* Wait for a reply... */
15209   W (ret);
15210   return ret;
15211 }
15212
15213 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15214
15215 /**
15216  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15217  * forwarding entries in data-plane accordingly.
15218  *
15219  * @param vam vpp API test context
15220  * @return return code
15221  */
15222 static int
15223 api_one_add_del_adjacency (vat_main_t * vam)
15224 {
15225   unformat_input_t *input = vam->input;
15226   vl_api_one_add_del_adjacency_t *mp;
15227   u32 vni = 0;
15228   ip4_address_t leid4, reid4;
15229   ip6_address_t leid6, reid6;
15230   u8 reid_mac[6] = { 0 };
15231   u8 leid_mac[6] = { 0 };
15232   u8 reid_type, leid_type;
15233   u32 leid_len = 0, reid_len = 0, len;
15234   u8 is_add = 1;
15235   int ret;
15236
15237   leid_type = reid_type = (u8) ~ 0;
15238
15239   /* Parse args required to build the message */
15240   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15241     {
15242       if (unformat (input, "del"))
15243         {
15244           is_add = 0;
15245         }
15246       else if (unformat (input, "add"))
15247         {
15248           is_add = 1;
15249         }
15250       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
15251                          &reid4, &len))
15252         {
15253           reid_type = 0;        /* ipv4 */
15254           reid_len = len;
15255         }
15256       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
15257                          &reid6, &len))
15258         {
15259           reid_type = 1;        /* ipv6 */
15260           reid_len = len;
15261         }
15262       else if (unformat (input, "reid %U", unformat_ethernet_address,
15263                          reid_mac))
15264         {
15265           reid_type = 2;        /* mac */
15266         }
15267       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
15268                          &leid4, &len))
15269         {
15270           leid_type = 0;        /* ipv4 */
15271           leid_len = len;
15272         }
15273       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
15274                          &leid6, &len))
15275         {
15276           leid_type = 1;        /* ipv6 */
15277           leid_len = len;
15278         }
15279       else if (unformat (input, "leid %U", unformat_ethernet_address,
15280                          leid_mac))
15281         {
15282           leid_type = 2;        /* mac */
15283         }
15284       else if (unformat (input, "vni %d", &vni))
15285         {
15286           ;
15287         }
15288       else
15289         {
15290           errmsg ("parse error '%U'", format_unformat_error, input);
15291           return -99;
15292         }
15293     }
15294
15295   if ((u8) ~ 0 == reid_type)
15296     {
15297       errmsg ("missing params!");
15298       return -99;
15299     }
15300
15301   if (leid_type != reid_type)
15302     {
15303       errmsg ("remote and local EIDs are of different types!");
15304       return -99;
15305     }
15306
15307   M (ONE_ADD_DEL_ADJACENCY, mp);
15308   mp->is_add = is_add;
15309   mp->vni = htonl (vni);
15310   mp->leid_len = leid_len;
15311   mp->reid_len = reid_len;
15312   mp->eid_type = reid_type;
15313
15314   switch (mp->eid_type)
15315     {
15316     case 0:
15317       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
15318       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
15319       break;
15320     case 1:
15321       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
15322       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
15323       break;
15324     case 2:
15325       clib_memcpy (mp->leid, leid_mac, 6);
15326       clib_memcpy (mp->reid, reid_mac, 6);
15327       break;
15328     default:
15329       errmsg ("unknown EID type %d!", mp->eid_type);
15330       return 0;
15331     }
15332
15333   /* send it... */
15334   S (mp);
15335
15336   /* Wait for a reply... */
15337   W (ret);
15338   return ret;
15339 }
15340
15341 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
15342
15343 uword
15344 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
15345 {
15346   u32 *mode = va_arg (*args, u32 *);
15347
15348   if (unformat (input, "lisp"))
15349     *mode = 0;
15350   else if (unformat (input, "vxlan"))
15351     *mode = 1;
15352   else
15353     return 0;
15354
15355   return 1;
15356 }
15357
15358 static int
15359 api_gpe_get_encap_mode (vat_main_t * vam)
15360 {
15361   vl_api_gpe_get_encap_mode_t *mp;
15362   int ret;
15363
15364   /* Construct the API message */
15365   M (GPE_GET_ENCAP_MODE, mp);
15366
15367   /* send it... */
15368   S (mp);
15369
15370   /* Wait for a reply... */
15371   W (ret);
15372   return ret;
15373 }
15374
15375 static int
15376 api_gpe_set_encap_mode (vat_main_t * vam)
15377 {
15378   unformat_input_t *input = vam->input;
15379   vl_api_gpe_set_encap_mode_t *mp;
15380   int ret;
15381   u32 mode = 0;
15382
15383   /* Parse args required to build the message */
15384   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15385     {
15386       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
15387         ;
15388       else
15389         break;
15390     }
15391
15392   /* Construct the API message */
15393   M (GPE_SET_ENCAP_MODE, mp);
15394
15395   mp->mode = mode;
15396
15397   /* send it... */
15398   S (mp);
15399
15400   /* Wait for a reply... */
15401   W (ret);
15402   return ret;
15403 }
15404
15405 static int
15406 api_lisp_gpe_add_del_iface (vat_main_t * vam)
15407 {
15408   unformat_input_t *input = vam->input;
15409   vl_api_gpe_add_del_iface_t *mp;
15410   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
15411   u32 dp_table = 0, vni = 0;
15412   int ret;
15413
15414   /* Parse args required to build the message */
15415   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15416     {
15417       if (unformat (input, "up"))
15418         {
15419           action_set = 1;
15420           is_add = 1;
15421         }
15422       else if (unformat (input, "down"))
15423         {
15424           action_set = 1;
15425           is_add = 0;
15426         }
15427       else if (unformat (input, "table_id %d", &dp_table))
15428         {
15429           dp_table_set = 1;
15430         }
15431       else if (unformat (input, "bd_id %d", &dp_table))
15432         {
15433           dp_table_set = 1;
15434           is_l2 = 1;
15435         }
15436       else if (unformat (input, "vni %d", &vni))
15437         {
15438           vni_set = 1;
15439         }
15440       else
15441         break;
15442     }
15443
15444   if (action_set == 0)
15445     {
15446       errmsg ("Action not set");
15447       return -99;
15448     }
15449   if (dp_table_set == 0 || vni_set == 0)
15450     {
15451       errmsg ("vni and dp_table must be set");
15452       return -99;
15453     }
15454
15455   /* Construct the API message */
15456   M (GPE_ADD_DEL_IFACE, mp);
15457
15458   mp->is_add = is_add;
15459   mp->dp_table = dp_table;
15460   mp->is_l2 = is_l2;
15461   mp->vni = vni;
15462
15463   /* send it... */
15464   S (mp);
15465
15466   /* Wait for a reply... */
15467   W (ret);
15468   return ret;
15469 }
15470
15471 /**
15472  * Add/del map request itr rlocs from ONE control plane and updates
15473  *
15474  * @param vam vpp API test context
15475  * @return return code
15476  */
15477 static int
15478 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
15479 {
15480   unformat_input_t *input = vam->input;
15481   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
15482   u8 *locator_set_name = 0;
15483   u8 locator_set_name_set = 0;
15484   u8 is_add = 1;
15485   int ret;
15486
15487   /* Parse args required to build the message */
15488   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15489     {
15490       if (unformat (input, "del"))
15491         {
15492           is_add = 0;
15493         }
15494       else if (unformat (input, "%_%v%_", &locator_set_name))
15495         {
15496           locator_set_name_set = 1;
15497         }
15498       else
15499         {
15500           clib_warning ("parse error '%U'", format_unformat_error, input);
15501           return -99;
15502         }
15503     }
15504
15505   if (is_add && !locator_set_name_set)
15506     {
15507       errmsg ("itr-rloc is not set!");
15508       return -99;
15509     }
15510
15511   if (is_add && vec_len (locator_set_name) > 64)
15512     {
15513       errmsg ("itr-rloc locator-set name too long");
15514       vec_free (locator_set_name);
15515       return -99;
15516     }
15517
15518   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
15519   mp->is_add = is_add;
15520   if (is_add)
15521     {
15522       clib_memcpy (mp->locator_set_name, locator_set_name,
15523                    vec_len (locator_set_name));
15524     }
15525   else
15526     {
15527       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
15528     }
15529   vec_free (locator_set_name);
15530
15531   /* send it... */
15532   S (mp);
15533
15534   /* Wait for a reply... */
15535   W (ret);
15536   return ret;
15537 }
15538
15539 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
15540
15541 static int
15542 api_one_locator_dump (vat_main_t * vam)
15543 {
15544   unformat_input_t *input = vam->input;
15545   vl_api_one_locator_dump_t *mp;
15546   vl_api_control_ping_t *mp_ping;
15547   u8 is_index_set = 0, is_name_set = 0;
15548   u8 *ls_name = 0;
15549   u32 ls_index = ~0;
15550   int ret;
15551
15552   /* Parse args required to build the message */
15553   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15554     {
15555       if (unformat (input, "ls_name %_%v%_", &ls_name))
15556         {
15557           is_name_set = 1;
15558         }
15559       else if (unformat (input, "ls_index %d", &ls_index))
15560         {
15561           is_index_set = 1;
15562         }
15563       else
15564         {
15565           errmsg ("parse error '%U'", format_unformat_error, input);
15566           return -99;
15567         }
15568     }
15569
15570   if (!is_index_set && !is_name_set)
15571     {
15572       errmsg ("error: expected one of index or name!");
15573       return -99;
15574     }
15575
15576   if (is_index_set && is_name_set)
15577     {
15578       errmsg ("error: only one param expected!");
15579       return -99;
15580     }
15581
15582   if (vec_len (ls_name) > 62)
15583     {
15584       errmsg ("error: locator set name too long!");
15585       return -99;
15586     }
15587
15588   if (!vam->json_output)
15589     {
15590       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
15591     }
15592
15593   M (ONE_LOCATOR_DUMP, mp);
15594   mp->is_index_set = is_index_set;
15595
15596   if (is_index_set)
15597     mp->ls_index = clib_host_to_net_u32 (ls_index);
15598   else
15599     {
15600       vec_add1 (ls_name, 0);
15601       strncpy ((char *) mp->ls_name, (char *) ls_name,
15602                sizeof (mp->ls_name) - 1);
15603     }
15604
15605   /* send it... */
15606   S (mp);
15607
15608   /* Use a control ping for synchronization */
15609   M (CONTROL_PING, mp_ping);
15610   S (mp_ping);
15611
15612   /* Wait for a reply... */
15613   W (ret);
15614   return ret;
15615 }
15616
15617 #define api_lisp_locator_dump api_one_locator_dump
15618
15619 static int
15620 api_one_locator_set_dump (vat_main_t * vam)
15621 {
15622   vl_api_one_locator_set_dump_t *mp;
15623   vl_api_control_ping_t *mp_ping;
15624   unformat_input_t *input = vam->input;
15625   u8 filter = 0;
15626   int ret;
15627
15628   /* Parse args required to build the message */
15629   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15630     {
15631       if (unformat (input, "local"))
15632         {
15633           filter = 1;
15634         }
15635       else if (unformat (input, "remote"))
15636         {
15637           filter = 2;
15638         }
15639       else
15640         {
15641           errmsg ("parse error '%U'", format_unformat_error, input);
15642           return -99;
15643         }
15644     }
15645
15646   if (!vam->json_output)
15647     {
15648       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
15649     }
15650
15651   M (ONE_LOCATOR_SET_DUMP, mp);
15652
15653   mp->filter = filter;
15654
15655   /* send it... */
15656   S (mp);
15657
15658   /* Use a control ping for synchronization */
15659   M (CONTROL_PING, mp_ping);
15660   S (mp_ping);
15661
15662   /* Wait for a reply... */
15663   W (ret);
15664   return ret;
15665 }
15666
15667 #define api_lisp_locator_set_dump api_one_locator_set_dump
15668
15669 static int
15670 api_one_eid_table_map_dump (vat_main_t * vam)
15671 {
15672   u8 is_l2 = 0;
15673   u8 mode_set = 0;
15674   unformat_input_t *input = vam->input;
15675   vl_api_one_eid_table_map_dump_t *mp;
15676   vl_api_control_ping_t *mp_ping;
15677   int ret;
15678
15679   /* Parse args required to build the message */
15680   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15681     {
15682       if (unformat (input, "l2"))
15683         {
15684           is_l2 = 1;
15685           mode_set = 1;
15686         }
15687       else if (unformat (input, "l3"))
15688         {
15689           is_l2 = 0;
15690           mode_set = 1;
15691         }
15692       else
15693         {
15694           errmsg ("parse error '%U'", format_unformat_error, input);
15695           return -99;
15696         }
15697     }
15698
15699   if (!mode_set)
15700     {
15701       errmsg ("expected one of 'l2' or 'l3' parameter!");
15702       return -99;
15703     }
15704
15705   if (!vam->json_output)
15706     {
15707       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
15708     }
15709
15710   M (ONE_EID_TABLE_MAP_DUMP, mp);
15711   mp->is_l2 = is_l2;
15712
15713   /* send it... */
15714   S (mp);
15715
15716   /* Use a control ping for synchronization */
15717   M (CONTROL_PING, mp_ping);
15718   S (mp_ping);
15719
15720   /* Wait for a reply... */
15721   W (ret);
15722   return ret;
15723 }
15724
15725 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
15726
15727 static int
15728 api_one_eid_table_vni_dump (vat_main_t * vam)
15729 {
15730   vl_api_one_eid_table_vni_dump_t *mp;
15731   vl_api_control_ping_t *mp_ping;
15732   int ret;
15733
15734   if (!vam->json_output)
15735     {
15736       print (vam->ofp, "VNI");
15737     }
15738
15739   M (ONE_EID_TABLE_VNI_DUMP, mp);
15740
15741   /* send it... */
15742   S (mp);
15743
15744   /* Use a control ping for synchronization */
15745   M (CONTROL_PING, mp_ping);
15746   S (mp_ping);
15747
15748   /* Wait for a reply... */
15749   W (ret);
15750   return ret;
15751 }
15752
15753 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
15754
15755 static int
15756 api_one_eid_table_dump (vat_main_t * vam)
15757 {
15758   unformat_input_t *i = vam->input;
15759   vl_api_one_eid_table_dump_t *mp;
15760   vl_api_control_ping_t *mp_ping;
15761   struct in_addr ip4;
15762   struct in6_addr ip6;
15763   u8 mac[6];
15764   u8 eid_type = ~0, eid_set = 0;
15765   u32 prefix_length = ~0, t, vni = 0;
15766   u8 filter = 0;
15767   int ret;
15768
15769   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15770     {
15771       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
15772         {
15773           eid_set = 1;
15774           eid_type = 0;
15775           prefix_length = t;
15776         }
15777       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
15778         {
15779           eid_set = 1;
15780           eid_type = 1;
15781           prefix_length = t;
15782         }
15783       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
15784         {
15785           eid_set = 1;
15786           eid_type = 2;
15787         }
15788       else if (unformat (i, "vni %d", &t))
15789         {
15790           vni = t;
15791         }
15792       else if (unformat (i, "local"))
15793         {
15794           filter = 1;
15795         }
15796       else if (unformat (i, "remote"))
15797         {
15798           filter = 2;
15799         }
15800       else
15801         {
15802           errmsg ("parse error '%U'", format_unformat_error, i);
15803           return -99;
15804         }
15805     }
15806
15807   if (!vam->json_output)
15808     {
15809       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
15810              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
15811     }
15812
15813   M (ONE_EID_TABLE_DUMP, mp);
15814
15815   mp->filter = filter;
15816   if (eid_set)
15817     {
15818       mp->eid_set = 1;
15819       mp->vni = htonl (vni);
15820       mp->eid_type = eid_type;
15821       switch (eid_type)
15822         {
15823         case 0:
15824           mp->prefix_length = prefix_length;
15825           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
15826           break;
15827         case 1:
15828           mp->prefix_length = prefix_length;
15829           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
15830           break;
15831         case 2:
15832           clib_memcpy (mp->eid, mac, sizeof (mac));
15833           break;
15834         default:
15835           errmsg ("unknown EID type %d!", eid_type);
15836           return -99;
15837         }
15838     }
15839
15840   /* send it... */
15841   S (mp);
15842
15843   /* Use a control ping for synchronization */
15844   M (CONTROL_PING, mp_ping);
15845   S (mp_ping);
15846
15847   /* Wait for a reply... */
15848   W (ret);
15849   return ret;
15850 }
15851
15852 #define api_lisp_eid_table_dump api_one_eid_table_dump
15853
15854 static int
15855 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
15856 {
15857   unformat_input_t *i = vam->input;
15858   vl_api_gpe_fwd_entries_get_t *mp;
15859   u8 vni_set = 0;
15860   u32 vni = ~0;
15861   int ret;
15862
15863   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15864     {
15865       if (unformat (i, "vni %d", &vni))
15866         {
15867           vni_set = 1;
15868         }
15869       else
15870         {
15871           errmsg ("parse error '%U'", format_unformat_error, i);
15872           return -99;
15873         }
15874     }
15875
15876   if (!vni_set)
15877     {
15878       errmsg ("vni not set!");
15879       return -99;
15880     }
15881
15882   if (!vam->json_output)
15883     {
15884       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
15885              "leid", "reid");
15886     }
15887
15888   M (GPE_FWD_ENTRIES_GET, mp);
15889   mp->vni = clib_host_to_net_u32 (vni);
15890
15891   /* send it... */
15892   S (mp);
15893
15894   /* Wait for a reply... */
15895   W (ret);
15896   return ret;
15897 }
15898
15899 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
15900 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
15901 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
15902 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
15903
15904 static int
15905 api_one_adjacencies_get (vat_main_t * vam)
15906 {
15907   unformat_input_t *i = vam->input;
15908   vl_api_one_adjacencies_get_t *mp;
15909   u8 vni_set = 0;
15910   u32 vni = ~0;
15911   int ret;
15912
15913   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15914     {
15915       if (unformat (i, "vni %d", &vni))
15916         {
15917           vni_set = 1;
15918         }
15919       else
15920         {
15921           errmsg ("parse error '%U'", format_unformat_error, i);
15922           return -99;
15923         }
15924     }
15925
15926   if (!vni_set)
15927     {
15928       errmsg ("vni not set!");
15929       return -99;
15930     }
15931
15932   if (!vam->json_output)
15933     {
15934       print (vam->ofp, "%s %40s", "leid", "reid");
15935     }
15936
15937   M (ONE_ADJACENCIES_GET, mp);
15938   mp->vni = clib_host_to_net_u32 (vni);
15939
15940   /* send it... */
15941   S (mp);
15942
15943   /* Wait for a reply... */
15944   W (ret);
15945   return ret;
15946 }
15947
15948 #define api_lisp_adjacencies_get api_one_adjacencies_get
15949
15950 static int
15951 api_one_map_server_dump (vat_main_t * vam)
15952 {
15953   vl_api_one_map_server_dump_t *mp;
15954   vl_api_control_ping_t *mp_ping;
15955   int ret;
15956
15957   if (!vam->json_output)
15958     {
15959       print (vam->ofp, "%=20s", "Map server");
15960     }
15961
15962   M (ONE_MAP_SERVER_DUMP, mp);
15963   /* send it... */
15964   S (mp);
15965
15966   /* Use a control ping for synchronization */
15967   M (CONTROL_PING, mp_ping);
15968   S (mp_ping);
15969
15970   /* Wait for a reply... */
15971   W (ret);
15972   return ret;
15973 }
15974
15975 #define api_lisp_map_server_dump api_one_map_server_dump
15976
15977 static int
15978 api_one_map_resolver_dump (vat_main_t * vam)
15979 {
15980   vl_api_one_map_resolver_dump_t *mp;
15981   vl_api_control_ping_t *mp_ping;
15982   int ret;
15983
15984   if (!vam->json_output)
15985     {
15986       print (vam->ofp, "%=20s", "Map resolver");
15987     }
15988
15989   M (ONE_MAP_RESOLVER_DUMP, mp);
15990   /* send it... */
15991   S (mp);
15992
15993   /* Use a control ping for synchronization */
15994   M (CONTROL_PING, mp_ping);
15995   S (mp_ping);
15996
15997   /* Wait for a reply... */
15998   W (ret);
15999   return ret;
16000 }
16001
16002 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
16003
16004 static int
16005 api_one_stats_flush (vat_main_t * vam)
16006 {
16007   vl_api_one_stats_flush_t *mp;
16008   int ret = 0;
16009
16010   M (ONE_STATS_FLUSH, mp);
16011   S (mp);
16012   W (ret);
16013   return ret;
16014 }
16015
16016 static int
16017 api_one_stats_dump (vat_main_t * vam)
16018 {
16019   vl_api_one_stats_dump_t *mp;
16020   vl_api_control_ping_t *mp_ping;
16021   int ret;
16022
16023   M (ONE_STATS_DUMP, mp);
16024   /* send it... */
16025   S (mp);
16026
16027   /* Use a control ping for synchronization */
16028   M (CONTROL_PING, mp_ping);
16029   S (mp_ping);
16030
16031   /* Wait for a reply... */
16032   W (ret);
16033   return ret;
16034 }
16035
16036 static int
16037 api_show_one_status (vat_main_t * vam)
16038 {
16039   vl_api_show_one_status_t *mp;
16040   int ret;
16041
16042   if (!vam->json_output)
16043     {
16044       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
16045     }
16046
16047   M (SHOW_ONE_STATUS, mp);
16048   /* send it... */
16049   S (mp);
16050   /* Wait for a reply... */
16051   W (ret);
16052   return ret;
16053 }
16054
16055 #define api_show_lisp_status api_show_one_status
16056
16057 static int
16058 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
16059 {
16060   vl_api_gpe_fwd_entry_path_dump_t *mp;
16061   vl_api_control_ping_t *mp_ping;
16062   unformat_input_t *i = vam->input;
16063   u32 fwd_entry_index = ~0;
16064   int ret;
16065
16066   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16067     {
16068       if (unformat (i, "index %d", &fwd_entry_index))
16069         ;
16070       else
16071         break;
16072     }
16073
16074   if (~0 == fwd_entry_index)
16075     {
16076       errmsg ("no index specified!");
16077       return -99;
16078     }
16079
16080   if (!vam->json_output)
16081     {
16082       print (vam->ofp, "first line");
16083     }
16084
16085   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
16086
16087   /* send it... */
16088   S (mp);
16089   /* Use a control ping for synchronization */
16090   M (CONTROL_PING, mp_ping);
16091   S (mp_ping);
16092
16093   /* Wait for a reply... */
16094   W (ret);
16095   return ret;
16096 }
16097
16098 static int
16099 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
16100 {
16101   vl_api_one_get_map_request_itr_rlocs_t *mp;
16102   int ret;
16103
16104   if (!vam->json_output)
16105     {
16106       print (vam->ofp, "%=20s", "itr-rlocs:");
16107     }
16108
16109   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
16110   /* send it... */
16111   S (mp);
16112   /* Wait for a reply... */
16113   W (ret);
16114   return ret;
16115 }
16116
16117 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
16118
16119 static int
16120 api_af_packet_create (vat_main_t * vam)
16121 {
16122   unformat_input_t *i = vam->input;
16123   vl_api_af_packet_create_t *mp;
16124   u8 *host_if_name = 0;
16125   u8 hw_addr[6];
16126   u8 random_hw_addr = 1;
16127   int ret;
16128
16129   memset (hw_addr, 0, sizeof (hw_addr));
16130
16131   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16132     {
16133       if (unformat (i, "name %s", &host_if_name))
16134         vec_add1 (host_if_name, 0);
16135       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
16136         random_hw_addr = 0;
16137       else
16138         break;
16139     }
16140
16141   if (!vec_len (host_if_name))
16142     {
16143       errmsg ("host-interface name must be specified");
16144       return -99;
16145     }
16146
16147   if (vec_len (host_if_name) > 64)
16148     {
16149       errmsg ("host-interface name too long");
16150       return -99;
16151     }
16152
16153   M (AF_PACKET_CREATE, mp);
16154
16155   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
16156   clib_memcpy (mp->hw_addr, hw_addr, 6);
16157   mp->use_random_hw_addr = random_hw_addr;
16158   vec_free (host_if_name);
16159
16160   S (mp);
16161
16162   /* *INDENT-OFF* */
16163   W2 (ret,
16164       ({
16165         if (ret == 0)
16166           fprintf (vam->ofp ? vam->ofp : stderr,
16167                    " new sw_if_index = %d\n", vam->sw_if_index);
16168       }));
16169   /* *INDENT-ON* */
16170   return ret;
16171 }
16172
16173 static int
16174 api_af_packet_delete (vat_main_t * vam)
16175 {
16176   unformat_input_t *i = vam->input;
16177   vl_api_af_packet_delete_t *mp;
16178   u8 *host_if_name = 0;
16179   int ret;
16180
16181   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16182     {
16183       if (unformat (i, "name %s", &host_if_name))
16184         vec_add1 (host_if_name, 0);
16185       else
16186         break;
16187     }
16188
16189   if (!vec_len (host_if_name))
16190     {
16191       errmsg ("host-interface name must be specified");
16192       return -99;
16193     }
16194
16195   if (vec_len (host_if_name) > 64)
16196     {
16197       errmsg ("host-interface name too long");
16198       return -99;
16199     }
16200
16201   M (AF_PACKET_DELETE, mp);
16202
16203   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
16204   vec_free (host_if_name);
16205
16206   S (mp);
16207   W (ret);
16208   return ret;
16209 }
16210
16211 static int
16212 api_policer_add_del (vat_main_t * vam)
16213 {
16214   unformat_input_t *i = vam->input;
16215   vl_api_policer_add_del_t *mp;
16216   u8 is_add = 1;
16217   u8 *name = 0;
16218   u32 cir = 0;
16219   u32 eir = 0;
16220   u64 cb = 0;
16221   u64 eb = 0;
16222   u8 rate_type = 0;
16223   u8 round_type = 0;
16224   u8 type = 0;
16225   u8 color_aware = 0;
16226   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
16227   int ret;
16228
16229   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
16230   conform_action.dscp = 0;
16231   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
16232   exceed_action.dscp = 0;
16233   violate_action.action_type = SSE2_QOS_ACTION_DROP;
16234   violate_action.dscp = 0;
16235
16236   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16237     {
16238       if (unformat (i, "del"))
16239         is_add = 0;
16240       else if (unformat (i, "name %s", &name))
16241         vec_add1 (name, 0);
16242       else if (unformat (i, "cir %u", &cir))
16243         ;
16244       else if (unformat (i, "eir %u", &eir))
16245         ;
16246       else if (unformat (i, "cb %u", &cb))
16247         ;
16248       else if (unformat (i, "eb %u", &eb))
16249         ;
16250       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
16251                          &rate_type))
16252         ;
16253       else if (unformat (i, "round_type %U", unformat_policer_round_type,
16254                          &round_type))
16255         ;
16256       else if (unformat (i, "type %U", unformat_policer_type, &type))
16257         ;
16258       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
16259                          &conform_action))
16260         ;
16261       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
16262                          &exceed_action))
16263         ;
16264       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
16265                          &violate_action))
16266         ;
16267       else if (unformat (i, "color-aware"))
16268         color_aware = 1;
16269       else
16270         break;
16271     }
16272
16273   if (!vec_len (name))
16274     {
16275       errmsg ("policer name must be specified");
16276       return -99;
16277     }
16278
16279   if (vec_len (name) > 64)
16280     {
16281       errmsg ("policer name too long");
16282       return -99;
16283     }
16284
16285   M (POLICER_ADD_DEL, mp);
16286
16287   clib_memcpy (mp->name, name, vec_len (name));
16288   vec_free (name);
16289   mp->is_add = is_add;
16290   mp->cir = cir;
16291   mp->eir = eir;
16292   mp->cb = cb;
16293   mp->eb = eb;
16294   mp->rate_type = rate_type;
16295   mp->round_type = round_type;
16296   mp->type = type;
16297   mp->conform_action_type = conform_action.action_type;
16298   mp->conform_dscp = conform_action.dscp;
16299   mp->exceed_action_type = exceed_action.action_type;
16300   mp->exceed_dscp = exceed_action.dscp;
16301   mp->violate_action_type = violate_action.action_type;
16302   mp->violate_dscp = violate_action.dscp;
16303   mp->color_aware = color_aware;
16304
16305   S (mp);
16306   W (ret);
16307   return ret;
16308 }
16309
16310 static int
16311 api_policer_dump (vat_main_t * vam)
16312 {
16313   unformat_input_t *i = vam->input;
16314   vl_api_policer_dump_t *mp;
16315   vl_api_control_ping_t *mp_ping;
16316   u8 *match_name = 0;
16317   u8 match_name_valid = 0;
16318   int ret;
16319
16320   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16321     {
16322       if (unformat (i, "name %s", &match_name))
16323         {
16324           vec_add1 (match_name, 0);
16325           match_name_valid = 1;
16326         }
16327       else
16328         break;
16329     }
16330
16331   M (POLICER_DUMP, mp);
16332   mp->match_name_valid = match_name_valid;
16333   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
16334   vec_free (match_name);
16335   /* send it... */
16336   S (mp);
16337
16338   /* Use a control ping for synchronization */
16339   M (CONTROL_PING, mp_ping);
16340   S (mp_ping);
16341
16342   /* Wait for a reply... */
16343   W (ret);
16344   return ret;
16345 }
16346
16347 static int
16348 api_policer_classify_set_interface (vat_main_t * vam)
16349 {
16350   unformat_input_t *i = vam->input;
16351   vl_api_policer_classify_set_interface_t *mp;
16352   u32 sw_if_index;
16353   int sw_if_index_set;
16354   u32 ip4_table_index = ~0;
16355   u32 ip6_table_index = ~0;
16356   u32 l2_table_index = ~0;
16357   u8 is_add = 1;
16358   int ret;
16359
16360   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16361     {
16362       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16363         sw_if_index_set = 1;
16364       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16365         sw_if_index_set = 1;
16366       else if (unformat (i, "del"))
16367         is_add = 0;
16368       else if (unformat (i, "ip4-table %d", &ip4_table_index))
16369         ;
16370       else if (unformat (i, "ip6-table %d", &ip6_table_index))
16371         ;
16372       else if (unformat (i, "l2-table %d", &l2_table_index))
16373         ;
16374       else
16375         {
16376           clib_warning ("parse error '%U'", format_unformat_error, i);
16377           return -99;
16378         }
16379     }
16380
16381   if (sw_if_index_set == 0)
16382     {
16383       errmsg ("missing interface name or sw_if_index");
16384       return -99;
16385     }
16386
16387   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
16388
16389   mp->sw_if_index = ntohl (sw_if_index);
16390   mp->ip4_table_index = ntohl (ip4_table_index);
16391   mp->ip6_table_index = ntohl (ip6_table_index);
16392   mp->l2_table_index = ntohl (l2_table_index);
16393   mp->is_add = is_add;
16394
16395   S (mp);
16396   W (ret);
16397   return ret;
16398 }
16399
16400 static int
16401 api_policer_classify_dump (vat_main_t * vam)
16402 {
16403   unformat_input_t *i = vam->input;
16404   vl_api_policer_classify_dump_t *mp;
16405   vl_api_control_ping_t *mp_ping;
16406   u8 type = POLICER_CLASSIFY_N_TABLES;
16407   int ret;
16408
16409   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
16410     ;
16411   else
16412     {
16413       errmsg ("classify table type must be specified");
16414       return -99;
16415     }
16416
16417   if (!vam->json_output)
16418     {
16419       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
16420     }
16421
16422   M (POLICER_CLASSIFY_DUMP, mp);
16423   mp->type = type;
16424   /* send it... */
16425   S (mp);
16426
16427   /* Use a control ping for synchronization */
16428   M (CONTROL_PING, mp_ping);
16429   S (mp_ping);
16430
16431   /* Wait for a reply... */
16432   W (ret);
16433   return ret;
16434 }
16435
16436 static int
16437 api_netmap_create (vat_main_t * vam)
16438 {
16439   unformat_input_t *i = vam->input;
16440   vl_api_netmap_create_t *mp;
16441   u8 *if_name = 0;
16442   u8 hw_addr[6];
16443   u8 random_hw_addr = 1;
16444   u8 is_pipe = 0;
16445   u8 is_master = 0;
16446   int ret;
16447
16448   memset (hw_addr, 0, sizeof (hw_addr));
16449
16450   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16451     {
16452       if (unformat (i, "name %s", &if_name))
16453         vec_add1 (if_name, 0);
16454       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
16455         random_hw_addr = 0;
16456       else if (unformat (i, "pipe"))
16457         is_pipe = 1;
16458       else if (unformat (i, "master"))
16459         is_master = 1;
16460       else if (unformat (i, "slave"))
16461         is_master = 0;
16462       else
16463         break;
16464     }
16465
16466   if (!vec_len (if_name))
16467     {
16468       errmsg ("interface name must be specified");
16469       return -99;
16470     }
16471
16472   if (vec_len (if_name) > 64)
16473     {
16474       errmsg ("interface name too long");
16475       return -99;
16476     }
16477
16478   M (NETMAP_CREATE, mp);
16479
16480   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
16481   clib_memcpy (mp->hw_addr, hw_addr, 6);
16482   mp->use_random_hw_addr = random_hw_addr;
16483   mp->is_pipe = is_pipe;
16484   mp->is_master = is_master;
16485   vec_free (if_name);
16486
16487   S (mp);
16488   W (ret);
16489   return ret;
16490 }
16491
16492 static int
16493 api_netmap_delete (vat_main_t * vam)
16494 {
16495   unformat_input_t *i = vam->input;
16496   vl_api_netmap_delete_t *mp;
16497   u8 *if_name = 0;
16498   int ret;
16499
16500   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16501     {
16502       if (unformat (i, "name %s", &if_name))
16503         vec_add1 (if_name, 0);
16504       else
16505         break;
16506     }
16507
16508   if (!vec_len (if_name))
16509     {
16510       errmsg ("interface name must be specified");
16511       return -99;
16512     }
16513
16514   if (vec_len (if_name) > 64)
16515     {
16516       errmsg ("interface name too long");
16517       return -99;
16518     }
16519
16520   M (NETMAP_DELETE, mp);
16521
16522   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
16523   vec_free (if_name);
16524
16525   S (mp);
16526   W (ret);
16527   return ret;
16528 }
16529
16530 static void
16531 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
16532 {
16533   if (fp->afi == IP46_TYPE_IP6)
16534     print (vam->ofp,
16535            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16536            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16537            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16538            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16539            format_ip6_address, fp->next_hop);
16540   else if (fp->afi == IP46_TYPE_IP4)
16541     print (vam->ofp,
16542            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16543            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16544            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16545            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16546            format_ip4_address, fp->next_hop);
16547 }
16548
16549 static void
16550 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
16551                                  vl_api_fib_path2_t * fp)
16552 {
16553   struct in_addr ip4;
16554   struct in6_addr ip6;
16555
16556   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16557   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16558   vat_json_object_add_uint (node, "is_local", fp->is_local);
16559   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16560   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16561   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16562   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16563   if (fp->afi == IP46_TYPE_IP4)
16564     {
16565       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16566       vat_json_object_add_ip4 (node, "next_hop", ip4);
16567     }
16568   else if (fp->afi == IP46_TYPE_IP6)
16569     {
16570       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16571       vat_json_object_add_ip6 (node, "next_hop", ip6);
16572     }
16573 }
16574
16575 static void
16576 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
16577 {
16578   vat_main_t *vam = &vat_main;
16579   int count = ntohl (mp->mt_count);
16580   vl_api_fib_path2_t *fp;
16581   i32 i;
16582
16583   print (vam->ofp, "[%d]: sw_if_index %d via:",
16584          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
16585   fp = mp->mt_paths;
16586   for (i = 0; i < count; i++)
16587     {
16588       vl_api_mpls_fib_path_print (vam, fp);
16589       fp++;
16590     }
16591
16592   print (vam->ofp, "");
16593 }
16594
16595 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
16596 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
16597
16598 static void
16599 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
16600 {
16601   vat_main_t *vam = &vat_main;
16602   vat_json_node_t *node = NULL;
16603   int count = ntohl (mp->mt_count);
16604   vl_api_fib_path2_t *fp;
16605   i32 i;
16606
16607   if (VAT_JSON_ARRAY != vam->json_tree.type)
16608     {
16609       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16610       vat_json_init_array (&vam->json_tree);
16611     }
16612   node = vat_json_array_add (&vam->json_tree);
16613
16614   vat_json_init_object (node);
16615   vat_json_object_add_uint (node, "tunnel_index",
16616                             ntohl (mp->mt_tunnel_index));
16617   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
16618
16619   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
16620
16621   fp = mp->mt_paths;
16622   for (i = 0; i < count; i++)
16623     {
16624       vl_api_mpls_fib_path_json_print (node, fp);
16625       fp++;
16626     }
16627 }
16628
16629 static int
16630 api_mpls_tunnel_dump (vat_main_t * vam)
16631 {
16632   vl_api_mpls_tunnel_dump_t *mp;
16633   vl_api_control_ping_t *mp_ping;
16634   i32 index = -1;
16635   int ret;
16636
16637   /* Parse args required to build the message */
16638   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
16639     {
16640       if (!unformat (vam->input, "tunnel_index %d", &index))
16641         {
16642           index = -1;
16643           break;
16644         }
16645     }
16646
16647   print (vam->ofp, "  tunnel_index %d", index);
16648
16649   M (MPLS_TUNNEL_DUMP, mp);
16650   mp->tunnel_index = htonl (index);
16651   S (mp);
16652
16653   /* Use a control ping for synchronization */
16654   M (CONTROL_PING, mp_ping);
16655   S (mp_ping);
16656
16657   W (ret);
16658   return ret;
16659 }
16660
16661 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
16662 #define vl_api_mpls_fib_details_t_print vl_noop_handler
16663
16664
16665 static void
16666 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
16667 {
16668   vat_main_t *vam = &vat_main;
16669   int count = ntohl (mp->count);
16670   vl_api_fib_path2_t *fp;
16671   int i;
16672
16673   print (vam->ofp,
16674          "table-id %d, label %u, ess_bit %u",
16675          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
16676   fp = mp->path;
16677   for (i = 0; i < count; i++)
16678     {
16679       vl_api_mpls_fib_path_print (vam, fp);
16680       fp++;
16681     }
16682 }
16683
16684 static void vl_api_mpls_fib_details_t_handler_json
16685   (vl_api_mpls_fib_details_t * mp)
16686 {
16687   vat_main_t *vam = &vat_main;
16688   int count = ntohl (mp->count);
16689   vat_json_node_t *node = NULL;
16690   vl_api_fib_path2_t *fp;
16691   int i;
16692
16693   if (VAT_JSON_ARRAY != vam->json_tree.type)
16694     {
16695       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16696       vat_json_init_array (&vam->json_tree);
16697     }
16698   node = vat_json_array_add (&vam->json_tree);
16699
16700   vat_json_init_object (node);
16701   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16702   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
16703   vat_json_object_add_uint (node, "label", ntohl (mp->label));
16704   vat_json_object_add_uint (node, "path_count", count);
16705   fp = mp->path;
16706   for (i = 0; i < count; i++)
16707     {
16708       vl_api_mpls_fib_path_json_print (node, fp);
16709       fp++;
16710     }
16711 }
16712
16713 static int
16714 api_mpls_fib_dump (vat_main_t * vam)
16715 {
16716   vl_api_mpls_fib_dump_t *mp;
16717   vl_api_control_ping_t *mp_ping;
16718   int ret;
16719
16720   M (MPLS_FIB_DUMP, mp);
16721   S (mp);
16722
16723   /* Use a control ping for synchronization */
16724   M (CONTROL_PING, mp_ping);
16725   S (mp_ping);
16726
16727   W (ret);
16728   return ret;
16729 }
16730
16731 #define vl_api_ip_fib_details_t_endian vl_noop_handler
16732 #define vl_api_ip_fib_details_t_print vl_noop_handler
16733
16734 static void
16735 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
16736 {
16737   vat_main_t *vam = &vat_main;
16738   int count = ntohl (mp->count);
16739   vl_api_fib_path_t *fp;
16740   int i;
16741
16742   print (vam->ofp,
16743          "table-id %d, prefix %U/%d",
16744          ntohl (mp->table_id), format_ip4_address, mp->address,
16745          mp->address_length);
16746   fp = mp->path;
16747   for (i = 0; i < count; i++)
16748     {
16749       if (fp->afi == IP46_TYPE_IP6)
16750         print (vam->ofp,
16751                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16752                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16753                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16754                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16755                format_ip6_address, fp->next_hop);
16756       else if (fp->afi == IP46_TYPE_IP4)
16757         print (vam->ofp,
16758                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16759                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16760                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16761                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16762                format_ip4_address, fp->next_hop);
16763       fp++;
16764     }
16765 }
16766
16767 static void vl_api_ip_fib_details_t_handler_json
16768   (vl_api_ip_fib_details_t * mp)
16769 {
16770   vat_main_t *vam = &vat_main;
16771   int count = ntohl (mp->count);
16772   vat_json_node_t *node = NULL;
16773   struct in_addr ip4;
16774   struct in6_addr ip6;
16775   vl_api_fib_path_t *fp;
16776   int i;
16777
16778   if (VAT_JSON_ARRAY != vam->json_tree.type)
16779     {
16780       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16781       vat_json_init_array (&vam->json_tree);
16782     }
16783   node = vat_json_array_add (&vam->json_tree);
16784
16785   vat_json_init_object (node);
16786   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16787   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
16788   vat_json_object_add_ip4 (node, "prefix", ip4);
16789   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16790   vat_json_object_add_uint (node, "path_count", count);
16791   fp = mp->path;
16792   for (i = 0; i < count; i++)
16793     {
16794       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16795       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16796       vat_json_object_add_uint (node, "is_local", fp->is_local);
16797       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16798       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16799       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16800       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16801       if (fp->afi == IP46_TYPE_IP4)
16802         {
16803           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16804           vat_json_object_add_ip4 (node, "next_hop", ip4);
16805         }
16806       else if (fp->afi == IP46_TYPE_IP6)
16807         {
16808           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16809           vat_json_object_add_ip6 (node, "next_hop", ip6);
16810         }
16811     }
16812 }
16813
16814 static int
16815 api_ip_fib_dump (vat_main_t * vam)
16816 {
16817   vl_api_ip_fib_dump_t *mp;
16818   vl_api_control_ping_t *mp_ping;
16819   int ret;
16820
16821   M (IP_FIB_DUMP, mp);
16822   S (mp);
16823
16824   /* Use a control ping for synchronization */
16825   M (CONTROL_PING, mp_ping);
16826   S (mp_ping);
16827
16828   W (ret);
16829   return ret;
16830 }
16831
16832 static int
16833 api_ip_mfib_dump (vat_main_t * vam)
16834 {
16835   vl_api_ip_mfib_dump_t *mp;
16836   vl_api_control_ping_t *mp_ping;
16837   int ret;
16838
16839   M (IP_MFIB_DUMP, mp);
16840   S (mp);
16841
16842   /* Use a control ping for synchronization */
16843   M (CONTROL_PING, mp_ping);
16844   S (mp_ping);
16845
16846   W (ret);
16847   return ret;
16848 }
16849
16850 static void vl_api_ip_neighbor_details_t_handler
16851   (vl_api_ip_neighbor_details_t * mp)
16852 {
16853   vat_main_t *vam = &vat_main;
16854
16855   print (vam->ofp, "%c %U %U",
16856          (mp->is_static) ? 'S' : 'D',
16857          format_ethernet_address, &mp->mac_address,
16858          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
16859          &mp->ip_address);
16860 }
16861
16862 static void vl_api_ip_neighbor_details_t_handler_json
16863   (vl_api_ip_neighbor_details_t * mp)
16864 {
16865
16866   vat_main_t *vam = &vat_main;
16867   vat_json_node_t *node;
16868   struct in_addr ip4;
16869   struct in6_addr ip6;
16870
16871   if (VAT_JSON_ARRAY != vam->json_tree.type)
16872     {
16873       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16874       vat_json_init_array (&vam->json_tree);
16875     }
16876   node = vat_json_array_add (&vam->json_tree);
16877
16878   vat_json_init_object (node);
16879   vat_json_object_add_string_copy (node, "flag",
16880                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
16881                                    "dynamic");
16882
16883   vat_json_object_add_string_copy (node, "link_layer",
16884                                    format (0, "%U", format_ethernet_address,
16885                                            &mp->mac_address));
16886
16887   if (mp->is_ipv6)
16888     {
16889       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
16890       vat_json_object_add_ip6 (node, "ip_address", ip6);
16891     }
16892   else
16893     {
16894       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
16895       vat_json_object_add_ip4 (node, "ip_address", ip4);
16896     }
16897 }
16898
16899 static int
16900 api_ip_neighbor_dump (vat_main_t * vam)
16901 {
16902   unformat_input_t *i = vam->input;
16903   vl_api_ip_neighbor_dump_t *mp;
16904   vl_api_control_ping_t *mp_ping;
16905   u8 is_ipv6 = 0;
16906   u32 sw_if_index = ~0;
16907   int ret;
16908
16909   /* Parse args required to build the message */
16910   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16911     {
16912       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16913         ;
16914       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16915         ;
16916       else if (unformat (i, "ip6"))
16917         is_ipv6 = 1;
16918       else
16919         break;
16920     }
16921
16922   if (sw_if_index == ~0)
16923     {
16924       errmsg ("missing interface name or sw_if_index");
16925       return -99;
16926     }
16927
16928   M (IP_NEIGHBOR_DUMP, mp);
16929   mp->is_ipv6 = (u8) is_ipv6;
16930   mp->sw_if_index = ntohl (sw_if_index);
16931   S (mp);
16932
16933   /* Use a control ping for synchronization */
16934   M (CONTROL_PING, mp_ping);
16935   S (mp_ping);
16936
16937   W (ret);
16938   return ret;
16939 }
16940
16941 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
16942 #define vl_api_ip6_fib_details_t_print vl_noop_handler
16943
16944 static void
16945 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
16946 {
16947   vat_main_t *vam = &vat_main;
16948   int count = ntohl (mp->count);
16949   vl_api_fib_path_t *fp;
16950   int i;
16951
16952   print (vam->ofp,
16953          "table-id %d, prefix %U/%d",
16954          ntohl (mp->table_id), format_ip6_address, mp->address,
16955          mp->address_length);
16956   fp = mp->path;
16957   for (i = 0; i < count; i++)
16958     {
16959       if (fp->afi == IP46_TYPE_IP6)
16960         print (vam->ofp,
16961                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16962                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16963                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16964                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16965                format_ip6_address, fp->next_hop);
16966       else if (fp->afi == IP46_TYPE_IP4)
16967         print (vam->ofp,
16968                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16969                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16970                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16971                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16972                format_ip4_address, fp->next_hop);
16973       fp++;
16974     }
16975 }
16976
16977 static void vl_api_ip6_fib_details_t_handler_json
16978   (vl_api_ip6_fib_details_t * mp)
16979 {
16980   vat_main_t *vam = &vat_main;
16981   int count = ntohl (mp->count);
16982   vat_json_node_t *node = NULL;
16983   struct in_addr ip4;
16984   struct in6_addr ip6;
16985   vl_api_fib_path_t *fp;
16986   int i;
16987
16988   if (VAT_JSON_ARRAY != vam->json_tree.type)
16989     {
16990       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16991       vat_json_init_array (&vam->json_tree);
16992     }
16993   node = vat_json_array_add (&vam->json_tree);
16994
16995   vat_json_init_object (node);
16996   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16997   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
16998   vat_json_object_add_ip6 (node, "prefix", ip6);
16999   vat_json_object_add_uint (node, "mask_length", mp->address_length);
17000   vat_json_object_add_uint (node, "path_count", count);
17001   fp = mp->path;
17002   for (i = 0; i < count; i++)
17003     {
17004       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17005       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17006       vat_json_object_add_uint (node, "is_local", fp->is_local);
17007       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
17008       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
17009       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
17010       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
17011       if (fp->afi == IP46_TYPE_IP4)
17012         {
17013           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
17014           vat_json_object_add_ip4 (node, "next_hop", ip4);
17015         }
17016       else if (fp->afi == IP46_TYPE_IP6)
17017         {
17018           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
17019           vat_json_object_add_ip6 (node, "next_hop", ip6);
17020         }
17021     }
17022 }
17023
17024 static int
17025 api_ip6_fib_dump (vat_main_t * vam)
17026 {
17027   vl_api_ip6_fib_dump_t *mp;
17028   vl_api_control_ping_t *mp_ping;
17029   int ret;
17030
17031   M (IP6_FIB_DUMP, mp);
17032   S (mp);
17033
17034   /* Use a control ping for synchronization */
17035   M (CONTROL_PING, mp_ping);
17036   S (mp_ping);
17037
17038   W (ret);
17039   return ret;
17040 }
17041
17042 static int
17043 api_ip6_mfib_dump (vat_main_t * vam)
17044 {
17045   vl_api_ip6_mfib_dump_t *mp;
17046   vl_api_control_ping_t *mp_ping;
17047   int ret;
17048
17049   M (IP6_MFIB_DUMP, mp);
17050   S (mp);
17051
17052   /* Use a control ping for synchronization */
17053   M (CONTROL_PING, mp_ping);
17054   S (mp_ping);
17055
17056   W (ret);
17057   return ret;
17058 }
17059
17060 int
17061 api_classify_table_ids (vat_main_t * vam)
17062 {
17063   vl_api_classify_table_ids_t *mp;
17064   int ret;
17065
17066   /* Construct the API message */
17067   M (CLASSIFY_TABLE_IDS, mp);
17068   mp->context = 0;
17069
17070   S (mp);
17071   W (ret);
17072   return ret;
17073 }
17074
17075 int
17076 api_classify_table_by_interface (vat_main_t * vam)
17077 {
17078   unformat_input_t *input = vam->input;
17079   vl_api_classify_table_by_interface_t *mp;
17080
17081   u32 sw_if_index = ~0;
17082   int ret;
17083   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17084     {
17085       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17086         ;
17087       else if (unformat (input, "sw_if_index %d", &sw_if_index))
17088         ;
17089       else
17090         break;
17091     }
17092   if (sw_if_index == ~0)
17093     {
17094       errmsg ("missing interface name or sw_if_index");
17095       return -99;
17096     }
17097
17098   /* Construct the API message */
17099   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
17100   mp->context = 0;
17101   mp->sw_if_index = ntohl (sw_if_index);
17102
17103   S (mp);
17104   W (ret);
17105   return ret;
17106 }
17107
17108 int
17109 api_classify_table_info (vat_main_t * vam)
17110 {
17111   unformat_input_t *input = vam->input;
17112   vl_api_classify_table_info_t *mp;
17113
17114   u32 table_id = ~0;
17115   int ret;
17116   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17117     {
17118       if (unformat (input, "table_id %d", &table_id))
17119         ;
17120       else
17121         break;
17122     }
17123   if (table_id == ~0)
17124     {
17125       errmsg ("missing table id");
17126       return -99;
17127     }
17128
17129   /* Construct the API message */
17130   M (CLASSIFY_TABLE_INFO, mp);
17131   mp->context = 0;
17132   mp->table_id = ntohl (table_id);
17133
17134   S (mp);
17135   W (ret);
17136   return ret;
17137 }
17138
17139 int
17140 api_classify_session_dump (vat_main_t * vam)
17141 {
17142   unformat_input_t *input = vam->input;
17143   vl_api_classify_session_dump_t *mp;
17144   vl_api_control_ping_t *mp_ping;
17145
17146   u32 table_id = ~0;
17147   int ret;
17148   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17149     {
17150       if (unformat (input, "table_id %d", &table_id))
17151         ;
17152       else
17153         break;
17154     }
17155   if (table_id == ~0)
17156     {
17157       errmsg ("missing table id");
17158       return -99;
17159     }
17160
17161   /* Construct the API message */
17162   M (CLASSIFY_SESSION_DUMP, mp);
17163   mp->context = 0;
17164   mp->table_id = ntohl (table_id);
17165   S (mp);
17166
17167   /* Use a control ping for synchronization */
17168   M (CONTROL_PING, mp_ping);
17169   S (mp_ping);
17170
17171   W (ret);
17172   return ret;
17173 }
17174
17175 static void
17176 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
17177 {
17178   vat_main_t *vam = &vat_main;
17179
17180   print (vam->ofp, "collector_address %U, collector_port %d, "
17181          "src_address %U, vrf_id %d, path_mtu %u, "
17182          "template_interval %u, udp_checksum %d",
17183          format_ip4_address, mp->collector_address,
17184          ntohs (mp->collector_port),
17185          format_ip4_address, mp->src_address,
17186          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
17187          ntohl (mp->template_interval), mp->udp_checksum);
17188
17189   vam->retval = 0;
17190   vam->result_ready = 1;
17191 }
17192
17193 static void
17194   vl_api_ipfix_exporter_details_t_handler_json
17195   (vl_api_ipfix_exporter_details_t * mp)
17196 {
17197   vat_main_t *vam = &vat_main;
17198   vat_json_node_t node;
17199   struct in_addr collector_address;
17200   struct in_addr src_address;
17201
17202   vat_json_init_object (&node);
17203   clib_memcpy (&collector_address, &mp->collector_address,
17204                sizeof (collector_address));
17205   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
17206   vat_json_object_add_uint (&node, "collector_port",
17207                             ntohs (mp->collector_port));
17208   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
17209   vat_json_object_add_ip4 (&node, "src_address", src_address);
17210   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
17211   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
17212   vat_json_object_add_uint (&node, "template_interval",
17213                             ntohl (mp->template_interval));
17214   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
17215
17216   vat_json_print (vam->ofp, &node);
17217   vat_json_free (&node);
17218   vam->retval = 0;
17219   vam->result_ready = 1;
17220 }
17221
17222 int
17223 api_ipfix_exporter_dump (vat_main_t * vam)
17224 {
17225   vl_api_ipfix_exporter_dump_t *mp;
17226   int ret;
17227
17228   /* Construct the API message */
17229   M (IPFIX_EXPORTER_DUMP, mp);
17230   mp->context = 0;
17231
17232   S (mp);
17233   W (ret);
17234   return ret;
17235 }
17236
17237 static int
17238 api_ipfix_classify_stream_dump (vat_main_t * vam)
17239 {
17240   vl_api_ipfix_classify_stream_dump_t *mp;
17241   int ret;
17242
17243   /* Construct the API message */
17244   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
17245   mp->context = 0;
17246
17247   S (mp);
17248   W (ret);
17249   return ret;
17250   /* NOTREACHED */
17251   return 0;
17252 }
17253
17254 static void
17255   vl_api_ipfix_classify_stream_details_t_handler
17256   (vl_api_ipfix_classify_stream_details_t * mp)
17257 {
17258   vat_main_t *vam = &vat_main;
17259   print (vam->ofp, "domain_id %d, src_port %d",
17260          ntohl (mp->domain_id), ntohs (mp->src_port));
17261   vam->retval = 0;
17262   vam->result_ready = 1;
17263 }
17264
17265 static void
17266   vl_api_ipfix_classify_stream_details_t_handler_json
17267   (vl_api_ipfix_classify_stream_details_t * mp)
17268 {
17269   vat_main_t *vam = &vat_main;
17270   vat_json_node_t node;
17271
17272   vat_json_init_object (&node);
17273   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
17274   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
17275
17276   vat_json_print (vam->ofp, &node);
17277   vat_json_free (&node);
17278   vam->retval = 0;
17279   vam->result_ready = 1;
17280 }
17281
17282 static int
17283 api_ipfix_classify_table_dump (vat_main_t * vam)
17284 {
17285   vl_api_ipfix_classify_table_dump_t *mp;
17286   vl_api_control_ping_t *mp_ping;
17287   int ret;
17288
17289   if (!vam->json_output)
17290     {
17291       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
17292              "transport_protocol");
17293     }
17294
17295   /* Construct the API message */
17296   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
17297
17298   /* send it... */
17299   S (mp);
17300
17301   /* Use a control ping for synchronization */
17302   M (CONTROL_PING, mp_ping);
17303   S (mp_ping);
17304
17305   W (ret);
17306   return ret;
17307 }
17308
17309 static void
17310   vl_api_ipfix_classify_table_details_t_handler
17311   (vl_api_ipfix_classify_table_details_t * mp)
17312 {
17313   vat_main_t *vam = &vat_main;
17314   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
17315          mp->transport_protocol);
17316 }
17317
17318 static void
17319   vl_api_ipfix_classify_table_details_t_handler_json
17320   (vl_api_ipfix_classify_table_details_t * mp)
17321 {
17322   vat_json_node_t *node = NULL;
17323   vat_main_t *vam = &vat_main;
17324
17325   if (VAT_JSON_ARRAY != vam->json_tree.type)
17326     {
17327       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17328       vat_json_init_array (&vam->json_tree);
17329     }
17330
17331   node = vat_json_array_add (&vam->json_tree);
17332   vat_json_init_object (node);
17333
17334   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
17335   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
17336   vat_json_object_add_uint (node, "transport_protocol",
17337                             mp->transport_protocol);
17338 }
17339
17340 static int
17341 api_sw_interface_span_enable_disable (vat_main_t * vam)
17342 {
17343   unformat_input_t *i = vam->input;
17344   vl_api_sw_interface_span_enable_disable_t *mp;
17345   u32 src_sw_if_index = ~0;
17346   u32 dst_sw_if_index = ~0;
17347   u8 state = 3;
17348   int ret;
17349
17350   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17351     {
17352       if (unformat
17353           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
17354         ;
17355       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
17356         ;
17357       else
17358         if (unformat
17359             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
17360         ;
17361       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
17362         ;
17363       else if (unformat (i, "disable"))
17364         state = 0;
17365       else if (unformat (i, "rx"))
17366         state = 1;
17367       else if (unformat (i, "tx"))
17368         state = 2;
17369       else if (unformat (i, "both"))
17370         state = 3;
17371       else
17372         break;
17373     }
17374
17375   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
17376
17377   mp->sw_if_index_from = htonl (src_sw_if_index);
17378   mp->sw_if_index_to = htonl (dst_sw_if_index);
17379   mp->state = state;
17380
17381   S (mp);
17382   W (ret);
17383   return ret;
17384 }
17385
17386 static void
17387 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
17388                                             * mp)
17389 {
17390   vat_main_t *vam = &vat_main;
17391   u8 *sw_if_from_name = 0;
17392   u8 *sw_if_to_name = 0;
17393   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
17394   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
17395   char *states[] = { "none", "rx", "tx", "both" };
17396   hash_pair_t *p;
17397
17398   /* *INDENT-OFF* */
17399   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
17400   ({
17401     if ((u32) p->value[0] == sw_if_index_from)
17402       {
17403         sw_if_from_name = (u8 *)(p->key);
17404         if (sw_if_to_name)
17405           break;
17406       }
17407     if ((u32) p->value[0] == sw_if_index_to)
17408       {
17409         sw_if_to_name = (u8 *)(p->key);
17410         if (sw_if_from_name)
17411           break;
17412       }
17413   }));
17414   /* *INDENT-ON* */
17415   print (vam->ofp, "%20s => %20s (%s)",
17416          sw_if_from_name, sw_if_to_name, states[mp->state]);
17417 }
17418
17419 static void
17420   vl_api_sw_interface_span_details_t_handler_json
17421   (vl_api_sw_interface_span_details_t * mp)
17422 {
17423   vat_main_t *vam = &vat_main;
17424   vat_json_node_t *node = NULL;
17425   u8 *sw_if_from_name = 0;
17426   u8 *sw_if_to_name = 0;
17427   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
17428   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
17429   hash_pair_t *p;
17430
17431   /* *INDENT-OFF* */
17432   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
17433   ({
17434     if ((u32) p->value[0] == sw_if_index_from)
17435       {
17436         sw_if_from_name = (u8 *)(p->key);
17437         if (sw_if_to_name)
17438           break;
17439       }
17440     if ((u32) p->value[0] == sw_if_index_to)
17441       {
17442         sw_if_to_name = (u8 *)(p->key);
17443         if (sw_if_from_name)
17444           break;
17445       }
17446   }));
17447   /* *INDENT-ON* */
17448
17449   if (VAT_JSON_ARRAY != vam->json_tree.type)
17450     {
17451       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17452       vat_json_init_array (&vam->json_tree);
17453     }
17454   node = vat_json_array_add (&vam->json_tree);
17455
17456   vat_json_init_object (node);
17457   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
17458   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
17459   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
17460   if (0 != sw_if_to_name)
17461     {
17462       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
17463     }
17464   vat_json_object_add_uint (node, "state", mp->state);
17465 }
17466
17467 static int
17468 api_sw_interface_span_dump (vat_main_t * vam)
17469 {
17470   vl_api_sw_interface_span_dump_t *mp;
17471   vl_api_control_ping_t *mp_ping;
17472   int ret;
17473
17474   M (SW_INTERFACE_SPAN_DUMP, mp);
17475   S (mp);
17476
17477   /* Use a control ping for synchronization */
17478   M (CONTROL_PING, mp_ping);
17479   S (mp_ping);
17480
17481   W (ret);
17482   return ret;
17483 }
17484
17485 int
17486 api_pg_create_interface (vat_main_t * vam)
17487 {
17488   unformat_input_t *input = vam->input;
17489   vl_api_pg_create_interface_t *mp;
17490
17491   u32 if_id = ~0;
17492   int ret;
17493   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17494     {
17495       if (unformat (input, "if_id %d", &if_id))
17496         ;
17497       else
17498         break;
17499     }
17500   if (if_id == ~0)
17501     {
17502       errmsg ("missing pg interface index");
17503       return -99;
17504     }
17505
17506   /* Construct the API message */
17507   M (PG_CREATE_INTERFACE, mp);
17508   mp->context = 0;
17509   mp->interface_id = ntohl (if_id);
17510
17511   S (mp);
17512   W (ret);
17513   return ret;
17514 }
17515
17516 int
17517 api_pg_capture (vat_main_t * vam)
17518 {
17519   unformat_input_t *input = vam->input;
17520   vl_api_pg_capture_t *mp;
17521
17522   u32 if_id = ~0;
17523   u8 enable = 1;
17524   u32 count = 1;
17525   u8 pcap_file_set = 0;
17526   u8 *pcap_file = 0;
17527   int ret;
17528   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17529     {
17530       if (unformat (input, "if_id %d", &if_id))
17531         ;
17532       else if (unformat (input, "pcap %s", &pcap_file))
17533         pcap_file_set = 1;
17534       else if (unformat (input, "count %d", &count))
17535         ;
17536       else if (unformat (input, "disable"))
17537         enable = 0;
17538       else
17539         break;
17540     }
17541   if (if_id == ~0)
17542     {
17543       errmsg ("missing pg interface index");
17544       return -99;
17545     }
17546   if (pcap_file_set > 0)
17547     {
17548       if (vec_len (pcap_file) > 255)
17549         {
17550           errmsg ("pcap file name is too long");
17551           return -99;
17552         }
17553     }
17554
17555   u32 name_len = vec_len (pcap_file);
17556   /* Construct the API message */
17557   M (PG_CAPTURE, mp);
17558   mp->context = 0;
17559   mp->interface_id = ntohl (if_id);
17560   mp->is_enabled = enable;
17561   mp->count = ntohl (count);
17562   mp->pcap_name_length = ntohl (name_len);
17563   if (pcap_file_set != 0)
17564     {
17565       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
17566     }
17567   vec_free (pcap_file);
17568
17569   S (mp);
17570   W (ret);
17571   return ret;
17572 }
17573
17574 int
17575 api_pg_enable_disable (vat_main_t * vam)
17576 {
17577   unformat_input_t *input = vam->input;
17578   vl_api_pg_enable_disable_t *mp;
17579
17580   u8 enable = 1;
17581   u8 stream_name_set = 0;
17582   u8 *stream_name = 0;
17583   int ret;
17584   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17585     {
17586       if (unformat (input, "stream %s", &stream_name))
17587         stream_name_set = 1;
17588       else if (unformat (input, "disable"))
17589         enable = 0;
17590       else
17591         break;
17592     }
17593
17594   if (stream_name_set > 0)
17595     {
17596       if (vec_len (stream_name) > 255)
17597         {
17598           errmsg ("stream name too long");
17599           return -99;
17600         }
17601     }
17602
17603   u32 name_len = vec_len (stream_name);
17604   /* Construct the API message */
17605   M (PG_ENABLE_DISABLE, mp);
17606   mp->context = 0;
17607   mp->is_enabled = enable;
17608   if (stream_name_set != 0)
17609     {
17610       mp->stream_name_length = ntohl (name_len);
17611       clib_memcpy (mp->stream_name, stream_name, name_len);
17612     }
17613   vec_free (stream_name);
17614
17615   S (mp);
17616   W (ret);
17617   return ret;
17618 }
17619
17620 int
17621 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
17622 {
17623   unformat_input_t *input = vam->input;
17624   vl_api_ip_source_and_port_range_check_add_del_t *mp;
17625
17626   u16 *low_ports = 0;
17627   u16 *high_ports = 0;
17628   u16 this_low;
17629   u16 this_hi;
17630   ip4_address_t ip4_addr;
17631   ip6_address_t ip6_addr;
17632   u32 length;
17633   u32 tmp, tmp2;
17634   u8 prefix_set = 0;
17635   u32 vrf_id = ~0;
17636   u8 is_add = 1;
17637   u8 is_ipv6 = 0;
17638   int ret;
17639
17640   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17641     {
17642       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
17643         {
17644           prefix_set = 1;
17645         }
17646       else
17647         if (unformat
17648             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
17649         {
17650           prefix_set = 1;
17651           is_ipv6 = 1;
17652         }
17653       else if (unformat (input, "vrf %d", &vrf_id))
17654         ;
17655       else if (unformat (input, "del"))
17656         is_add = 0;
17657       else if (unformat (input, "port %d", &tmp))
17658         {
17659           if (tmp == 0 || tmp > 65535)
17660             {
17661               errmsg ("port %d out of range", tmp);
17662               return -99;
17663             }
17664           this_low = tmp;
17665           this_hi = this_low + 1;
17666           vec_add1 (low_ports, this_low);
17667           vec_add1 (high_ports, this_hi);
17668         }
17669       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
17670         {
17671           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
17672             {
17673               errmsg ("incorrect range parameters");
17674               return -99;
17675             }
17676           this_low = tmp;
17677           /* Note: in debug CLI +1 is added to high before
17678              passing to real fn that does "the work"
17679              (ip_source_and_port_range_check_add_del).
17680              This fn is a wrapper around the binary API fn a
17681              control plane will call, which expects this increment
17682              to have occurred. Hence letting the binary API control
17683              plane fn do the increment for consistency between VAT
17684              and other control planes.
17685            */
17686           this_hi = tmp2;
17687           vec_add1 (low_ports, this_low);
17688           vec_add1 (high_ports, this_hi);
17689         }
17690       else
17691         break;
17692     }
17693
17694   if (prefix_set == 0)
17695     {
17696       errmsg ("<address>/<mask> not specified");
17697       return -99;
17698     }
17699
17700   if (vrf_id == ~0)
17701     {
17702       errmsg ("VRF ID required, not specified");
17703       return -99;
17704     }
17705
17706   if (vrf_id == 0)
17707     {
17708       errmsg
17709         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17710       return -99;
17711     }
17712
17713   if (vec_len (low_ports) == 0)
17714     {
17715       errmsg ("At least one port or port range required");
17716       return -99;
17717     }
17718
17719   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
17720
17721   mp->is_add = is_add;
17722
17723   if (is_ipv6)
17724     {
17725       mp->is_ipv6 = 1;
17726       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
17727     }
17728   else
17729     {
17730       mp->is_ipv6 = 0;
17731       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
17732     }
17733
17734   mp->mask_length = length;
17735   mp->number_of_ranges = vec_len (low_ports);
17736
17737   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
17738   vec_free (low_ports);
17739
17740   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
17741   vec_free (high_ports);
17742
17743   mp->vrf_id = ntohl (vrf_id);
17744
17745   S (mp);
17746   W (ret);
17747   return ret;
17748 }
17749
17750 int
17751 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
17752 {
17753   unformat_input_t *input = vam->input;
17754   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
17755   u32 sw_if_index = ~0;
17756   int vrf_set = 0;
17757   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
17758   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
17759   u8 is_add = 1;
17760   int ret;
17761
17762   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17763     {
17764       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17765         ;
17766       else if (unformat (input, "sw_if_index %d", &sw_if_index))
17767         ;
17768       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
17769         vrf_set = 1;
17770       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
17771         vrf_set = 1;
17772       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
17773         vrf_set = 1;
17774       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
17775         vrf_set = 1;
17776       else if (unformat (input, "del"))
17777         is_add = 0;
17778       else
17779         break;
17780     }
17781
17782   if (sw_if_index == ~0)
17783     {
17784       errmsg ("Interface required but not specified");
17785       return -99;
17786     }
17787
17788   if (vrf_set == 0)
17789     {
17790       errmsg ("VRF ID required but not specified");
17791       return -99;
17792     }
17793
17794   if (tcp_out_vrf_id == 0
17795       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
17796     {
17797       errmsg
17798         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17799       return -99;
17800     }
17801
17802   /* Construct the API message */
17803   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
17804
17805   mp->sw_if_index = ntohl (sw_if_index);
17806   mp->is_add = is_add;
17807   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
17808   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
17809   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
17810   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
17811
17812   /* send it... */
17813   S (mp);
17814
17815   /* Wait for a reply... */
17816   W (ret);
17817   return ret;
17818 }
17819
17820 static int
17821 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
17822 {
17823   unformat_input_t *i = vam->input;
17824   vl_api_ipsec_gre_add_del_tunnel_t *mp;
17825   u32 local_sa_id = 0;
17826   u32 remote_sa_id = 0;
17827   ip4_address_t src_address;
17828   ip4_address_t dst_address;
17829   u8 is_add = 1;
17830   int ret;
17831
17832   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17833     {
17834       if (unformat (i, "local_sa %d", &local_sa_id))
17835         ;
17836       else if (unformat (i, "remote_sa %d", &remote_sa_id))
17837         ;
17838       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
17839         ;
17840       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
17841         ;
17842       else if (unformat (i, "del"))
17843         is_add = 0;
17844       else
17845         {
17846           clib_warning ("parse error '%U'", format_unformat_error, i);
17847           return -99;
17848         }
17849     }
17850
17851   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
17852
17853   mp->local_sa_id = ntohl (local_sa_id);
17854   mp->remote_sa_id = ntohl (remote_sa_id);
17855   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
17856   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
17857   mp->is_add = is_add;
17858
17859   S (mp);
17860   W (ret);
17861   return ret;
17862 }
17863
17864 static int
17865 api_punt (vat_main_t * vam)
17866 {
17867   unformat_input_t *i = vam->input;
17868   vl_api_punt_t *mp;
17869   u32 ipv = ~0;
17870   u32 protocol = ~0;
17871   u32 port = ~0;
17872   int is_add = 1;
17873   int ret;
17874
17875   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17876     {
17877       if (unformat (i, "ip %d", &ipv))
17878         ;
17879       else if (unformat (i, "protocol %d", &protocol))
17880         ;
17881       else if (unformat (i, "port %d", &port))
17882         ;
17883       else if (unformat (i, "del"))
17884         is_add = 0;
17885       else
17886         {
17887           clib_warning ("parse error '%U'", format_unformat_error, i);
17888           return -99;
17889         }
17890     }
17891
17892   M (PUNT, mp);
17893
17894   mp->is_add = (u8) is_add;
17895   mp->ipv = (u8) ipv;
17896   mp->l4_protocol = (u8) protocol;
17897   mp->l4_port = htons ((u16) port);
17898
17899   S (mp);
17900   W (ret);
17901   return ret;
17902 }
17903
17904 static void vl_api_ipsec_gre_tunnel_details_t_handler
17905   (vl_api_ipsec_gre_tunnel_details_t * mp)
17906 {
17907   vat_main_t *vam = &vat_main;
17908
17909   print (vam->ofp, "%11d%15U%15U%14d%14d",
17910          ntohl (mp->sw_if_index),
17911          format_ip4_address, &mp->src_address,
17912          format_ip4_address, &mp->dst_address,
17913          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
17914 }
17915
17916 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
17917   (vl_api_ipsec_gre_tunnel_details_t * mp)
17918 {
17919   vat_main_t *vam = &vat_main;
17920   vat_json_node_t *node = NULL;
17921   struct in_addr ip4;
17922
17923   if (VAT_JSON_ARRAY != vam->json_tree.type)
17924     {
17925       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17926       vat_json_init_array (&vam->json_tree);
17927     }
17928   node = vat_json_array_add (&vam->json_tree);
17929
17930   vat_json_init_object (node);
17931   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17932   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
17933   vat_json_object_add_ip4 (node, "src_address", ip4);
17934   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
17935   vat_json_object_add_ip4 (node, "dst_address", ip4);
17936   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
17937   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
17938 }
17939
17940 static int
17941 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
17942 {
17943   unformat_input_t *i = vam->input;
17944   vl_api_ipsec_gre_tunnel_dump_t *mp;
17945   vl_api_control_ping_t *mp_ping;
17946   u32 sw_if_index;
17947   u8 sw_if_index_set = 0;
17948   int ret;
17949
17950   /* Parse args required to build the message */
17951   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17952     {
17953       if (unformat (i, "sw_if_index %d", &sw_if_index))
17954         sw_if_index_set = 1;
17955       else
17956         break;
17957     }
17958
17959   if (sw_if_index_set == 0)
17960     {
17961       sw_if_index = ~0;
17962     }
17963
17964   if (!vam->json_output)
17965     {
17966       print (vam->ofp, "%11s%15s%15s%14s%14s",
17967              "sw_if_index", "src_address", "dst_address",
17968              "local_sa_id", "remote_sa_id");
17969     }
17970
17971   /* Get list of gre-tunnel interfaces */
17972   M (IPSEC_GRE_TUNNEL_DUMP, mp);
17973
17974   mp->sw_if_index = htonl (sw_if_index);
17975
17976   S (mp);
17977
17978   /* Use a control ping for synchronization */
17979   M (CONTROL_PING, mp_ping);
17980   S (mp_ping);
17981
17982   W (ret);
17983   return ret;
17984 }
17985
17986 static int
17987 api_delete_subif (vat_main_t * vam)
17988 {
17989   unformat_input_t *i = vam->input;
17990   vl_api_delete_subif_t *mp;
17991   u32 sw_if_index = ~0;
17992   int ret;
17993
17994   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17995     {
17996       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17997         ;
17998       if (unformat (i, "sw_if_index %d", &sw_if_index))
17999         ;
18000       else
18001         break;
18002     }
18003
18004   if (sw_if_index == ~0)
18005     {
18006       errmsg ("missing sw_if_index");
18007       return -99;
18008     }
18009
18010   /* Construct the API message */
18011   M (DELETE_SUBIF, mp);
18012   mp->sw_if_index = ntohl (sw_if_index);
18013
18014   S (mp);
18015   W (ret);
18016   return ret;
18017 }
18018
18019 #define foreach_pbb_vtr_op      \
18020 _("disable",  L2_VTR_DISABLED)  \
18021 _("pop",  L2_VTR_POP_2)         \
18022 _("push",  L2_VTR_PUSH_2)
18023
18024 static int
18025 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
18026 {
18027   unformat_input_t *i = vam->input;
18028   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
18029   u32 sw_if_index = ~0, vtr_op = ~0;
18030   u16 outer_tag = ~0;
18031   u8 dmac[6], smac[6];
18032   u8 dmac_set = 0, smac_set = 0;
18033   u16 vlanid = 0;
18034   u32 sid = ~0;
18035   u32 tmp;
18036   int ret;
18037
18038   /* Shut up coverity */
18039   memset (dmac, 0, sizeof (dmac));
18040   memset (smac, 0, sizeof (smac));
18041
18042   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18043     {
18044       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18045         ;
18046       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18047         ;
18048       else if (unformat (i, "vtr_op %d", &vtr_op))
18049         ;
18050 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
18051       foreach_pbb_vtr_op
18052 #undef _
18053         else if (unformat (i, "translate_pbb_stag"))
18054         {
18055           if (unformat (i, "%d", &tmp))
18056             {
18057               vtr_op = L2_VTR_TRANSLATE_2_1;
18058               outer_tag = tmp;
18059             }
18060           else
18061             {
18062               errmsg
18063                 ("translate_pbb_stag operation requires outer tag definition");
18064               return -99;
18065             }
18066         }
18067       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
18068         dmac_set++;
18069       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
18070         smac_set++;
18071       else if (unformat (i, "sid %d", &sid))
18072         ;
18073       else if (unformat (i, "vlanid %d", &tmp))
18074         vlanid = tmp;
18075       else
18076         {
18077           clib_warning ("parse error '%U'", format_unformat_error, i);
18078           return -99;
18079         }
18080     }
18081
18082   if ((sw_if_index == ~0) || (vtr_op == ~0))
18083     {
18084       errmsg ("missing sw_if_index or vtr operation");
18085       return -99;
18086     }
18087   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
18088       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
18089     {
18090       errmsg
18091         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
18092       return -99;
18093     }
18094
18095   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
18096   mp->sw_if_index = ntohl (sw_if_index);
18097   mp->vtr_op = ntohl (vtr_op);
18098   mp->outer_tag = ntohs (outer_tag);
18099   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
18100   clib_memcpy (mp->b_smac, smac, sizeof (smac));
18101   mp->b_vlanid = ntohs (vlanid);
18102   mp->i_sid = ntohl (sid);
18103
18104   S (mp);
18105   W (ret);
18106   return ret;
18107 }
18108
18109 static int
18110 api_flow_classify_set_interface (vat_main_t * vam)
18111 {
18112   unformat_input_t *i = vam->input;
18113   vl_api_flow_classify_set_interface_t *mp;
18114   u32 sw_if_index;
18115   int sw_if_index_set;
18116   u32 ip4_table_index = ~0;
18117   u32 ip6_table_index = ~0;
18118   u8 is_add = 1;
18119   int ret;
18120
18121   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18122     {
18123       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18124         sw_if_index_set = 1;
18125       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18126         sw_if_index_set = 1;
18127       else if (unformat (i, "del"))
18128         is_add = 0;
18129       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18130         ;
18131       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18132         ;
18133       else
18134         {
18135           clib_warning ("parse error '%U'", format_unformat_error, i);
18136           return -99;
18137         }
18138     }
18139
18140   if (sw_if_index_set == 0)
18141     {
18142       errmsg ("missing interface name or sw_if_index");
18143       return -99;
18144     }
18145
18146   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
18147
18148   mp->sw_if_index = ntohl (sw_if_index);
18149   mp->ip4_table_index = ntohl (ip4_table_index);
18150   mp->ip6_table_index = ntohl (ip6_table_index);
18151   mp->is_add = is_add;
18152
18153   S (mp);
18154   W (ret);
18155   return ret;
18156 }
18157
18158 static int
18159 api_flow_classify_dump (vat_main_t * vam)
18160 {
18161   unformat_input_t *i = vam->input;
18162   vl_api_flow_classify_dump_t *mp;
18163   vl_api_control_ping_t *mp_ping;
18164   u8 type = FLOW_CLASSIFY_N_TABLES;
18165   int ret;
18166
18167   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
18168     ;
18169   else
18170     {
18171       errmsg ("classify table type must be specified");
18172       return -99;
18173     }
18174
18175   if (!vam->json_output)
18176     {
18177       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18178     }
18179
18180   M (FLOW_CLASSIFY_DUMP, mp);
18181   mp->type = type;
18182   /* send it... */
18183   S (mp);
18184
18185   /* Use a control ping for synchronization */
18186   M (CONTROL_PING, mp_ping);
18187   S (mp_ping);
18188
18189   /* Wait for a reply... */
18190   W (ret);
18191   return ret;
18192 }
18193
18194 static int
18195 api_feature_enable_disable (vat_main_t * vam)
18196 {
18197   unformat_input_t *i = vam->input;
18198   vl_api_feature_enable_disable_t *mp;
18199   u8 *arc_name = 0;
18200   u8 *feature_name = 0;
18201   u32 sw_if_index = ~0;
18202   u8 enable = 1;
18203   int ret;
18204
18205   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18206     {
18207       if (unformat (i, "arc_name %s", &arc_name))
18208         ;
18209       else if (unformat (i, "feature_name %s", &feature_name))
18210         ;
18211       else
18212         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18213         ;
18214       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18215         ;
18216       else if (unformat (i, "disable"))
18217         enable = 0;
18218       else
18219         break;
18220     }
18221
18222   if (arc_name == 0)
18223     {
18224       errmsg ("missing arc name");
18225       return -99;
18226     }
18227   if (vec_len (arc_name) > 63)
18228     {
18229       errmsg ("arc name too long");
18230     }
18231
18232   if (feature_name == 0)
18233     {
18234       errmsg ("missing feature name");
18235       return -99;
18236     }
18237   if (vec_len (feature_name) > 63)
18238     {
18239       errmsg ("feature name too long");
18240     }
18241
18242   if (sw_if_index == ~0)
18243     {
18244       errmsg ("missing interface name or sw_if_index");
18245       return -99;
18246     }
18247
18248   /* Construct the API message */
18249   M (FEATURE_ENABLE_DISABLE, mp);
18250   mp->sw_if_index = ntohl (sw_if_index);
18251   mp->enable = enable;
18252   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
18253   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
18254   vec_free (arc_name);
18255   vec_free (feature_name);
18256
18257   S (mp);
18258   W (ret);
18259   return ret;
18260 }
18261
18262 static int
18263 api_sw_interface_tag_add_del (vat_main_t * vam)
18264 {
18265   unformat_input_t *i = vam->input;
18266   vl_api_sw_interface_tag_add_del_t *mp;
18267   u32 sw_if_index = ~0;
18268   u8 *tag = 0;
18269   u8 enable = 1;
18270   int ret;
18271
18272   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18273     {
18274       if (unformat (i, "tag %s", &tag))
18275         ;
18276       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18277         ;
18278       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18279         ;
18280       else if (unformat (i, "del"))
18281         enable = 0;
18282       else
18283         break;
18284     }
18285
18286   if (sw_if_index == ~0)
18287     {
18288       errmsg ("missing interface name or sw_if_index");
18289       return -99;
18290     }
18291
18292   if (enable && (tag == 0))
18293     {
18294       errmsg ("no tag specified");
18295       return -99;
18296     }
18297
18298   /* Construct the API message */
18299   M (SW_INTERFACE_TAG_ADD_DEL, mp);
18300   mp->sw_if_index = ntohl (sw_if_index);
18301   mp->is_add = enable;
18302   if (enable)
18303     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
18304   vec_free (tag);
18305
18306   S (mp);
18307   W (ret);
18308   return ret;
18309 }
18310
18311 static void vl_api_l2_xconnect_details_t_handler
18312   (vl_api_l2_xconnect_details_t * mp)
18313 {
18314   vat_main_t *vam = &vat_main;
18315
18316   print (vam->ofp, "%15d%15d",
18317          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
18318 }
18319
18320 static void vl_api_l2_xconnect_details_t_handler_json
18321   (vl_api_l2_xconnect_details_t * mp)
18322 {
18323   vat_main_t *vam = &vat_main;
18324   vat_json_node_t *node = NULL;
18325
18326   if (VAT_JSON_ARRAY != vam->json_tree.type)
18327     {
18328       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18329       vat_json_init_array (&vam->json_tree);
18330     }
18331   node = vat_json_array_add (&vam->json_tree);
18332
18333   vat_json_init_object (node);
18334   vat_json_object_add_uint (node, "rx_sw_if_index",
18335                             ntohl (mp->rx_sw_if_index));
18336   vat_json_object_add_uint (node, "tx_sw_if_index",
18337                             ntohl (mp->tx_sw_if_index));
18338 }
18339
18340 static int
18341 api_l2_xconnect_dump (vat_main_t * vam)
18342 {
18343   vl_api_l2_xconnect_dump_t *mp;
18344   vl_api_control_ping_t *mp_ping;
18345   int ret;
18346
18347   if (!vam->json_output)
18348     {
18349       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
18350     }
18351
18352   M (L2_XCONNECT_DUMP, mp);
18353
18354   S (mp);
18355
18356   /* Use a control ping for synchronization */
18357   M (CONTROL_PING, mp_ping);
18358   S (mp_ping);
18359
18360   W (ret);
18361   return ret;
18362 }
18363
18364 static int
18365 api_sw_interface_set_mtu (vat_main_t * vam)
18366 {
18367   unformat_input_t *i = vam->input;
18368   vl_api_sw_interface_set_mtu_t *mp;
18369   u32 sw_if_index = ~0;
18370   u32 mtu = 0;
18371   int ret;
18372
18373   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18374     {
18375       if (unformat (i, "mtu %d", &mtu))
18376         ;
18377       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18378         ;
18379       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18380         ;
18381       else
18382         break;
18383     }
18384
18385   if (sw_if_index == ~0)
18386     {
18387       errmsg ("missing interface name or sw_if_index");
18388       return -99;
18389     }
18390
18391   if (mtu == 0)
18392     {
18393       errmsg ("no mtu specified");
18394       return -99;
18395     }
18396
18397   /* Construct the API message */
18398   M (SW_INTERFACE_SET_MTU, mp);
18399   mp->sw_if_index = ntohl (sw_if_index);
18400   mp->mtu = ntohs ((u16) mtu);
18401
18402   S (mp);
18403   W (ret);
18404   return ret;
18405 }
18406
18407
18408 static int
18409 q_or_quit (vat_main_t * vam)
18410 {
18411 #if VPP_API_TEST_BUILTIN == 0
18412   longjmp (vam->jump_buf, 1);
18413 #endif
18414   return 0;                     /* not so much */
18415 }
18416
18417 static int
18418 q (vat_main_t * vam)
18419 {
18420   return q_or_quit (vam);
18421 }
18422
18423 static int
18424 quit (vat_main_t * vam)
18425 {
18426   return q_or_quit (vam);
18427 }
18428
18429 static int
18430 comment (vat_main_t * vam)
18431 {
18432   return 0;
18433 }
18434
18435 static int
18436 cmd_cmp (void *a1, void *a2)
18437 {
18438   u8 **c1 = a1;
18439   u8 **c2 = a2;
18440
18441   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
18442 }
18443
18444 static int
18445 help (vat_main_t * vam)
18446 {
18447   u8 **cmds = 0;
18448   u8 *name = 0;
18449   hash_pair_t *p;
18450   unformat_input_t *i = vam->input;
18451   int j;
18452
18453   if (unformat (i, "%s", &name))
18454     {
18455       uword *hs;
18456
18457       vec_add1 (name, 0);
18458
18459       hs = hash_get_mem (vam->help_by_name, name);
18460       if (hs)
18461         print (vam->ofp, "usage: %s %s", name, hs[0]);
18462       else
18463         print (vam->ofp, "No such msg / command '%s'", name);
18464       vec_free (name);
18465       return 0;
18466     }
18467
18468   print (vam->ofp, "Help is available for the following:");
18469
18470     /* *INDENT-OFF* */
18471     hash_foreach_pair (p, vam->function_by_name,
18472     ({
18473       vec_add1 (cmds, (u8 *)(p->key));
18474     }));
18475     /* *INDENT-ON* */
18476
18477   vec_sort_with_function (cmds, cmd_cmp);
18478
18479   for (j = 0; j < vec_len (cmds); j++)
18480     print (vam->ofp, "%s", cmds[j]);
18481
18482   vec_free (cmds);
18483   return 0;
18484 }
18485
18486 static int
18487 set (vat_main_t * vam)
18488 {
18489   u8 *name = 0, *value = 0;
18490   unformat_input_t *i = vam->input;
18491
18492   if (unformat (i, "%s", &name))
18493     {
18494       /* The input buffer is a vector, not a string. */
18495       value = vec_dup (i->buffer);
18496       vec_delete (value, i->index, 0);
18497       /* Almost certainly has a trailing newline */
18498       if (value[vec_len (value) - 1] == '\n')
18499         value[vec_len (value) - 1] = 0;
18500       /* Make sure it's a proper string, one way or the other */
18501       vec_add1 (value, 0);
18502       (void) clib_macro_set_value (&vam->macro_main,
18503                                    (char *) name, (char *) value);
18504     }
18505   else
18506     errmsg ("usage: set <name> <value>");
18507
18508   vec_free (name);
18509   vec_free (value);
18510   return 0;
18511 }
18512
18513 static int
18514 unset (vat_main_t * vam)
18515 {
18516   u8 *name = 0;
18517
18518   if (unformat (vam->input, "%s", &name))
18519     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
18520       errmsg ("unset: %s wasn't set", name);
18521   vec_free (name);
18522   return 0;
18523 }
18524
18525 typedef struct
18526 {
18527   u8 *name;
18528   u8 *value;
18529 } macro_sort_t;
18530
18531
18532 static int
18533 macro_sort_cmp (void *a1, void *a2)
18534 {
18535   macro_sort_t *s1 = a1;
18536   macro_sort_t *s2 = a2;
18537
18538   return strcmp ((char *) (s1->name), (char *) (s2->name));
18539 }
18540
18541 static int
18542 dump_macro_table (vat_main_t * vam)
18543 {
18544   macro_sort_t *sort_me = 0, *sm;
18545   int i;
18546   hash_pair_t *p;
18547
18548     /* *INDENT-OFF* */
18549     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
18550     ({
18551       vec_add2 (sort_me, sm, 1);
18552       sm->name = (u8 *)(p->key);
18553       sm->value = (u8 *) (p->value[0]);
18554     }));
18555     /* *INDENT-ON* */
18556
18557   vec_sort_with_function (sort_me, macro_sort_cmp);
18558
18559   if (vec_len (sort_me))
18560     print (vam->ofp, "%-15s%s", "Name", "Value");
18561   else
18562     print (vam->ofp, "The macro table is empty...");
18563
18564   for (i = 0; i < vec_len (sort_me); i++)
18565     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
18566   return 0;
18567 }
18568
18569 static int
18570 dump_node_table (vat_main_t * vam)
18571 {
18572   int i, j;
18573   vlib_node_t *node, *next_node;
18574
18575   if (vec_len (vam->graph_nodes) == 0)
18576     {
18577       print (vam->ofp, "Node table empty, issue get_node_graph...");
18578       return 0;
18579     }
18580
18581   for (i = 0; i < vec_len (vam->graph_nodes); i++)
18582     {
18583       node = vam->graph_nodes[i];
18584       print (vam->ofp, "[%d] %s", i, node->name);
18585       for (j = 0; j < vec_len (node->next_nodes); j++)
18586         {
18587           if (node->next_nodes[j] != ~0)
18588             {
18589               next_node = vam->graph_nodes[node->next_nodes[j]];
18590               print (vam->ofp, "  [%d] %s", j, next_node->name);
18591             }
18592         }
18593     }
18594   return 0;
18595 }
18596
18597 static int
18598 value_sort_cmp (void *a1, void *a2)
18599 {
18600   name_sort_t *n1 = a1;
18601   name_sort_t *n2 = a2;
18602
18603   if (n1->value < n2->value)
18604     return -1;
18605   if (n1->value > n2->value)
18606     return 1;
18607   return 0;
18608 }
18609
18610
18611 static int
18612 dump_msg_api_table (vat_main_t * vam)
18613 {
18614   api_main_t *am = &api_main;
18615   name_sort_t *nses = 0, *ns;
18616   hash_pair_t *hp;
18617   int i;
18618
18619   /* *INDENT-OFF* */
18620   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
18621   ({
18622     vec_add2 (nses, ns, 1);
18623     ns->name = (u8 *)(hp->key);
18624     ns->value = (u32) hp->value[0];
18625   }));
18626   /* *INDENT-ON* */
18627
18628   vec_sort_with_function (nses, value_sort_cmp);
18629
18630   for (i = 0; i < vec_len (nses); i++)
18631     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
18632   vec_free (nses);
18633   return 0;
18634 }
18635
18636 static int
18637 get_msg_id (vat_main_t * vam)
18638 {
18639   u8 *name_and_crc;
18640   u32 message_index;
18641
18642   if (unformat (vam->input, "%s", &name_and_crc))
18643     {
18644       message_index = vl_api_get_msg_index (name_and_crc);
18645       if (message_index == ~0)
18646         {
18647           print (vam->ofp, " '%s' not found", name_and_crc);
18648           return 0;
18649         }
18650       print (vam->ofp, " '%s' has message index %d",
18651              name_and_crc, message_index);
18652       return 0;
18653     }
18654   errmsg ("name_and_crc required...");
18655   return 0;
18656 }
18657
18658 static int
18659 search_node_table (vat_main_t * vam)
18660 {
18661   unformat_input_t *line_input = vam->input;
18662   u8 *node_to_find;
18663   int j;
18664   vlib_node_t *node, *next_node;
18665   uword *p;
18666
18667   if (vam->graph_node_index_by_name == 0)
18668     {
18669       print (vam->ofp, "Node table empty, issue get_node_graph...");
18670       return 0;
18671     }
18672
18673   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
18674     {
18675       if (unformat (line_input, "%s", &node_to_find))
18676         {
18677           vec_add1 (node_to_find, 0);
18678           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
18679           if (p == 0)
18680             {
18681               print (vam->ofp, "%s not found...", node_to_find);
18682               goto out;
18683             }
18684           node = vam->graph_nodes[p[0]];
18685           print (vam->ofp, "[%d] %s", p[0], node->name);
18686           for (j = 0; j < vec_len (node->next_nodes); j++)
18687             {
18688               if (node->next_nodes[j] != ~0)
18689                 {
18690                   next_node = vam->graph_nodes[node->next_nodes[j]];
18691                   print (vam->ofp, "  [%d] %s", j, next_node->name);
18692                 }
18693             }
18694         }
18695
18696       else
18697         {
18698           clib_warning ("parse error '%U'", format_unformat_error,
18699                         line_input);
18700           return -99;
18701         }
18702
18703     out:
18704       vec_free (node_to_find);
18705
18706     }
18707
18708   return 0;
18709 }
18710
18711
18712 static int
18713 script (vat_main_t * vam)
18714 {
18715 #if (VPP_API_TEST_BUILTIN==0)
18716   u8 *s = 0;
18717   char *save_current_file;
18718   unformat_input_t save_input;
18719   jmp_buf save_jump_buf;
18720   u32 save_line_number;
18721
18722   FILE *new_fp, *save_ifp;
18723
18724   if (unformat (vam->input, "%s", &s))
18725     {
18726       new_fp = fopen ((char *) s, "r");
18727       if (new_fp == 0)
18728         {
18729           errmsg ("Couldn't open script file %s", s);
18730           vec_free (s);
18731           return -99;
18732         }
18733     }
18734   else
18735     {
18736       errmsg ("Missing script name");
18737       return -99;
18738     }
18739
18740   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
18741   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
18742   save_ifp = vam->ifp;
18743   save_line_number = vam->input_line_number;
18744   save_current_file = (char *) vam->current_file;
18745
18746   vam->input_line_number = 0;
18747   vam->ifp = new_fp;
18748   vam->current_file = s;
18749   do_one_file (vam);
18750
18751   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
18752   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
18753   vam->ifp = save_ifp;
18754   vam->input_line_number = save_line_number;
18755   vam->current_file = (u8 *) save_current_file;
18756   vec_free (s);
18757
18758   return 0;
18759 #else
18760   clib_warning ("use the exec command...");
18761   return -99;
18762 #endif
18763 }
18764
18765 static int
18766 echo (vat_main_t * vam)
18767 {
18768   print (vam->ofp, "%v", vam->input->buffer);
18769   return 0;
18770 }
18771
18772 /* List of API message constructors, CLI names map to api_xxx */
18773 #define foreach_vpe_api_msg                                             \
18774 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
18775 _(sw_interface_dump,"")                                                 \
18776 _(sw_interface_set_flags,                                               \
18777   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
18778 _(sw_interface_add_del_address,                                         \
18779   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
18780 _(sw_interface_set_table,                                               \
18781   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
18782 _(sw_interface_set_mpls_enable,                                         \
18783   "<intfc> | sw_if_index [disable | dis]")                              \
18784 _(sw_interface_set_vpath,                                               \
18785   "<intfc> | sw_if_index <id> enable | disable")                        \
18786 _(sw_interface_set_vxlan_bypass,                                        \
18787   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
18788 _(sw_interface_set_l2_xconnect,                                         \
18789   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18790   "enable | disable")                                                   \
18791 _(sw_interface_set_l2_bridge,                                           \
18792   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
18793   "[shg <split-horizon-group>] [bvi]\n"                                 \
18794   "enable | disable")                                                   \
18795 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
18796 _(bridge_domain_add_del,                                                \
18797   "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") \
18798 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
18799 _(l2fib_add_del,                                                        \
18800   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
18801 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
18802 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
18803 _(l2_flags,                                                             \
18804   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
18805 _(bridge_flags,                                                         \
18806   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
18807 _(tap_connect,                                                          \
18808   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
18809 _(tap_modify,                                                           \
18810   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
18811 _(tap_delete,                                                           \
18812   "<vpp-if-name> | sw_if_index <id>")                                   \
18813 _(sw_interface_tap_dump, "")                                            \
18814 _(ip_add_del_route,                                                     \
18815   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
18816   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
18817   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
18818   "[multipath] [count <n>]")                                            \
18819 _(ip_mroute_add_del,                                                    \
18820   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
18821   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
18822 _(mpls_route_add_del,                                                   \
18823   "<label> <eos> via <addr> [table-id <n>]\n"                           \
18824   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
18825   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
18826   "[multipath] [count <n>]")                                            \
18827 _(mpls_ip_bind_unbind,                                                  \
18828   "<label> <addr/len>")                                                 \
18829 _(mpls_tunnel_add_del,                                                  \
18830   " via <addr> [table-id <n>]\n"                                        \
18831   "sw_if_index <id>] [l2]  [del]")                                      \
18832 _(proxy_arp_add_del,                                                    \
18833   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
18834 _(proxy_arp_intfc_enable_disable,                                       \
18835   "<intfc> | sw_if_index <id> enable | disable")                        \
18836 _(sw_interface_set_unnumbered,                                          \
18837   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
18838 _(ip_neighbor_add_del,                                                  \
18839   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
18840   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
18841 _(reset_vrf, "vrf <id> [ipv6]")                                         \
18842 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
18843 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
18844   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
18845   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
18846   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
18847 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
18848 _(reset_fib, "vrf <n> [ipv6]")                                          \
18849 _(dhcp_proxy_config,                                                    \
18850   "svr <v46-address> src <v46-address>\n"                               \
18851    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
18852 _(dhcp_proxy_set_vss,                                                   \
18853   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
18854 _(dhcp_proxy_dump, "ip6")                                               \
18855 _(dhcp_client_config,                                                   \
18856   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
18857 _(set_ip_flow_hash,                                                     \
18858   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
18859 _(sw_interface_ip6_enable_disable,                                      \
18860   "<intfc> | sw_if_index <id> enable | disable")                        \
18861 _(sw_interface_ip6_set_link_local_address,                              \
18862   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
18863 _(ip6nd_proxy_add_del,                                                  \
18864   "<intfc> | sw_if_index <id> <ip6-address>")                           \
18865 _(ip6nd_proxy_dump, "")                                                 \
18866 _(sw_interface_ip6nd_ra_prefix,                                         \
18867   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
18868   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
18869   "[nolink] [isno]")                                                    \
18870 _(sw_interface_ip6nd_ra_config,                                         \
18871   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
18872   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
18873   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
18874 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
18875 _(l2_patch_add_del,                                                     \
18876   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18877   "enable | disable")                                                   \
18878 _(sr_localsid_add_del,                                                  \
18879   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
18880   "fib-table <num> (end.psp) sw_if_index <num>")                        \
18881 _(classify_add_del_table,                                               \
18882   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
18883   " [del] [del-chain] mask <mask-value>\n"                              \
18884   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
18885   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
18886 _(classify_add_del_session,                                             \
18887   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
18888   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
18889   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
18890   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
18891 _(classify_set_interface_ip_table,                                      \
18892   "<intfc> | sw_if_index <nn> table <nn>")                              \
18893 _(classify_set_interface_l2_tables,                                     \
18894   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18895   "  [other-table <nn>]")                                               \
18896 _(get_node_index, "node <node-name")                                    \
18897 _(add_node_next, "node <node-name> next <next-node-name>")              \
18898 _(l2tpv3_create_tunnel,                                                 \
18899   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
18900   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
18901   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
18902 _(l2tpv3_set_tunnel_cookies,                                            \
18903   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
18904   "[new_remote_cookie <nn>]\n")                                         \
18905 _(l2tpv3_interface_enable_disable,                                      \
18906   "<intfc> | sw_if_index <nn> enable | disable")                        \
18907 _(l2tpv3_set_lookup_key,                                                \
18908   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
18909 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
18910 _(vxlan_add_del_tunnel,                                                 \
18911   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
18912   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
18913   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
18914 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
18915 _(gre_add_del_tunnel,                                                   \
18916   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
18917 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
18918 _(l2_fib_clear_table, "")                                               \
18919 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
18920 _(l2_interface_vlan_tag_rewrite,                                        \
18921   "<intfc> | sw_if_index <nn> \n"                                       \
18922   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
18923   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
18924 _(create_vhost_user_if,                                                 \
18925         "socket <filename> [server] [renumber <dev_instance>] "         \
18926         "[mac <mac_address>] "                                          \
18927         "[mode <interrupt | polling>]")                                 \
18928 _(modify_vhost_user_if,                                                 \
18929         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
18930         "[server] [renumber <dev_instance>] "                           \
18931         "[mode <interrupt | polling>]")                                 \
18932 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
18933 _(sw_interface_vhost_user_dump, "")                                     \
18934 _(show_version, "")                                                     \
18935 _(vxlan_gpe_add_del_tunnel,                                             \
18936   "local <addr> remote <addr> vni <nn>\n"                               \
18937     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
18938   "[next-ethernet] [next-nsh]\n")                                       \
18939 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
18940 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
18941 _(interface_name_renumber,                                              \
18942   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
18943 _(input_acl_set_interface,                                              \
18944   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18945   "  [l2-table <nn>] [del]")                                            \
18946 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
18947 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
18948 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
18949 _(ip_dump, "ipv4 | ipv6")                                               \
18950 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
18951 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
18952   "  spid_id <n> ")                                                     \
18953 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
18954   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
18955   "  integ_alg <alg> integ_key <hex>")                                  \
18956 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
18957   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
18958   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
18959   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
18960 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
18961 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
18962   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
18963   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
18964   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
18965 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
18966 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
18967   "(auth_data 0x<data> | auth_data <data>)")                            \
18968 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
18969   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
18970 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
18971   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
18972   "(local|remote)")                                                     \
18973 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
18974 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
18975 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18976 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18977 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
18978 _(ikev2_initiate_sa_init, "<profile_name>")                             \
18979 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
18980 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
18981 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
18982 _(delete_loopback,"sw_if_index <nn>")                                   \
18983 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
18984 _(map_add_domain,                                                       \
18985   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
18986   "ip6-src <ip6addr> "                                                  \
18987   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
18988 _(map_del_domain, "index <n>")                                          \
18989 _(map_add_del_rule,                                                     \
18990   "index <n> psid <n> dst <ip6addr> [del]")                             \
18991 _(map_domain_dump, "")                                                  \
18992 _(map_rule_dump, "index <map-domain>")                                  \
18993 _(want_interface_events,  "enable|disable")                             \
18994 _(want_stats,"enable|disable")                                          \
18995 _(get_first_msg_id, "client <name>")                                    \
18996 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
18997 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
18998   "fib-id <nn> [ip4][ip6][default]")                                    \
18999 _(get_node_graph, " ")                                                  \
19000 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
19001 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
19002 _(ioam_disable, "")                                                     \
19003 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
19004                             " sw_if_index <sw_if_index> p <priority> "  \
19005                             "w <weight>] [del]")                        \
19006 _(one_add_del_locator, "locator-set <locator_name> "                    \
19007                         "iface <intf> | sw_if_index <sw_if_index> "     \
19008                         "p <priority> w <weight> [del]")                \
19009 _(one_add_del_local_eid,"vni <vni> eid "                                \
19010                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
19011                          "locator-set <locator_name> [del]"             \
19012                          "[key-id sha1|sha256 secret-key <secret-key>]")\
19013 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
19014 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
19015 _(one_enable_disable, "enable|disable")                                 \
19016 _(one_map_register_enable_disable, "enable|disable")                    \
19017 _(one_rloc_probe_enable_disable, "enable|disable")                      \
19018 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
19019                                "[seid <seid>] "                         \
19020                                "rloc <locator> p <prio> "               \
19021                                "w <weight> [rloc <loc> ... ] "          \
19022                                "action <action> [del-all]")             \
19023 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
19024                           "<local-eid>")                                \
19025 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
19026 _(one_use_petr, "ip-address> | disable")                                \
19027 _(one_map_request_mode, "src-dst|dst-only")                             \
19028 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
19029 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
19030 _(one_locator_set_dump, "[local | remote]")                             \
19031 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
19032 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
19033                        "[local] | [remote]")                            \
19034 _(one_stats_enable_disable, "enable|disalbe")                           \
19035 _(show_one_stats_enable_disable, "")                                    \
19036 _(one_eid_table_vni_dump, "")                                           \
19037 _(one_eid_table_map_dump, "l2|l3")                                      \
19038 _(one_map_resolver_dump, "")                                            \
19039 _(one_map_server_dump, "")                                              \
19040 _(one_adjacencies_get, "vni <vni>")                                     \
19041 _(show_one_rloc_probe_state, "")                                        \
19042 _(show_one_map_register_state, "")                                      \
19043 _(show_one_status, "")                                                  \
19044 _(one_stats_dump, "")                                                   \
19045 _(one_stats_flush, "")                                                  \
19046 _(one_get_map_request_itr_rlocs, "")                                    \
19047 _(show_one_pitr, "")                                                    \
19048 _(show_one_use_petr, "")                                                \
19049 _(show_one_map_request_mode, "")                                        \
19050 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
19051                             " sw_if_index <sw_if_index> p <priority> "  \
19052                             "w <weight>] [del]")                        \
19053 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
19054                         "iface <intf> | sw_if_index <sw_if_index> "     \
19055                         "p <priority> w <weight> [del]")                \
19056 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
19057                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
19058                          "locator-set <locator_name> [del]"             \
19059                          "[key-id sha1|sha256 secret-key <secret-key>]") \
19060 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
19061 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
19062 _(lisp_enable_disable, "enable|disable")                                \
19063 _(lisp_map_register_enable_disable, "enable|disable")                   \
19064 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
19065 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
19066                                "[seid <seid>] "                         \
19067                                "rloc <locator> p <prio> "               \
19068                                "w <weight> [rloc <loc> ... ] "          \
19069                                "action <action> [del-all]")             \
19070 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
19071                           "<local-eid>")                                \
19072 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
19073 _(lisp_use_petr, "<ip-address> | disable")                              \
19074 _(lisp_map_request_mode, "src-dst|dst-only")                            \
19075 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
19076 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
19077 _(lisp_locator_set_dump, "[local | remote]")                            \
19078 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
19079 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
19080                        "[local] | [remote]")                            \
19081 _(lisp_eid_table_vni_dump, "")                                          \
19082 _(lisp_eid_table_map_dump, "l2|l3")                                     \
19083 _(lisp_map_resolver_dump, "")                                           \
19084 _(lisp_map_server_dump, "")                                             \
19085 _(lisp_adjacencies_get, "vni <vni>")                                    \
19086 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
19087 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
19088 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
19089 _(gpe_get_encap_mode, "")                                               \
19090 _(lisp_gpe_add_del_iface, "up|down")                                    \
19091 _(lisp_gpe_enable_disable, "enable|disable")                            \
19092 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
19093   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
19094 _(show_lisp_rloc_probe_state, "")                                       \
19095 _(show_lisp_map_register_state, "")                                     \
19096 _(show_lisp_status, "")                                                 \
19097 _(lisp_get_map_request_itr_rlocs, "")                                   \
19098 _(show_lisp_pitr, "")                                                   \
19099 _(show_lisp_use_petr, "")                                               \
19100 _(show_lisp_map_request_mode, "")                                       \
19101 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
19102 _(af_packet_delete, "name <host interface name>")                       \
19103 _(policer_add_del, "name <policer name> <params> [del]")                \
19104 _(policer_dump, "[name <policer name>]")                                \
19105 _(policer_classify_set_interface,                                       \
19106   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
19107   "  [l2-table <nn>] [del]")                                            \
19108 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
19109 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
19110     "[master|slave]")                                                   \
19111 _(netmap_delete, "name <interface name>")                               \
19112 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
19113 _(mpls_fib_dump, "")                                                    \
19114 _(classify_table_ids, "")                                               \
19115 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
19116 _(classify_table_info, "table_id <nn>")                                 \
19117 _(classify_session_dump, "table_id <nn>")                               \
19118 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
19119     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
19120     "[template_interval <nn>] [udp_checksum]")                          \
19121 _(ipfix_exporter_dump, "")                                              \
19122 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
19123 _(ipfix_classify_stream_dump, "")                                       \
19124 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
19125 _(ipfix_classify_table_dump, "")                                        \
19126 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
19127 _(sw_interface_span_dump, "")                                           \
19128 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
19129 _(pg_create_interface, "if_id <nn>")                                    \
19130 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
19131 _(pg_enable_disable, "[stream <id>] disable")                           \
19132 _(ip_source_and_port_range_check_add_del,                               \
19133   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
19134 _(ip_source_and_port_range_check_interface_add_del,                     \
19135   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
19136   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
19137 _(ipsec_gre_add_del_tunnel,                                             \
19138   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
19139 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
19140 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
19141 _(l2_interface_pbb_tag_rewrite,                                         \
19142   "<intfc> | sw_if_index <nn> \n"                                       \
19143   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
19144   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
19145 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
19146 _(flow_classify_set_interface,                                          \
19147   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
19148 _(flow_classify_dump, "type [ip4|ip6]")                                 \
19149 _(ip_fib_dump, "")                                                      \
19150 _(ip_mfib_dump, "")                                                     \
19151 _(ip6_fib_dump, "")                                                     \
19152 _(ip6_mfib_dump, "")                                                    \
19153 _(feature_enable_disable, "arc_name <arc_name> "                        \
19154   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
19155 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
19156 "[disable]")                                                            \
19157 _(l2_xconnect_dump, "")                                                 \
19158 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
19159 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
19160 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
19161
19162 /* List of command functions, CLI names map directly to functions */
19163 #define foreach_cli_function                                    \
19164 _(comment, "usage: comment <ignore-rest-of-line>")              \
19165 _(dump_interface_table, "usage: dump_interface_table")          \
19166 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
19167 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
19168 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
19169 _(dump_stats_table, "usage: dump_stats_table")                  \
19170 _(dump_macro_table, "usage: dump_macro_table ")                 \
19171 _(dump_node_table, "usage: dump_node_table")                    \
19172 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
19173 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
19174 _(echo, "usage: echo <message>")                                \
19175 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
19176 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
19177 _(help, "usage: help")                                          \
19178 _(q, "usage: quit")                                             \
19179 _(quit, "usage: quit")                                          \
19180 _(search_node_table, "usage: search_node_table <name>...")      \
19181 _(set, "usage: set <variable-name> <value>")                    \
19182 _(script, "usage: script <file-name>")                          \
19183 _(unset, "usage: unset <variable-name>")
19184
19185 #define _(N,n)                                  \
19186     static void vl_api_##n##_t_handler_uni      \
19187     (vl_api_##n##_t * mp)                       \
19188     {                                           \
19189         vat_main_t * vam = &vat_main;           \
19190         if (vam->json_output) {                 \
19191             vl_api_##n##_t_handler_json(mp);    \
19192         } else {                                \
19193             vl_api_##n##_t_handler(mp);         \
19194         }                                       \
19195     }
19196 foreach_vpe_api_reply_msg;
19197 #if VPP_API_TEST_BUILTIN == 0
19198 foreach_standalone_reply_msg;
19199 #endif
19200 #undef _
19201
19202 void
19203 vat_api_hookup (vat_main_t * vam)
19204 {
19205 #define _(N,n)                                                  \
19206     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
19207                            vl_api_##n##_t_handler_uni,          \
19208                            vl_noop_handler,                     \
19209                            vl_api_##n##_t_endian,               \
19210                            vl_api_##n##_t_print,                \
19211                            sizeof(vl_api_##n##_t), 1);
19212   foreach_vpe_api_reply_msg;
19213 #if VPP_API_TEST_BUILTIN == 0
19214   foreach_standalone_reply_msg;
19215 #endif
19216 #undef _
19217
19218 #if (VPP_API_TEST_BUILTIN==0)
19219   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
19220
19221   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
19222
19223   vam->function_by_name = hash_create_string (0, sizeof (uword));
19224
19225   vam->help_by_name = hash_create_string (0, sizeof (uword));
19226 #endif
19227
19228   /* API messages we can send */
19229 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
19230   foreach_vpe_api_msg;
19231 #undef _
19232
19233   /* Help strings */
19234 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
19235   foreach_vpe_api_msg;
19236 #undef _
19237
19238   /* CLI functions */
19239 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
19240   foreach_cli_function;
19241 #undef _
19242
19243   /* Help strings */
19244 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
19245   foreach_cli_function;
19246 #undef _
19247 }
19248
19249 #if VPP_API_TEST_BUILTIN
19250 static clib_error_t *
19251 vat_api_hookup_shim (vlib_main_t * vm)
19252 {
19253   vat_api_hookup (&vat_main);
19254   return 0;
19255 }
19256
19257 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
19258 #endif
19259
19260 /*
19261  * fd.io coding-style-patch-verification: ON
19262  *
19263  * Local Variables:
19264  * eval: (c-set-style "gnu")
19265  * End:
19266  */