Missing plugin binary API command fns found after brief search
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/l2/l2_input.h>
26 #include <vnet/l2tp/l2tp.h>
27 #include <vnet/vxlan/vxlan.h>
28 #include <vnet/gre/gre.h>
29 #include <vnet/vxlan-gpe/vxlan_gpe.h>
30 #include <vnet/lisp-gpe/lisp_gpe.h>
31
32 #include <vpp/api/vpe_msg_enum.h>
33 #include <vnet/l2/l2_classify.h>
34 #include <vnet/l2/l2_vtr.h>
35 #include <vnet/classify/input_acl.h>
36 #include <vnet/classify/policer_classify.h>
37 #include <vnet/classify/flow_classify.h>
38 #include <vnet/mpls/mpls.h>
39 #include <vnet/ipsec/ipsec.h>
40 #include <vnet/ipsec/ikev2.h>
41 #include <inttypes.h>
42 #include <vnet/map/map.h>
43 #include <vnet/cop/cop.h>
44 #include <vnet/ip/ip6_hop_by_hop.h>
45 #include <vnet/ip/ip_source_and_port_range_check.h>
46 #include <vnet/policer/xlate.h>
47 #include <vnet/span/span.h>
48 #include <vnet/policer/policer.h>
49 #include <vnet/policer/police.h>
50 #include <vnet/mfib/mfib_types.h>
51
52 #include "vat/json_format.h"
53
54 #include <inttypes.h>
55 #include <sys/stat.h>
56
57 #define vl_typedefs             /* define message structures */
58 #include <vpp/api/vpe_all_api_h.h>
59 #undef vl_typedefs
60
61 /* declare message handlers for each api */
62
63 #define vl_endianfun            /* define message structures */
64 #include <vpp/api/vpe_all_api_h.h>
65 #undef vl_endianfun
66
67 /* instantiate all the print functions we know about */
68 #define vl_print(handle, ...)
69 #define vl_printfun
70 #include <vpp/api/vpe_all_api_h.h>
71 #undef vl_printfun
72
73 #define __plugin_msg_base 0
74 #include <vlibapi/vat_helper_macros.h>
75
76 f64
77 vat_time_now (vat_main_t * vam)
78 {
79 #if VPP_API_TEST_BUILTIN
80   return vlib_time_now (vam->vlib_main);
81 #else
82   return clib_time_now (&vam->clib_time);
83 #endif
84 }
85
86 void
87 errmsg (char *fmt, ...)
88 {
89   vat_main_t *vam = &vat_main;
90   va_list va;
91   u8 *s;
92
93   va_start (va, fmt);
94   s = va_format (0, fmt, &va);
95   va_end (va);
96
97   vec_add1 (s, 0);
98
99 #if VPP_API_TEST_BUILTIN
100   vlib_cli_output (vam->vlib_main, (char *) s);
101 #else
102   {
103     if (vam->ifp != stdin)
104       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
105                vam->input_line_number);
106     fformat (vam->ofp, (char *) s);
107     fflush (vam->ofp);
108   }
109 #endif
110
111   vec_free (s);
112 }
113
114 #if VPP_API_TEST_BUILTIN == 0
115 static uword
116 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
117 {
118   vat_main_t *vam = va_arg (*args, vat_main_t *);
119   u32 *result = va_arg (*args, u32 *);
120   u8 *if_name;
121   uword *p;
122
123   if (!unformat (input, "%s", &if_name))
124     return 0;
125
126   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
127   if (p == 0)
128     return 0;
129   *result = p[0];
130   return 1;
131 }
132
133 /* Parse an IP4 address %d.%d.%d.%d. */
134 uword
135 unformat_ip4_address (unformat_input_t * input, va_list * args)
136 {
137   u8 *result = va_arg (*args, u8 *);
138   unsigned a[4];
139
140   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
141     return 0;
142
143   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
144     return 0;
145
146   result[0] = a[0];
147   result[1] = a[1];
148   result[2] = a[2];
149   result[3] = a[3];
150
151   return 1;
152 }
153
154 uword
155 unformat_ethernet_address (unformat_input_t * input, va_list * args)
156 {
157   u8 *result = va_arg (*args, u8 *);
158   u32 i, a[6];
159
160   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
161                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
162     return 0;
163
164   /* Check range. */
165   for (i = 0; i < 6; i++)
166     if (a[i] >= (1 << 8))
167       return 0;
168
169   for (i = 0; i < 6; i++)
170     result[i] = a[i];
171
172   return 1;
173 }
174
175 /* Returns ethernet type as an int in host byte order. */
176 uword
177 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
178                                         va_list * args)
179 {
180   u16 *result = va_arg (*args, u16 *);
181   int type;
182
183   /* Numeric type. */
184   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
185     {
186       if (type >= (1 << 16))
187         return 0;
188       *result = type;
189       return 1;
190     }
191   return 0;
192 }
193
194 /* Parse an IP6 address. */
195 uword
196 unformat_ip6_address (unformat_input_t * input, va_list * args)
197 {
198   ip6_address_t *result = va_arg (*args, ip6_address_t *);
199   u16 hex_quads[8];
200   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
201   uword c, n_colon, double_colon_index;
202
203   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
204   double_colon_index = ARRAY_LEN (hex_quads);
205   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
206     {
207       hex_digit = 16;
208       if (c >= '0' && c <= '9')
209         hex_digit = c - '0';
210       else if (c >= 'a' && c <= 'f')
211         hex_digit = c + 10 - 'a';
212       else if (c >= 'A' && c <= 'F')
213         hex_digit = c + 10 - 'A';
214       else if (c == ':' && n_colon < 2)
215         n_colon++;
216       else
217         {
218           unformat_put_input (input);
219           break;
220         }
221
222       /* Too many hex quads. */
223       if (n_hex_quads >= ARRAY_LEN (hex_quads))
224         return 0;
225
226       if (hex_digit < 16)
227         {
228           hex_quad = (hex_quad << 4) | hex_digit;
229
230           /* Hex quad must fit in 16 bits. */
231           if (n_hex_digits >= 4)
232             return 0;
233
234           n_colon = 0;
235           n_hex_digits++;
236         }
237
238       /* Save position of :: */
239       if (n_colon == 2)
240         {
241           /* More than one :: ? */
242           if (double_colon_index < ARRAY_LEN (hex_quads))
243             return 0;
244           double_colon_index = n_hex_quads;
245         }
246
247       if (n_colon > 0 && n_hex_digits > 0)
248         {
249           hex_quads[n_hex_quads++] = hex_quad;
250           hex_quad = 0;
251           n_hex_digits = 0;
252         }
253     }
254
255   if (n_hex_digits > 0)
256     hex_quads[n_hex_quads++] = hex_quad;
257
258   {
259     word i;
260
261     /* Expand :: to appropriate number of zero hex quads. */
262     if (double_colon_index < ARRAY_LEN (hex_quads))
263       {
264         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
265
266         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
267           hex_quads[n_zero + i] = hex_quads[i];
268
269         for (i = 0; i < n_zero; i++)
270           hex_quads[double_colon_index + i] = 0;
271
272         n_hex_quads = ARRAY_LEN (hex_quads);
273       }
274
275     /* Too few hex quads given. */
276     if (n_hex_quads < ARRAY_LEN (hex_quads))
277       return 0;
278
279     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
280       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
281
282     return 1;
283   }
284 }
285
286 uword
287 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
288 {
289   u32 *r = va_arg (*args, u32 *);
290
291   if (0);
292 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
293   foreach_ipsec_policy_action
294 #undef _
295     else
296     return 0;
297   return 1;
298 }
299
300 uword
301 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
302 {
303   u32 *r = va_arg (*args, u32 *);
304
305   if (0);
306 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
307   foreach_ipsec_crypto_alg
308 #undef _
309     else
310     return 0;
311   return 1;
312 }
313
314 u8 *
315 format_ipsec_crypto_alg (u8 * s, va_list * args)
316 {
317   u32 i = va_arg (*args, u32);
318   u8 *t = 0;
319
320   switch (i)
321     {
322 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
323       foreach_ipsec_crypto_alg
324 #undef _
325     default:
326       return format (s, "unknown");
327     }
328   return format (s, "%s", t);
329 }
330
331 uword
332 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
333 {
334   u32 *r = va_arg (*args, u32 *);
335
336   if (0);
337 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
338   foreach_ipsec_integ_alg
339 #undef _
340     else
341     return 0;
342   return 1;
343 }
344
345 u8 *
346 format_ipsec_integ_alg (u8 * s, va_list * args)
347 {
348   u32 i = va_arg (*args, u32);
349   u8 *t = 0;
350
351   switch (i)
352     {
353 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
354       foreach_ipsec_integ_alg
355 #undef _
356     default:
357       return format (s, "unknown");
358     }
359   return format (s, "%s", t);
360 }
361
362 uword
363 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
364 {
365   u32 *r = va_arg (*args, u32 *);
366
367   if (0);
368 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
369   foreach_ikev2_auth_method
370 #undef _
371     else
372     return 0;
373   return 1;
374 }
375
376 uword
377 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
378 {
379   u32 *r = va_arg (*args, u32 *);
380
381   if (0);
382 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
383   foreach_ikev2_id_type
384 #undef _
385     else
386     return 0;
387   return 1;
388 }
389 #else /* VPP_API_TEST_BUILTIN == 1 */
390 static uword
391 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
392 {
393   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
394   vnet_main_t *vnm = vnet_get_main ();
395   u32 *result = va_arg (*args, u32 *);
396   u32 sw_if_index;
397
398   if (!unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
399     return 0;
400
401   *result = sw_if_index;
402   return 1;
403 }
404 #endif /* VPP_API_TEST_BUILTIN */
405
406 static uword
407 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
408 {
409   u8 *r = va_arg (*args, u8 *);
410
411   if (unformat (input, "kbps"))
412     *r = SSE2_QOS_RATE_KBPS;
413   else if (unformat (input, "pps"))
414     *r = SSE2_QOS_RATE_PPS;
415   else
416     return 0;
417   return 1;
418 }
419
420 static uword
421 unformat_policer_round_type (unformat_input_t * input, va_list * args)
422 {
423   u8 *r = va_arg (*args, u8 *);
424
425   if (unformat (input, "closest"))
426     *r = SSE2_QOS_ROUND_TO_CLOSEST;
427   else if (unformat (input, "up"))
428     *r = SSE2_QOS_ROUND_TO_UP;
429   else if (unformat (input, "down"))
430     *r = SSE2_QOS_ROUND_TO_DOWN;
431   else
432     return 0;
433   return 1;
434 }
435
436 static uword
437 unformat_policer_type (unformat_input_t * input, va_list * args)
438 {
439   u8 *r = va_arg (*args, u8 *);
440
441   if (unformat (input, "1r2c"))
442     *r = SSE2_QOS_POLICER_TYPE_1R2C;
443   else if (unformat (input, "1r3c"))
444     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
445   else if (unformat (input, "2r3c-2698"))
446     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
447   else if (unformat (input, "2r3c-4115"))
448     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
449   else if (unformat (input, "2r3c-mef5cf1"))
450     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
451   else
452     return 0;
453   return 1;
454 }
455
456 static uword
457 unformat_dscp (unformat_input_t * input, va_list * va)
458 {
459   u8 *r = va_arg (*va, u8 *);
460
461   if (0);
462 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
463   foreach_vnet_dscp
464 #undef _
465     else
466     return 0;
467   return 1;
468 }
469
470 static uword
471 unformat_policer_action_type (unformat_input_t * input, va_list * va)
472 {
473   sse2_qos_pol_action_params_st *a
474     = va_arg (*va, sse2_qos_pol_action_params_st *);
475
476   if (unformat (input, "drop"))
477     a->action_type = SSE2_QOS_ACTION_DROP;
478   else if (unformat (input, "transmit"))
479     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
480   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
481     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
482   else
483     return 0;
484   return 1;
485 }
486
487 static uword
488 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
489 {
490   u32 *r = va_arg (*va, u32 *);
491   u32 tid;
492
493   if (unformat (input, "ip4"))
494     tid = POLICER_CLASSIFY_TABLE_IP4;
495   else if (unformat (input, "ip6"))
496     tid = POLICER_CLASSIFY_TABLE_IP6;
497   else if (unformat (input, "l2"))
498     tid = POLICER_CLASSIFY_TABLE_L2;
499   else
500     return 0;
501
502   *r = tid;
503   return 1;
504 }
505
506 static uword
507 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
508 {
509   u32 *r = va_arg (*va, u32 *);
510   u32 tid;
511
512   if (unformat (input, "ip4"))
513     tid = FLOW_CLASSIFY_TABLE_IP4;
514   else if (unformat (input, "ip6"))
515     tid = FLOW_CLASSIFY_TABLE_IP6;
516   else
517     return 0;
518
519   *r = tid;
520   return 1;
521 }
522
523 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
524 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
525 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
526 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
527
528 #if (VPP_API_TEST_BUILTIN==0)
529 uword
530 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
531 {
532   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
533   mfib_itf_attribute_t attr;
534
535   old = *iflags;
536   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
537   {
538     if (unformat (input, mfib_itf_flag_long_names[attr]))
539       *iflags |= (1 << attr);
540   }
541   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
542   {
543     if (unformat (input, mfib_itf_flag_names[attr]))
544       *iflags |= (1 << attr);
545   }
546
547   return (old == *iflags ? 0 : 1);
548 }
549
550 uword
551 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
552 {
553   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
554   mfib_entry_attribute_t attr;
555
556   old = *eflags;
557   FOR_EACH_MFIB_ATTRIBUTE (attr)
558   {
559     if (unformat (input, mfib_flag_long_names[attr]))
560       *eflags |= (1 << attr);
561   }
562   FOR_EACH_MFIB_ATTRIBUTE (attr)
563   {
564     if (unformat (input, mfib_flag_names[attr]))
565       *eflags |= (1 << attr);
566   }
567
568   return (old == *eflags ? 0 : 1);
569 }
570
571 u8 *
572 format_ip4_address (u8 * s, va_list * args)
573 {
574   u8 *a = va_arg (*args, u8 *);
575   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
576 }
577
578 u8 *
579 format_ip6_address (u8 * s, va_list * args)
580 {
581   ip6_address_t *a = va_arg (*args, ip6_address_t *);
582   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
583
584   i_max_n_zero = ARRAY_LEN (a->as_u16);
585   max_n_zeros = 0;
586   i_first_zero = i_max_n_zero;
587   n_zeros = 0;
588   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
589     {
590       u32 is_zero = a->as_u16[i] == 0;
591       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
592         {
593           i_first_zero = i;
594           n_zeros = 0;
595         }
596       n_zeros += is_zero;
597       if ((!is_zero && n_zeros > max_n_zeros)
598           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
599         {
600           i_max_n_zero = i_first_zero;
601           max_n_zeros = n_zeros;
602           i_first_zero = ARRAY_LEN (a->as_u16);
603           n_zeros = 0;
604         }
605     }
606
607   last_double_colon = 0;
608   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
609     {
610       if (i == i_max_n_zero && max_n_zeros > 1)
611         {
612           s = format (s, "::");
613           i += max_n_zeros - 1;
614           last_double_colon = 1;
615         }
616       else
617         {
618           s = format (s, "%s%x",
619                       (last_double_colon || i == 0) ? "" : ":",
620                       clib_net_to_host_u16 (a->as_u16[i]));
621           last_double_colon = 0;
622         }
623     }
624
625   return s;
626 }
627
628 /* Format an IP46 address. */
629 u8 *
630 format_ip46_address (u8 * s, va_list * args)
631 {
632   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
633   ip46_type_t type = va_arg (*args, ip46_type_t);
634   int is_ip4 = 1;
635
636   switch (type)
637     {
638     case IP46_TYPE_ANY:
639       is_ip4 = ip46_address_is_ip4 (ip46);
640       break;
641     case IP46_TYPE_IP4:
642       is_ip4 = 1;
643       break;
644     case IP46_TYPE_IP6:
645       is_ip4 = 0;
646       break;
647     }
648
649   return is_ip4 ?
650     format (s, "%U", format_ip4_address, &ip46->ip4) :
651     format (s, "%U", format_ip6_address, &ip46->ip6);
652 }
653
654 u8 *
655 format_ethernet_address (u8 * s, va_list * args)
656 {
657   u8 *a = va_arg (*args, u8 *);
658
659   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
660                  a[0], a[1], a[2], a[3], a[4], a[5]);
661 }
662 #endif
663
664 static void
665 increment_v4_address (ip4_address_t * a)
666 {
667   u32 v;
668
669   v = ntohl (a->as_u32) + 1;
670   a->as_u32 = ntohl (v);
671 }
672
673 static void
674 increment_v6_address (ip6_address_t * a)
675 {
676   u64 v0, v1;
677
678   v0 = clib_net_to_host_u64 (a->as_u64[0]);
679   v1 = clib_net_to_host_u64 (a->as_u64[1]);
680
681   v1 += 1;
682   if (v1 == 0)
683     v0 += 1;
684   a->as_u64[0] = clib_net_to_host_u64 (v0);
685   a->as_u64[1] = clib_net_to_host_u64 (v1);
686 }
687
688 static void
689 increment_mac_address (u64 * mac)
690 {
691   u64 tmp = *mac;
692
693   tmp = clib_net_to_host_u64 (tmp);
694   tmp += 1 << 16;               /* skip unused (least significant) octets */
695   tmp = clib_host_to_net_u64 (tmp);
696   *mac = tmp;
697 }
698
699 static void vl_api_create_loopback_reply_t_handler
700   (vl_api_create_loopback_reply_t * mp)
701 {
702   vat_main_t *vam = &vat_main;
703   i32 retval = ntohl (mp->retval);
704
705   vam->retval = retval;
706   vam->regenerate_interface_table = 1;
707   vam->sw_if_index = ntohl (mp->sw_if_index);
708   vam->result_ready = 1;
709 }
710
711 static void vl_api_create_loopback_reply_t_handler_json
712   (vl_api_create_loopback_reply_t * mp)
713 {
714   vat_main_t *vam = &vat_main;
715   vat_json_node_t node;
716
717   vat_json_init_object (&node);
718   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
719   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
720
721   vat_json_print (vam->ofp, &node);
722   vat_json_free (&node);
723   vam->retval = ntohl (mp->retval);
724   vam->result_ready = 1;
725 }
726
727 static void vl_api_create_loopback_instance_reply_t_handler
728   (vl_api_create_loopback_instance_reply_t * mp)
729 {
730   vat_main_t *vam = &vat_main;
731   i32 retval = ntohl (mp->retval);
732
733   vam->retval = retval;
734   vam->regenerate_interface_table = 1;
735   vam->sw_if_index = ntohl (mp->sw_if_index);
736   vam->result_ready = 1;
737 }
738
739 static void vl_api_create_loopback_instance_reply_t_handler_json
740   (vl_api_create_loopback_instance_reply_t * mp)
741 {
742   vat_main_t *vam = &vat_main;
743   vat_json_node_t node;
744
745   vat_json_init_object (&node);
746   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
747   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
748
749   vat_json_print (vam->ofp, &node);
750   vat_json_free (&node);
751   vam->retval = ntohl (mp->retval);
752   vam->result_ready = 1;
753 }
754
755 static void vl_api_af_packet_create_reply_t_handler
756   (vl_api_af_packet_create_reply_t * mp)
757 {
758   vat_main_t *vam = &vat_main;
759   i32 retval = ntohl (mp->retval);
760
761   vam->retval = retval;
762   vam->regenerate_interface_table = 1;
763   vam->sw_if_index = ntohl (mp->sw_if_index);
764   vam->result_ready = 1;
765 }
766
767 static void vl_api_af_packet_create_reply_t_handler_json
768   (vl_api_af_packet_create_reply_t * mp)
769 {
770   vat_main_t *vam = &vat_main;
771   vat_json_node_t node;
772
773   vat_json_init_object (&node);
774   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
775   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
776
777   vat_json_print (vam->ofp, &node);
778   vat_json_free (&node);
779
780   vam->retval = ntohl (mp->retval);
781   vam->result_ready = 1;
782 }
783
784 static void vl_api_create_vlan_subif_reply_t_handler
785   (vl_api_create_vlan_subif_reply_t * mp)
786 {
787   vat_main_t *vam = &vat_main;
788   i32 retval = ntohl (mp->retval);
789
790   vam->retval = retval;
791   vam->regenerate_interface_table = 1;
792   vam->sw_if_index = ntohl (mp->sw_if_index);
793   vam->result_ready = 1;
794 }
795
796 static void vl_api_create_vlan_subif_reply_t_handler_json
797   (vl_api_create_vlan_subif_reply_t * mp)
798 {
799   vat_main_t *vam = &vat_main;
800   vat_json_node_t node;
801
802   vat_json_init_object (&node);
803   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
804   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
805
806   vat_json_print (vam->ofp, &node);
807   vat_json_free (&node);
808
809   vam->retval = ntohl (mp->retval);
810   vam->result_ready = 1;
811 }
812
813 static void vl_api_create_subif_reply_t_handler
814   (vl_api_create_subif_reply_t * mp)
815 {
816   vat_main_t *vam = &vat_main;
817   i32 retval = ntohl (mp->retval);
818
819   vam->retval = retval;
820   vam->regenerate_interface_table = 1;
821   vam->sw_if_index = ntohl (mp->sw_if_index);
822   vam->result_ready = 1;
823 }
824
825 static void vl_api_create_subif_reply_t_handler_json
826   (vl_api_create_subif_reply_t * mp)
827 {
828   vat_main_t *vam = &vat_main;
829   vat_json_node_t node;
830
831   vat_json_init_object (&node);
832   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
833   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
834
835   vat_json_print (vam->ofp, &node);
836   vat_json_free (&node);
837
838   vam->retval = ntohl (mp->retval);
839   vam->result_ready = 1;
840 }
841
842 static void vl_api_interface_name_renumber_reply_t_handler
843   (vl_api_interface_name_renumber_reply_t * mp)
844 {
845   vat_main_t *vam = &vat_main;
846   i32 retval = ntohl (mp->retval);
847
848   vam->retval = retval;
849   vam->regenerate_interface_table = 1;
850   vam->result_ready = 1;
851 }
852
853 static void vl_api_interface_name_renumber_reply_t_handler_json
854   (vl_api_interface_name_renumber_reply_t * mp)
855 {
856   vat_main_t *vam = &vat_main;
857   vat_json_node_t node;
858
859   vat_json_init_object (&node);
860   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
861
862   vat_json_print (vam->ofp, &node);
863   vat_json_free (&node);
864
865   vam->retval = ntohl (mp->retval);
866   vam->result_ready = 1;
867 }
868
869 /*
870  * Special-case: build the interface table, maintain
871  * the next loopback sw_if_index vbl.
872  */
873 static void vl_api_sw_interface_details_t_handler
874   (vl_api_sw_interface_details_t * mp)
875 {
876   vat_main_t *vam = &vat_main;
877   u8 *s = format (0, "%s%c", mp->interface_name, 0);
878
879   hash_set_mem (vam->sw_if_index_by_interface_name, s,
880                 ntohl (mp->sw_if_index));
881
882   /* In sub interface case, fill the sub interface table entry */
883   if (mp->sw_if_index != mp->sup_sw_if_index)
884     {
885       sw_interface_subif_t *sub = NULL;
886
887       vec_add2 (vam->sw_if_subif_table, sub, 1);
888
889       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
890       strncpy ((char *) sub->interface_name, (char *) s,
891                vec_len (sub->interface_name));
892       sub->sw_if_index = ntohl (mp->sw_if_index);
893       sub->sub_id = ntohl (mp->sub_id);
894
895       sub->sub_dot1ad = mp->sub_dot1ad;
896       sub->sub_number_of_tags = mp->sub_number_of_tags;
897       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
898       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
899       sub->sub_exact_match = mp->sub_exact_match;
900       sub->sub_default = mp->sub_default;
901       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
902       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
903
904       /* vlan tag rewrite */
905       sub->vtr_op = ntohl (mp->vtr_op);
906       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
907       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
908       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
909     }
910 }
911
912 static void vl_api_sw_interface_details_t_handler_json
913   (vl_api_sw_interface_details_t * mp)
914 {
915   vat_main_t *vam = &vat_main;
916   vat_json_node_t *node = NULL;
917
918   if (VAT_JSON_ARRAY != vam->json_tree.type)
919     {
920       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
921       vat_json_init_array (&vam->json_tree);
922     }
923   node = vat_json_array_add (&vam->json_tree);
924
925   vat_json_init_object (node);
926   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
927   vat_json_object_add_uint (node, "sup_sw_if_index",
928                             ntohl (mp->sup_sw_if_index));
929   vat_json_object_add_uint (node, "l2_address_length",
930                             ntohl (mp->l2_address_length));
931   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
932                              sizeof (mp->l2_address));
933   vat_json_object_add_string_copy (node, "interface_name",
934                                    mp->interface_name);
935   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
936   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
937   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
938   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
939   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
940   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
941   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
942   vat_json_object_add_uint (node, "sub_number_of_tags",
943                             mp->sub_number_of_tags);
944   vat_json_object_add_uint (node, "sub_outer_vlan_id",
945                             ntohs (mp->sub_outer_vlan_id));
946   vat_json_object_add_uint (node, "sub_inner_vlan_id",
947                             ntohs (mp->sub_inner_vlan_id));
948   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
949   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
950   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
951                             mp->sub_outer_vlan_id_any);
952   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
953                             mp->sub_inner_vlan_id_any);
954   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
955   vat_json_object_add_uint (node, "vtr_push_dot1q",
956                             ntohl (mp->vtr_push_dot1q));
957   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
958   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
959   if (mp->sub_dot1ah)
960     {
961       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
962                                        format (0, "%U",
963                                                format_ethernet_address,
964                                                &mp->b_dmac));
965       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
966                                        format (0, "%U",
967                                                format_ethernet_address,
968                                                &mp->b_smac));
969       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
970       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
971     }
972 }
973
974 #if VPP_API_TEST_BUILTIN == 0
975 static void vl_api_sw_interface_set_flags_t_handler
976   (vl_api_sw_interface_set_flags_t * mp)
977 {
978   vat_main_t *vam = &vat_main;
979   if (vam->interface_event_display)
980     errmsg ("interface flags: sw_if_index %d %s %s",
981             ntohl (mp->sw_if_index),
982             mp->admin_up_down ? "admin-up" : "admin-down",
983             mp->link_up_down ? "link-up" : "link-down");
984 }
985 #endif
986
987 static void vl_api_sw_interface_set_flags_t_handler_json
988   (vl_api_sw_interface_set_flags_t * mp)
989 {
990   /* JSON output not supported */
991 }
992
993 static void
994 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
995 {
996   vat_main_t *vam = &vat_main;
997   i32 retval = ntohl (mp->retval);
998
999   vam->retval = retval;
1000   vam->shmem_result = (u8 *) mp->reply_in_shmem;
1001   vam->result_ready = 1;
1002 }
1003
1004 static void
1005 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1006 {
1007   vat_main_t *vam = &vat_main;
1008   vat_json_node_t node;
1009   api_main_t *am = &api_main;
1010   void *oldheap;
1011   u8 *reply;
1012
1013   vat_json_init_object (&node);
1014   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1015   vat_json_object_add_uint (&node, "reply_in_shmem",
1016                             ntohl (mp->reply_in_shmem));
1017   /* Toss the shared-memory original... */
1018   pthread_mutex_lock (&am->vlib_rp->mutex);
1019   oldheap = svm_push_data_heap (am->vlib_rp);
1020
1021   reply = (u8 *) (mp->reply_in_shmem);
1022   vec_free (reply);
1023
1024   svm_pop_heap (oldheap);
1025   pthread_mutex_unlock (&am->vlib_rp->mutex);
1026
1027   vat_json_print (vam->ofp, &node);
1028   vat_json_free (&node);
1029
1030   vam->retval = ntohl (mp->retval);
1031   vam->result_ready = 1;
1032 }
1033
1034 static void
1035 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1036 {
1037   vat_main_t *vam = &vat_main;
1038   i32 retval = ntohl (mp->retval);
1039
1040   vam->retval = retval;
1041   vam->cmd_reply = mp->reply;
1042   vam->result_ready = 1;
1043 }
1044
1045 static void
1046 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1047 {
1048   vat_main_t *vam = &vat_main;
1049   vat_json_node_t node;
1050
1051   vat_json_init_object (&node);
1052   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1053   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1054
1055   vat_json_print (vam->ofp, &node);
1056   vat_json_free (&node);
1057
1058   vam->retval = ntohl (mp->retval);
1059   vam->result_ready = 1;
1060 }
1061
1062 static void vl_api_classify_add_del_table_reply_t_handler
1063   (vl_api_classify_add_del_table_reply_t * mp)
1064 {
1065   vat_main_t *vam = &vat_main;
1066   i32 retval = ntohl (mp->retval);
1067   if (vam->async_mode)
1068     {
1069       vam->async_errors += (retval < 0);
1070     }
1071   else
1072     {
1073       vam->retval = retval;
1074       if (retval == 0 &&
1075           ((mp->new_table_index != 0xFFFFFFFF) ||
1076            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1077            (mp->match_n_vectors != 0xFFFFFFFF)))
1078         /*
1079          * Note: this is just barely thread-safe, depends on
1080          * the main thread spinning waiting for an answer...
1081          */
1082         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1083                 ntohl (mp->new_table_index),
1084                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1085       vam->result_ready = 1;
1086     }
1087 }
1088
1089 static void vl_api_classify_add_del_table_reply_t_handler_json
1090   (vl_api_classify_add_del_table_reply_t * mp)
1091 {
1092   vat_main_t *vam = &vat_main;
1093   vat_json_node_t node;
1094
1095   vat_json_init_object (&node);
1096   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1097   vat_json_object_add_uint (&node, "new_table_index",
1098                             ntohl (mp->new_table_index));
1099   vat_json_object_add_uint (&node, "skip_n_vectors",
1100                             ntohl (mp->skip_n_vectors));
1101   vat_json_object_add_uint (&node, "match_n_vectors",
1102                             ntohl (mp->match_n_vectors));
1103
1104   vat_json_print (vam->ofp, &node);
1105   vat_json_free (&node);
1106
1107   vam->retval = ntohl (mp->retval);
1108   vam->result_ready = 1;
1109 }
1110
1111 static void vl_api_get_node_index_reply_t_handler
1112   (vl_api_get_node_index_reply_t * mp)
1113 {
1114   vat_main_t *vam = &vat_main;
1115   i32 retval = ntohl (mp->retval);
1116   if (vam->async_mode)
1117     {
1118       vam->async_errors += (retval < 0);
1119     }
1120   else
1121     {
1122       vam->retval = retval;
1123       if (retval == 0)
1124         errmsg ("node index %d", ntohl (mp->node_index));
1125       vam->result_ready = 1;
1126     }
1127 }
1128
1129 static void vl_api_get_node_index_reply_t_handler_json
1130   (vl_api_get_node_index_reply_t * mp)
1131 {
1132   vat_main_t *vam = &vat_main;
1133   vat_json_node_t node;
1134
1135   vat_json_init_object (&node);
1136   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1137   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1138
1139   vat_json_print (vam->ofp, &node);
1140   vat_json_free (&node);
1141
1142   vam->retval = ntohl (mp->retval);
1143   vam->result_ready = 1;
1144 }
1145
1146 static void vl_api_get_next_index_reply_t_handler
1147   (vl_api_get_next_index_reply_t * mp)
1148 {
1149   vat_main_t *vam = &vat_main;
1150   i32 retval = ntohl (mp->retval);
1151   if (vam->async_mode)
1152     {
1153       vam->async_errors += (retval < 0);
1154     }
1155   else
1156     {
1157       vam->retval = retval;
1158       if (retval == 0)
1159         errmsg ("next node index %d", ntohl (mp->next_index));
1160       vam->result_ready = 1;
1161     }
1162 }
1163
1164 static void vl_api_get_next_index_reply_t_handler_json
1165   (vl_api_get_next_index_reply_t * mp)
1166 {
1167   vat_main_t *vam = &vat_main;
1168   vat_json_node_t node;
1169
1170   vat_json_init_object (&node);
1171   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1172   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1173
1174   vat_json_print (vam->ofp, &node);
1175   vat_json_free (&node);
1176
1177   vam->retval = ntohl (mp->retval);
1178   vam->result_ready = 1;
1179 }
1180
1181 static void vl_api_add_node_next_reply_t_handler
1182   (vl_api_add_node_next_reply_t * mp)
1183 {
1184   vat_main_t *vam = &vat_main;
1185   i32 retval = ntohl (mp->retval);
1186   if (vam->async_mode)
1187     {
1188       vam->async_errors += (retval < 0);
1189     }
1190   else
1191     {
1192       vam->retval = retval;
1193       if (retval == 0)
1194         errmsg ("next index %d", ntohl (mp->next_index));
1195       vam->result_ready = 1;
1196     }
1197 }
1198
1199 static void vl_api_add_node_next_reply_t_handler_json
1200   (vl_api_add_node_next_reply_t * mp)
1201 {
1202   vat_main_t *vam = &vat_main;
1203   vat_json_node_t node;
1204
1205   vat_json_init_object (&node);
1206   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1207   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1208
1209   vat_json_print (vam->ofp, &node);
1210   vat_json_free (&node);
1211
1212   vam->retval = ntohl (mp->retval);
1213   vam->result_ready = 1;
1214 }
1215
1216 static void vl_api_show_version_reply_t_handler
1217   (vl_api_show_version_reply_t * mp)
1218 {
1219   vat_main_t *vam = &vat_main;
1220   i32 retval = ntohl (mp->retval);
1221
1222   if (retval >= 0)
1223     {
1224       errmsg ("        program: %s", mp->program);
1225       errmsg ("        version: %s", mp->version);
1226       errmsg ("     build date: %s", mp->build_date);
1227       errmsg ("build directory: %s", mp->build_directory);
1228     }
1229   vam->retval = retval;
1230   vam->result_ready = 1;
1231 }
1232
1233 static void vl_api_show_version_reply_t_handler_json
1234   (vl_api_show_version_reply_t * mp)
1235 {
1236   vat_main_t *vam = &vat_main;
1237   vat_json_node_t node;
1238
1239   vat_json_init_object (&node);
1240   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1241   vat_json_object_add_string_copy (&node, "program", mp->program);
1242   vat_json_object_add_string_copy (&node, "version", mp->version);
1243   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1244   vat_json_object_add_string_copy (&node, "build_directory",
1245                                    mp->build_directory);
1246
1247   vat_json_print (vam->ofp, &node);
1248   vat_json_free (&node);
1249
1250   vam->retval = ntohl (mp->retval);
1251   vam->result_ready = 1;
1252 }
1253
1254 static void
1255 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1256 {
1257   u32 sw_if_index = ntohl (mp->sw_if_index);
1258   errmsg ("arp %s event: address %U new mac %U sw_if_index %d",
1259           mp->mac_ip ? "mac/ip binding" : "address resolution",
1260           format_ip4_address, &mp->address,
1261           format_ethernet_address, mp->new_mac, sw_if_index);
1262 }
1263
1264 static void
1265 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1266 {
1267   /* JSON output not supported */
1268 }
1269
1270 static void
1271 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1272 {
1273   u32 sw_if_index = ntohl (mp->sw_if_index);
1274   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d",
1275           mp->mac_ip ? "mac/ip binding" : "address resolution",
1276           format_ip6_address, mp->address,
1277           format_ethernet_address, mp->new_mac, sw_if_index);
1278 }
1279
1280 static void
1281 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1282 {
1283   /* JSON output not supported */
1284 }
1285
1286 /*
1287  * Special-case: build the bridge domain table, maintain
1288  * the next bd id vbl.
1289  */
1290 static void vl_api_bridge_domain_details_t_handler
1291   (vl_api_bridge_domain_details_t * mp)
1292 {
1293   vat_main_t *vam = &vat_main;
1294   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1295
1296   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1297          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1298
1299   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1300          ntohl (mp->bd_id), mp->learn, mp->forward,
1301          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1302
1303   if (n_sw_ifs)
1304     print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG", "Interface Name");
1305 }
1306
1307 static void vl_api_bridge_domain_details_t_handler_json
1308   (vl_api_bridge_domain_details_t * mp)
1309 {
1310   vat_main_t *vam = &vat_main;
1311   vat_json_node_t *node, *array = NULL;
1312
1313   if (VAT_JSON_ARRAY != vam->json_tree.type)
1314     {
1315       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1316       vat_json_init_array (&vam->json_tree);
1317     }
1318   node = vat_json_array_add (&vam->json_tree);
1319
1320   vat_json_init_object (node);
1321   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1322   vat_json_object_add_uint (node, "flood", mp->flood);
1323   vat_json_object_add_uint (node, "forward", mp->forward);
1324   vat_json_object_add_uint (node, "learn", mp->learn);
1325   vat_json_object_add_uint (node, "bvi_sw_if_index",
1326                             ntohl (mp->bvi_sw_if_index));
1327   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1328   array = vat_json_object_add (node, "sw_if");
1329   vat_json_init_array (array);
1330 }
1331
1332 /*
1333  * Special-case: build the bridge domain sw if table.
1334  */
1335 static void vl_api_bridge_domain_sw_if_details_t_handler
1336   (vl_api_bridge_domain_sw_if_details_t * mp)
1337 {
1338   vat_main_t *vam = &vat_main;
1339   hash_pair_t *p;
1340   u8 *sw_if_name = 0;
1341   u32 sw_if_index;
1342
1343   sw_if_index = ntohl (mp->sw_if_index);
1344   /* *INDENT-OFF* */
1345   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1346   ({
1347     if ((u32) p->value[0] == sw_if_index)
1348       {
1349         sw_if_name = (u8 *)(p->key);
1350         break;
1351       }
1352   }));
1353   /* *INDENT-ON* */
1354
1355   print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1356          mp->shg, sw_if_name ? (char *) sw_if_name :
1357          "sw_if_index not found!");
1358 }
1359
1360 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1361   (vl_api_bridge_domain_sw_if_details_t * mp)
1362 {
1363   vat_main_t *vam = &vat_main;
1364   vat_json_node_t *node = NULL;
1365   uword last_index = 0;
1366
1367   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1368   ASSERT (vec_len (vam->json_tree.array) >= 1);
1369   last_index = vec_len (vam->json_tree.array) - 1;
1370   node = &vam->json_tree.array[last_index];
1371   node = vat_json_object_get_element (node, "sw_if");
1372   ASSERT (NULL != node);
1373   node = vat_json_array_add (node);
1374
1375   vat_json_init_object (node);
1376   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1377   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1378   vat_json_object_add_uint (node, "shg", mp->shg);
1379 }
1380
1381 static void vl_api_control_ping_reply_t_handler
1382   (vl_api_control_ping_reply_t * mp)
1383 {
1384   vat_main_t *vam = &vat_main;
1385   i32 retval = ntohl (mp->retval);
1386   if (vam->async_mode)
1387     {
1388       vam->async_errors += (retval < 0);
1389     }
1390   else
1391     {
1392       vam->retval = retval;
1393       vam->result_ready = 1;
1394     }
1395 }
1396
1397 static void vl_api_control_ping_reply_t_handler_json
1398   (vl_api_control_ping_reply_t * mp)
1399 {
1400   vat_main_t *vam = &vat_main;
1401   i32 retval = ntohl (mp->retval);
1402
1403   if (VAT_JSON_NONE != vam->json_tree.type)
1404     {
1405       vat_json_print (vam->ofp, &vam->json_tree);
1406       vat_json_free (&vam->json_tree);
1407       vam->json_tree.type = VAT_JSON_NONE;
1408     }
1409   else
1410     {
1411       /* just print [] */
1412       vat_json_init_array (&vam->json_tree);
1413       vat_json_print (vam->ofp, &vam->json_tree);
1414       vam->json_tree.type = VAT_JSON_NONE;
1415     }
1416
1417   vam->retval = retval;
1418   vam->result_ready = 1;
1419 }
1420
1421 static void
1422 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1423 {
1424   vat_main_t *vam = &vat_main;
1425   i32 retval = ntohl (mp->retval);
1426   if (vam->async_mode)
1427     {
1428       vam->async_errors += (retval < 0);
1429     }
1430   else
1431     {
1432       vam->retval = retval;
1433       vam->result_ready = 1;
1434     }
1435 }
1436
1437 static void vl_api_l2_flags_reply_t_handler_json
1438   (vl_api_l2_flags_reply_t * mp)
1439 {
1440   vat_main_t *vam = &vat_main;
1441   vat_json_node_t node;
1442
1443   vat_json_init_object (&node);
1444   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1445   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1446                             ntohl (mp->resulting_feature_bitmap));
1447
1448   vat_json_print (vam->ofp, &node);
1449   vat_json_free (&node);
1450
1451   vam->retval = ntohl (mp->retval);
1452   vam->result_ready = 1;
1453 }
1454
1455 static void vl_api_bridge_flags_reply_t_handler
1456   (vl_api_bridge_flags_reply_t * mp)
1457 {
1458   vat_main_t *vam = &vat_main;
1459   i32 retval = ntohl (mp->retval);
1460   if (vam->async_mode)
1461     {
1462       vam->async_errors += (retval < 0);
1463     }
1464   else
1465     {
1466       vam->retval = retval;
1467       vam->result_ready = 1;
1468     }
1469 }
1470
1471 static void vl_api_bridge_flags_reply_t_handler_json
1472   (vl_api_bridge_flags_reply_t * mp)
1473 {
1474   vat_main_t *vam = &vat_main;
1475   vat_json_node_t node;
1476
1477   vat_json_init_object (&node);
1478   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1479   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1480                             ntohl (mp->resulting_feature_bitmap));
1481
1482   vat_json_print (vam->ofp, &node);
1483   vat_json_free (&node);
1484
1485   vam->retval = ntohl (mp->retval);
1486   vam->result_ready = 1;
1487 }
1488
1489 static void vl_api_tap_connect_reply_t_handler
1490   (vl_api_tap_connect_reply_t * mp)
1491 {
1492   vat_main_t *vam = &vat_main;
1493   i32 retval = ntohl (mp->retval);
1494   if (vam->async_mode)
1495     {
1496       vam->async_errors += (retval < 0);
1497     }
1498   else
1499     {
1500       vam->retval = retval;
1501       vam->sw_if_index = ntohl (mp->sw_if_index);
1502       vam->result_ready = 1;
1503     }
1504
1505 }
1506
1507 static void vl_api_tap_connect_reply_t_handler_json
1508   (vl_api_tap_connect_reply_t * mp)
1509 {
1510   vat_main_t *vam = &vat_main;
1511   vat_json_node_t node;
1512
1513   vat_json_init_object (&node);
1514   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1515   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1516
1517   vat_json_print (vam->ofp, &node);
1518   vat_json_free (&node);
1519
1520   vam->retval = ntohl (mp->retval);
1521   vam->result_ready = 1;
1522
1523 }
1524
1525 static void
1526 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1527 {
1528   vat_main_t *vam = &vat_main;
1529   i32 retval = ntohl (mp->retval);
1530   if (vam->async_mode)
1531     {
1532       vam->async_errors += (retval < 0);
1533     }
1534   else
1535     {
1536       vam->retval = retval;
1537       vam->sw_if_index = ntohl (mp->sw_if_index);
1538       vam->result_ready = 1;
1539     }
1540 }
1541
1542 static void vl_api_tap_modify_reply_t_handler_json
1543   (vl_api_tap_modify_reply_t * mp)
1544 {
1545   vat_main_t *vam = &vat_main;
1546   vat_json_node_t node;
1547
1548   vat_json_init_object (&node);
1549   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1550   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1551
1552   vat_json_print (vam->ofp, &node);
1553   vat_json_free (&node);
1554
1555   vam->retval = ntohl (mp->retval);
1556   vam->result_ready = 1;
1557 }
1558
1559 static void
1560 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1561 {
1562   vat_main_t *vam = &vat_main;
1563   i32 retval = ntohl (mp->retval);
1564   if (vam->async_mode)
1565     {
1566       vam->async_errors += (retval < 0);
1567     }
1568   else
1569     {
1570       vam->retval = retval;
1571       vam->result_ready = 1;
1572     }
1573 }
1574
1575 static void vl_api_tap_delete_reply_t_handler_json
1576   (vl_api_tap_delete_reply_t * mp)
1577 {
1578   vat_main_t *vam = &vat_main;
1579   vat_json_node_t node;
1580
1581   vat_json_init_object (&node);
1582   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1583
1584   vat_json_print (vam->ofp, &node);
1585   vat_json_free (&node);
1586
1587   vam->retval = ntohl (mp->retval);
1588   vam->result_ready = 1;
1589 }
1590
1591 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1592   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1593 {
1594   vat_main_t *vam = &vat_main;
1595   i32 retval = ntohl (mp->retval);
1596   if (vam->async_mode)
1597     {
1598       vam->async_errors += (retval < 0);
1599     }
1600   else
1601     {
1602       vam->retval = retval;
1603       vam->result_ready = 1;
1604     }
1605 }
1606
1607 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1608   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1609 {
1610   vat_main_t *vam = &vat_main;
1611   vat_json_node_t node;
1612
1613   vat_json_init_object (&node);
1614   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1615   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1616                             ntohl (mp->sw_if_index));
1617
1618   vat_json_print (vam->ofp, &node);
1619   vat_json_free (&node);
1620
1621   vam->retval = ntohl (mp->retval);
1622   vam->result_ready = 1;
1623 }
1624
1625 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1626   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1627 {
1628   vat_main_t *vam = &vat_main;
1629   i32 retval = ntohl (mp->retval);
1630   if (vam->async_mode)
1631     {
1632       vam->async_errors += (retval < 0);
1633     }
1634   else
1635     {
1636       vam->retval = retval;
1637       vam->sw_if_index = ntohl (mp->sw_if_index);
1638       vam->result_ready = 1;
1639     }
1640 }
1641
1642 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1643   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1644 {
1645   vat_main_t *vam = &vat_main;
1646   vat_json_node_t node;
1647
1648   vat_json_init_object (&node);
1649   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1650   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1651
1652   vat_json_print (vam->ofp, &node);
1653   vat_json_free (&node);
1654
1655   vam->retval = ntohl (mp->retval);
1656   vam->result_ready = 1;
1657 }
1658
1659
1660 static void vl_api_one_add_del_locator_set_reply_t_handler
1661   (vl_api_one_add_del_locator_set_reply_t * mp)
1662 {
1663   vat_main_t *vam = &vat_main;
1664   i32 retval = ntohl (mp->retval);
1665   if (vam->async_mode)
1666     {
1667       vam->async_errors += (retval < 0);
1668     }
1669   else
1670     {
1671       vam->retval = retval;
1672       vam->result_ready = 1;
1673     }
1674 }
1675
1676 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1677   (vl_api_one_add_del_locator_set_reply_t * mp)
1678 {
1679   vat_main_t *vam = &vat_main;
1680   vat_json_node_t node;
1681
1682   vat_json_init_object (&node);
1683   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1684   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1685
1686   vat_json_print (vam->ofp, &node);
1687   vat_json_free (&node);
1688
1689   vam->retval = ntohl (mp->retval);
1690   vam->result_ready = 1;
1691 }
1692
1693 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1694   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1695 {
1696   vat_main_t *vam = &vat_main;
1697   i32 retval = ntohl (mp->retval);
1698   if (vam->async_mode)
1699     {
1700       vam->async_errors += (retval < 0);
1701     }
1702   else
1703     {
1704       vam->retval = retval;
1705       vam->sw_if_index = ntohl (mp->sw_if_index);
1706       vam->result_ready = 1;
1707     }
1708 }
1709
1710 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1711   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1712 {
1713   vat_main_t *vam = &vat_main;
1714   vat_json_node_t node;
1715
1716   vat_json_init_object (&node);
1717   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1718   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1719
1720   vat_json_print (vam->ofp, &node);
1721   vat_json_free (&node);
1722
1723   vam->retval = ntohl (mp->retval);
1724   vam->result_ready = 1;
1725 }
1726
1727 static void vl_api_gre_add_del_tunnel_reply_t_handler
1728   (vl_api_gre_add_del_tunnel_reply_t * mp)
1729 {
1730   vat_main_t *vam = &vat_main;
1731   i32 retval = ntohl (mp->retval);
1732   if (vam->async_mode)
1733     {
1734       vam->async_errors += (retval < 0);
1735     }
1736   else
1737     {
1738       vam->retval = retval;
1739       vam->sw_if_index = ntohl (mp->sw_if_index);
1740       vam->result_ready = 1;
1741     }
1742 }
1743
1744 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1745   (vl_api_gre_add_del_tunnel_reply_t * mp)
1746 {
1747   vat_main_t *vam = &vat_main;
1748   vat_json_node_t node;
1749
1750   vat_json_init_object (&node);
1751   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1752   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1753
1754   vat_json_print (vam->ofp, &node);
1755   vat_json_free (&node);
1756
1757   vam->retval = ntohl (mp->retval);
1758   vam->result_ready = 1;
1759 }
1760
1761 static void vl_api_create_vhost_user_if_reply_t_handler
1762   (vl_api_create_vhost_user_if_reply_t * mp)
1763 {
1764   vat_main_t *vam = &vat_main;
1765   i32 retval = ntohl (mp->retval);
1766   if (vam->async_mode)
1767     {
1768       vam->async_errors += (retval < 0);
1769     }
1770   else
1771     {
1772       vam->retval = retval;
1773       vam->sw_if_index = ntohl (mp->sw_if_index);
1774       vam->result_ready = 1;
1775     }
1776 }
1777
1778 static void vl_api_create_vhost_user_if_reply_t_handler_json
1779   (vl_api_create_vhost_user_if_reply_t * mp)
1780 {
1781   vat_main_t *vam = &vat_main;
1782   vat_json_node_t node;
1783
1784   vat_json_init_object (&node);
1785   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1786   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1787
1788   vat_json_print (vam->ofp, &node);
1789   vat_json_free (&node);
1790
1791   vam->retval = ntohl (mp->retval);
1792   vam->result_ready = 1;
1793 }
1794
1795 static void vl_api_ip_address_details_t_handler
1796   (vl_api_ip_address_details_t * mp)
1797 {
1798   vat_main_t *vam = &vat_main;
1799   static ip_address_details_t empty_ip_address_details = { {0} };
1800   ip_address_details_t *address = NULL;
1801   ip_details_t *current_ip_details = NULL;
1802   ip_details_t *details = NULL;
1803
1804   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1805
1806   if (!details || vam->current_sw_if_index >= vec_len (details)
1807       || !details[vam->current_sw_if_index].present)
1808     {
1809       errmsg ("ip address details arrived but not stored");
1810       errmsg ("ip_dump should be called first");
1811       return;
1812     }
1813
1814   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1815
1816 #define addresses (current_ip_details->addr)
1817
1818   vec_validate_init_empty (addresses, vec_len (addresses),
1819                            empty_ip_address_details);
1820
1821   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1822
1823   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1824   address->prefix_length = mp->prefix_length;
1825 #undef addresses
1826 }
1827
1828 static void vl_api_ip_address_details_t_handler_json
1829   (vl_api_ip_address_details_t * mp)
1830 {
1831   vat_main_t *vam = &vat_main;
1832   vat_json_node_t *node = NULL;
1833   struct in6_addr ip6;
1834   struct in_addr ip4;
1835
1836   if (VAT_JSON_ARRAY != vam->json_tree.type)
1837     {
1838       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1839       vat_json_init_array (&vam->json_tree);
1840     }
1841   node = vat_json_array_add (&vam->json_tree);
1842
1843   vat_json_init_object (node);
1844   if (vam->is_ipv6)
1845     {
1846       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1847       vat_json_object_add_ip6 (node, "ip", ip6);
1848     }
1849   else
1850     {
1851       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1852       vat_json_object_add_ip4 (node, "ip", ip4);
1853     }
1854   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1855 }
1856
1857 static void
1858 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1859 {
1860   vat_main_t *vam = &vat_main;
1861   static ip_details_t empty_ip_details = { 0 };
1862   ip_details_t *ip = NULL;
1863   u32 sw_if_index = ~0;
1864
1865   sw_if_index = ntohl (mp->sw_if_index);
1866
1867   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1868                            sw_if_index, empty_ip_details);
1869
1870   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1871                          sw_if_index);
1872
1873   ip->present = 1;
1874 }
1875
1876 static void
1877 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1878 {
1879   vat_main_t *vam = &vat_main;
1880
1881   if (VAT_JSON_ARRAY != vam->json_tree.type)
1882     {
1883       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1884       vat_json_init_array (&vam->json_tree);
1885     }
1886   vat_json_array_add_uint (&vam->json_tree,
1887                            clib_net_to_host_u32 (mp->sw_if_index));
1888 }
1889
1890 static void vl_api_map_domain_details_t_handler_json
1891   (vl_api_map_domain_details_t * mp)
1892 {
1893   vat_json_node_t *node = NULL;
1894   vat_main_t *vam = &vat_main;
1895   struct in6_addr ip6;
1896   struct in_addr ip4;
1897
1898   if (VAT_JSON_ARRAY != vam->json_tree.type)
1899     {
1900       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1901       vat_json_init_array (&vam->json_tree);
1902     }
1903
1904   node = vat_json_array_add (&vam->json_tree);
1905   vat_json_init_object (node);
1906
1907   vat_json_object_add_uint (node, "domain_index",
1908                             clib_net_to_host_u32 (mp->domain_index));
1909   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1910   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1911   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1912   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1913   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1914   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1915   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1916   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1917   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1918   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1919   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1920   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1921   vat_json_object_add_uint (node, "flags", mp->flags);
1922   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1923   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1924 }
1925
1926 static void vl_api_map_domain_details_t_handler
1927   (vl_api_map_domain_details_t * mp)
1928 {
1929   vat_main_t *vam = &vat_main;
1930
1931   if (mp->is_translation)
1932     {
1933       print (vam->ofp,
1934              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
1935              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1936              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1937              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1938              clib_net_to_host_u32 (mp->domain_index));
1939     }
1940   else
1941     {
1942       print (vam->ofp,
1943              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
1944              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1945              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1946              format_ip6_address, mp->ip6_src,
1947              clib_net_to_host_u32 (mp->domain_index));
1948     }
1949   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
1950          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1951          mp->is_translation ? "map-t" : "");
1952 }
1953
1954 static void vl_api_map_rule_details_t_handler_json
1955   (vl_api_map_rule_details_t * mp)
1956 {
1957   struct in6_addr ip6;
1958   vat_json_node_t *node = NULL;
1959   vat_main_t *vam = &vat_main;
1960
1961   if (VAT_JSON_ARRAY != vam->json_tree.type)
1962     {
1963       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1964       vat_json_init_array (&vam->json_tree);
1965     }
1966
1967   node = vat_json_array_add (&vam->json_tree);
1968   vat_json_init_object (node);
1969
1970   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1971   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1972   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1973 }
1974
1975 static void
1976 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1977 {
1978   vat_main_t *vam = &vat_main;
1979   print (vam->ofp, " %d (psid) %U (ip6-dst)",
1980          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1981 }
1982
1983 static void
1984 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1985 {
1986   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1987           "router_addr %U host_mac %U",
1988           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1989           format_ip4_address, &mp->host_address,
1990           format_ip4_address, &mp->router_address,
1991           format_ethernet_address, mp->host_mac);
1992 }
1993
1994 static void vl_api_dhcp_compl_event_t_handler_json
1995   (vl_api_dhcp_compl_event_t * mp)
1996 {
1997   /* JSON output not supported */
1998 }
1999
2000 static void
2001 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2002                               u32 counter)
2003 {
2004   vat_main_t *vam = &vat_main;
2005   static u64 default_counter = 0;
2006
2007   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2008                            NULL);
2009   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2010                            sw_if_index, default_counter);
2011   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2012 }
2013
2014 static void
2015 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2016                                 interface_counter_t counter)
2017 {
2018   vat_main_t *vam = &vat_main;
2019   static interface_counter_t default_counter = { 0, };
2020
2021   vec_validate_init_empty (vam->combined_interface_counters,
2022                            vnet_counter_type, NULL);
2023   vec_validate_init_empty (vam->combined_interface_counters
2024                            [vnet_counter_type], sw_if_index, default_counter);
2025   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2026 }
2027
2028 static void vl_api_vnet_interface_counters_t_handler
2029   (vl_api_vnet_interface_counters_t * mp)
2030 {
2031   /* not supported */
2032 }
2033
2034 static void vl_api_vnet_interface_counters_t_handler_json
2035   (vl_api_vnet_interface_counters_t * mp)
2036 {
2037   interface_counter_t counter;
2038   vlib_counter_t *v;
2039   u64 *v_packets;
2040   u64 packets;
2041   u32 count;
2042   u32 first_sw_if_index;
2043   int i;
2044
2045   count = ntohl (mp->count);
2046   first_sw_if_index = ntohl (mp->first_sw_if_index);
2047
2048   if (!mp->is_combined)
2049     {
2050       v_packets = (u64 *) & mp->data;
2051       for (i = 0; i < count; i++)
2052         {
2053           packets =
2054             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2055           set_simple_interface_counter (mp->vnet_counter_type,
2056                                         first_sw_if_index + i, packets);
2057           v_packets++;
2058         }
2059     }
2060   else
2061     {
2062       v = (vlib_counter_t *) & mp->data;
2063       for (i = 0; i < count; i++)
2064         {
2065           counter.packets =
2066             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2067           counter.bytes =
2068             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2069           set_combined_interface_counter (mp->vnet_counter_type,
2070                                           first_sw_if_index + i, counter);
2071           v++;
2072         }
2073     }
2074 }
2075
2076 static u32
2077 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2078 {
2079   vat_main_t *vam = &vat_main;
2080   u32 i;
2081
2082   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2083     {
2084       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2085         {
2086           return i;
2087         }
2088     }
2089   return ~0;
2090 }
2091
2092 static u32
2093 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2094 {
2095   vat_main_t *vam = &vat_main;
2096   u32 i;
2097
2098   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2099     {
2100       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2101         {
2102           return i;
2103         }
2104     }
2105   return ~0;
2106 }
2107
2108 static void vl_api_vnet_ip4_fib_counters_t_handler
2109   (vl_api_vnet_ip4_fib_counters_t * mp)
2110 {
2111   /* not supported */
2112 }
2113
2114 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2115   (vl_api_vnet_ip4_fib_counters_t * mp)
2116 {
2117   vat_main_t *vam = &vat_main;
2118   vl_api_ip4_fib_counter_t *v;
2119   ip4_fib_counter_t *counter;
2120   struct in_addr ip4;
2121   u32 vrf_id;
2122   u32 vrf_index;
2123   u32 count;
2124   int i;
2125
2126   vrf_id = ntohl (mp->vrf_id);
2127   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2128   if (~0 == vrf_index)
2129     {
2130       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2131       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2132       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2133       vec_validate (vam->ip4_fib_counters, vrf_index);
2134       vam->ip4_fib_counters[vrf_index] = NULL;
2135     }
2136
2137   vec_free (vam->ip4_fib_counters[vrf_index]);
2138   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2139   count = ntohl (mp->count);
2140   for (i = 0; i < count; i++)
2141     {
2142       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2143       counter = &vam->ip4_fib_counters[vrf_index][i];
2144       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2145       counter->address = ip4;
2146       counter->address_length = v->address_length;
2147       counter->packets = clib_net_to_host_u64 (v->packets);
2148       counter->bytes = clib_net_to_host_u64 (v->bytes);
2149       v++;
2150     }
2151 }
2152
2153 static void vl_api_vnet_ip4_nbr_counters_t_handler
2154   (vl_api_vnet_ip4_nbr_counters_t * mp)
2155 {
2156   /* not supported */
2157 }
2158
2159 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2160   (vl_api_vnet_ip4_nbr_counters_t * mp)
2161 {
2162   vat_main_t *vam = &vat_main;
2163   vl_api_ip4_nbr_counter_t *v;
2164   ip4_nbr_counter_t *counter;
2165   u32 sw_if_index;
2166   u32 count;
2167   int i;
2168
2169   sw_if_index = ntohl (mp->sw_if_index);
2170   count = ntohl (mp->count);
2171   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2172
2173   if (mp->begin)
2174     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2175
2176   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2177   for (i = 0; i < count; i++)
2178     {
2179       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2180       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2181       counter->address.s_addr = v->address;
2182       counter->packets = clib_net_to_host_u64 (v->packets);
2183       counter->bytes = clib_net_to_host_u64 (v->bytes);
2184       counter->linkt = v->link_type;
2185       v++;
2186     }
2187 }
2188
2189 static void vl_api_vnet_ip6_fib_counters_t_handler
2190   (vl_api_vnet_ip6_fib_counters_t * mp)
2191 {
2192   /* not supported */
2193 }
2194
2195 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2196   (vl_api_vnet_ip6_fib_counters_t * mp)
2197 {
2198   vat_main_t *vam = &vat_main;
2199   vl_api_ip6_fib_counter_t *v;
2200   ip6_fib_counter_t *counter;
2201   struct in6_addr ip6;
2202   u32 vrf_id;
2203   u32 vrf_index;
2204   u32 count;
2205   int i;
2206
2207   vrf_id = ntohl (mp->vrf_id);
2208   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2209   if (~0 == vrf_index)
2210     {
2211       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2212       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2213       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2214       vec_validate (vam->ip6_fib_counters, vrf_index);
2215       vam->ip6_fib_counters[vrf_index] = NULL;
2216     }
2217
2218   vec_free (vam->ip6_fib_counters[vrf_index]);
2219   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2220   count = ntohl (mp->count);
2221   for (i = 0; i < count; i++)
2222     {
2223       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2224       counter = &vam->ip6_fib_counters[vrf_index][i];
2225       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2226       counter->address = ip6;
2227       counter->address_length = v->address_length;
2228       counter->packets = clib_net_to_host_u64 (v->packets);
2229       counter->bytes = clib_net_to_host_u64 (v->bytes);
2230       v++;
2231     }
2232 }
2233
2234 static void vl_api_vnet_ip6_nbr_counters_t_handler
2235   (vl_api_vnet_ip6_nbr_counters_t * mp)
2236 {
2237   /* not supported */
2238 }
2239
2240 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2241   (vl_api_vnet_ip6_nbr_counters_t * mp)
2242 {
2243   vat_main_t *vam = &vat_main;
2244   vl_api_ip6_nbr_counter_t *v;
2245   ip6_nbr_counter_t *counter;
2246   struct in6_addr ip6;
2247   u32 sw_if_index;
2248   u32 count;
2249   int i;
2250
2251   sw_if_index = ntohl (mp->sw_if_index);
2252   count = ntohl (mp->count);
2253   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2254
2255   if (mp->begin)
2256     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2257
2258   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2259   for (i = 0; i < count; i++)
2260     {
2261       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2262       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2263       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2264       counter->address = ip6;
2265       counter->packets = clib_net_to_host_u64 (v->packets);
2266       counter->bytes = clib_net_to_host_u64 (v->bytes);
2267       v++;
2268     }
2269 }
2270
2271 static void vl_api_get_first_msg_id_reply_t_handler
2272   (vl_api_get_first_msg_id_reply_t * mp)
2273 {
2274   vat_main_t *vam = &vat_main;
2275   i32 retval = ntohl (mp->retval);
2276
2277   if (vam->async_mode)
2278     {
2279       vam->async_errors += (retval < 0);
2280     }
2281   else
2282     {
2283       vam->retval = retval;
2284       vam->result_ready = 1;
2285     }
2286   if (retval >= 0)
2287     {
2288       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2289     }
2290 }
2291
2292 static void vl_api_get_first_msg_id_reply_t_handler_json
2293   (vl_api_get_first_msg_id_reply_t * mp)
2294 {
2295   vat_main_t *vam = &vat_main;
2296   vat_json_node_t node;
2297
2298   vat_json_init_object (&node);
2299   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2300   vat_json_object_add_uint (&node, "first_msg_id",
2301                             (uint) ntohs (mp->first_msg_id));
2302
2303   vat_json_print (vam->ofp, &node);
2304   vat_json_free (&node);
2305
2306   vam->retval = ntohl (mp->retval);
2307   vam->result_ready = 1;
2308 }
2309
2310 static void vl_api_get_node_graph_reply_t_handler
2311   (vl_api_get_node_graph_reply_t * mp)
2312 {
2313   vat_main_t *vam = &vat_main;
2314   api_main_t *am = &api_main;
2315   i32 retval = ntohl (mp->retval);
2316   u8 *pvt_copy, *reply;
2317   void *oldheap;
2318   vlib_node_t *node;
2319   int i;
2320
2321   if (vam->async_mode)
2322     {
2323       vam->async_errors += (retval < 0);
2324     }
2325   else
2326     {
2327       vam->retval = retval;
2328       vam->result_ready = 1;
2329     }
2330
2331   /* "Should never happen..." */
2332   if (retval != 0)
2333     return;
2334
2335   reply = (u8 *) (mp->reply_in_shmem);
2336   pvt_copy = vec_dup (reply);
2337
2338   /* Toss the shared-memory original... */
2339   pthread_mutex_lock (&am->vlib_rp->mutex);
2340   oldheap = svm_push_data_heap (am->vlib_rp);
2341
2342   vec_free (reply);
2343
2344   svm_pop_heap (oldheap);
2345   pthread_mutex_unlock (&am->vlib_rp->mutex);
2346
2347   if (vam->graph_nodes)
2348     {
2349       hash_free (vam->graph_node_index_by_name);
2350
2351       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2352         {
2353           node = vam->graph_nodes[i];
2354           vec_free (node->name);
2355           vec_free (node->next_nodes);
2356           vec_free (node);
2357         }
2358       vec_free (vam->graph_nodes);
2359     }
2360
2361   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2362   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2363   vec_free (pvt_copy);
2364
2365   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2366     {
2367       node = vam->graph_nodes[i];
2368       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2369     }
2370 }
2371
2372 static void vl_api_get_node_graph_reply_t_handler_json
2373   (vl_api_get_node_graph_reply_t * mp)
2374 {
2375   vat_main_t *vam = &vat_main;
2376   api_main_t *am = &api_main;
2377   void *oldheap;
2378   vat_json_node_t node;
2379   u8 *reply;
2380
2381   /* $$$$ make this real? */
2382   vat_json_init_object (&node);
2383   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2384   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2385
2386   reply = (u8 *) (mp->reply_in_shmem);
2387
2388   /* Toss the shared-memory original... */
2389   pthread_mutex_lock (&am->vlib_rp->mutex);
2390   oldheap = svm_push_data_heap (am->vlib_rp);
2391
2392   vec_free (reply);
2393
2394   svm_pop_heap (oldheap);
2395   pthread_mutex_unlock (&am->vlib_rp->mutex);
2396
2397   vat_json_print (vam->ofp, &node);
2398   vat_json_free (&node);
2399
2400   vam->retval = ntohl (mp->retval);
2401   vam->result_ready = 1;
2402 }
2403
2404 static void
2405 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2406 {
2407   vat_main_t *vam = &vat_main;
2408   u8 *s = 0;
2409
2410   if (mp->local)
2411     {
2412       s = format (s, "%=16d%=16d%=16d",
2413                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2414     }
2415   else
2416     {
2417       s = format (s, "%=16U%=16d%=16d",
2418                   mp->is_ipv6 ? format_ip6_address :
2419                   format_ip4_address,
2420                   mp->ip_address, mp->priority, mp->weight);
2421     }
2422
2423   print (vam->ofp, "%v", s);
2424   vec_free (s);
2425 }
2426
2427 static void
2428 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2429 {
2430   vat_main_t *vam = &vat_main;
2431   vat_json_node_t *node = NULL;
2432   struct in6_addr ip6;
2433   struct in_addr ip4;
2434
2435   if (VAT_JSON_ARRAY != vam->json_tree.type)
2436     {
2437       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2438       vat_json_init_array (&vam->json_tree);
2439     }
2440   node = vat_json_array_add (&vam->json_tree);
2441   vat_json_init_object (node);
2442
2443   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2444   vat_json_object_add_uint (node, "priority", mp->priority);
2445   vat_json_object_add_uint (node, "weight", mp->weight);
2446
2447   if (mp->local)
2448     vat_json_object_add_uint (node, "sw_if_index",
2449                               clib_net_to_host_u32 (mp->sw_if_index));
2450   else
2451     {
2452       if (mp->is_ipv6)
2453         {
2454           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2455           vat_json_object_add_ip6 (node, "address", ip6);
2456         }
2457       else
2458         {
2459           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2460           vat_json_object_add_ip4 (node, "address", ip4);
2461         }
2462     }
2463 }
2464
2465 static void
2466 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2467                                           mp)
2468 {
2469   vat_main_t *vam = &vat_main;
2470   u8 *ls_name = 0;
2471
2472   ls_name = format (0, "%s", mp->ls_name);
2473
2474   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2475          ls_name);
2476   vec_free (ls_name);
2477 }
2478
2479 static void
2480   vl_api_one_locator_set_details_t_handler_json
2481   (vl_api_one_locator_set_details_t * mp)
2482 {
2483   vat_main_t *vam = &vat_main;
2484   vat_json_node_t *node = 0;
2485   u8 *ls_name = 0;
2486
2487   ls_name = format (0, "%s", mp->ls_name);
2488   vec_add1 (ls_name, 0);
2489
2490   if (VAT_JSON_ARRAY != vam->json_tree.type)
2491     {
2492       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2493       vat_json_init_array (&vam->json_tree);
2494     }
2495   node = vat_json_array_add (&vam->json_tree);
2496
2497   vat_json_init_object (node);
2498   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2499   vat_json_object_add_uint (node, "ls_index",
2500                             clib_net_to_host_u32 (mp->ls_index));
2501   vec_free (ls_name);
2502 }
2503
2504 static u8 *
2505 format_lisp_flat_eid (u8 * s, va_list * args)
2506 {
2507   u32 type = va_arg (*args, u32);
2508   u8 *eid = va_arg (*args, u8 *);
2509   u32 eid_len = va_arg (*args, u32);
2510
2511   switch (type)
2512     {
2513     case 0:
2514       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2515     case 1:
2516       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2517     case 2:
2518       return format (s, "%U", format_ethernet_address, eid);
2519     }
2520   return 0;
2521 }
2522
2523 static u8 *
2524 format_lisp_eid_vat (u8 * s, va_list * args)
2525 {
2526   u32 type = va_arg (*args, u32);
2527   u8 *eid = va_arg (*args, u8 *);
2528   u32 eid_len = va_arg (*args, u32);
2529   u8 *seid = va_arg (*args, u8 *);
2530   u32 seid_len = va_arg (*args, u32);
2531   u32 is_src_dst = va_arg (*args, u32);
2532
2533   if (is_src_dst)
2534     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2535
2536   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2537
2538   return s;
2539 }
2540
2541 static void
2542 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2543 {
2544   vat_main_t *vam = &vat_main;
2545   u8 *s = 0, *eid = 0;
2546
2547   if (~0 == mp->locator_set_index)
2548     s = format (0, "action: %d", mp->action);
2549   else
2550     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2551
2552   eid = format (0, "%U", format_lisp_eid_vat,
2553                 mp->eid_type,
2554                 mp->eid,
2555                 mp->eid_prefix_len,
2556                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2557   vec_add1 (eid, 0);
2558
2559   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2560          clib_net_to_host_u32 (mp->vni),
2561          eid,
2562          mp->is_local ? "local" : "remote",
2563          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2564          clib_net_to_host_u16 (mp->key_id), mp->key);
2565
2566   vec_free (s);
2567   vec_free (eid);
2568 }
2569
2570 static void
2571 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2572                                              * mp)
2573 {
2574   vat_main_t *vam = &vat_main;
2575   vat_json_node_t *node = 0;
2576   u8 *eid = 0;
2577
2578   if (VAT_JSON_ARRAY != vam->json_tree.type)
2579     {
2580       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2581       vat_json_init_array (&vam->json_tree);
2582     }
2583   node = vat_json_array_add (&vam->json_tree);
2584
2585   vat_json_init_object (node);
2586   if (~0 == mp->locator_set_index)
2587     vat_json_object_add_uint (node, "action", mp->action);
2588   else
2589     vat_json_object_add_uint (node, "locator_set_index",
2590                               clib_net_to_host_u32 (mp->locator_set_index));
2591
2592   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2593   eid = format (0, "%U", format_lisp_eid_vat,
2594                 mp->eid_type,
2595                 mp->eid,
2596                 mp->eid_prefix_len,
2597                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2598   vec_add1 (eid, 0);
2599   vat_json_object_add_string_copy (node, "eid", eid);
2600   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2601   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2602   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2603
2604   if (mp->key_id)
2605     {
2606       vat_json_object_add_uint (node, "key_id",
2607                                 clib_net_to_host_u16 (mp->key_id));
2608       vat_json_object_add_string_copy (node, "key", mp->key);
2609     }
2610   vec_free (eid);
2611 }
2612
2613 static void
2614   vl_api_one_eid_table_map_details_t_handler
2615   (vl_api_one_eid_table_map_details_t * mp)
2616 {
2617   vat_main_t *vam = &vat_main;
2618
2619   u8 *line = format (0, "%=10d%=10d",
2620                      clib_net_to_host_u32 (mp->vni),
2621                      clib_net_to_host_u32 (mp->dp_table));
2622   print (vam->ofp, "%v", line);
2623   vec_free (line);
2624 }
2625
2626 static void
2627   vl_api_one_eid_table_map_details_t_handler_json
2628   (vl_api_one_eid_table_map_details_t * mp)
2629 {
2630   vat_main_t *vam = &vat_main;
2631   vat_json_node_t *node = NULL;
2632
2633   if (VAT_JSON_ARRAY != vam->json_tree.type)
2634     {
2635       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2636       vat_json_init_array (&vam->json_tree);
2637     }
2638   node = vat_json_array_add (&vam->json_tree);
2639   vat_json_init_object (node);
2640   vat_json_object_add_uint (node, "dp_table",
2641                             clib_net_to_host_u32 (mp->dp_table));
2642   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2643 }
2644
2645 static void
2646   vl_api_one_eid_table_vni_details_t_handler
2647   (vl_api_one_eid_table_vni_details_t * mp)
2648 {
2649   vat_main_t *vam = &vat_main;
2650
2651   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2652   print (vam->ofp, "%v", line);
2653   vec_free (line);
2654 }
2655
2656 static void
2657   vl_api_one_eid_table_vni_details_t_handler_json
2658   (vl_api_one_eid_table_vni_details_t * mp)
2659 {
2660   vat_main_t *vam = &vat_main;
2661   vat_json_node_t *node = NULL;
2662
2663   if (VAT_JSON_ARRAY != vam->json_tree.type)
2664     {
2665       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2666       vat_json_init_array (&vam->json_tree);
2667     }
2668   node = vat_json_array_add (&vam->json_tree);
2669   vat_json_init_object (node);
2670   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2671 }
2672
2673 static void
2674   vl_api_show_one_map_register_state_reply_t_handler
2675   (vl_api_show_one_map_register_state_reply_t * mp)
2676 {
2677   vat_main_t *vam = &vat_main;
2678   int retval = clib_net_to_host_u32 (mp->retval);
2679
2680   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2681
2682   vam->retval = retval;
2683   vam->result_ready = 1;
2684 }
2685
2686 static void
2687   vl_api_show_one_map_register_state_reply_t_handler_json
2688   (vl_api_show_one_map_register_state_reply_t * mp)
2689 {
2690   vat_main_t *vam = &vat_main;
2691   vat_json_node_t _node, *node = &_node;
2692   int retval = clib_net_to_host_u32 (mp->retval);
2693
2694   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2695
2696   vat_json_init_object (node);
2697   vat_json_object_add_string_copy (node, "state", s);
2698
2699   vat_json_print (vam->ofp, node);
2700   vat_json_free (node);
2701
2702   vam->retval = retval;
2703   vam->result_ready = 1;
2704   vec_free (s);
2705 }
2706
2707 static void
2708   vl_api_show_one_rloc_probe_state_reply_t_handler
2709   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2710 {
2711   vat_main_t *vam = &vat_main;
2712   int retval = clib_net_to_host_u32 (mp->retval);
2713
2714   if (retval)
2715     goto end;
2716
2717   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2718 end:
2719   vam->retval = retval;
2720   vam->result_ready = 1;
2721 }
2722
2723 static void
2724   vl_api_show_one_rloc_probe_state_reply_t_handler_json
2725   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2726 {
2727   vat_main_t *vam = &vat_main;
2728   vat_json_node_t _node, *node = &_node;
2729   int retval = clib_net_to_host_u32 (mp->retval);
2730
2731   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2732   vat_json_init_object (node);
2733   vat_json_object_add_string_copy (node, "state", s);
2734
2735   vat_json_print (vam->ofp, node);
2736   vat_json_free (node);
2737
2738   vam->retval = retval;
2739   vam->result_ready = 1;
2740   vec_free (s);
2741 }
2742
2743 static void
2744 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
2745 {
2746   e->dp_table = clib_net_to_host_u32 (e->dp_table);
2747   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
2748 }
2749
2750 static void
2751   gpe_fwd_entries_get_reply_t_net_to_host
2752   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2753 {
2754   u32 i;
2755
2756   mp->count = clib_net_to_host_u32 (mp->count);
2757   for (i = 0; i < mp->count; i++)
2758     {
2759       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
2760     }
2761 }
2762
2763 static u8 *
2764 format_gpe_encap_mode (u8 * s, va_list * args)
2765 {
2766   u32 mode = va_arg (*args, u32);
2767
2768   switch (mode)
2769     {
2770     case 0:
2771       return format (s, "lisp");
2772     case 1:
2773       return format (s, "vxlan");
2774     }
2775   return 0;
2776 }
2777
2778 static void
2779   vl_api_gpe_get_encap_mode_reply_t_handler
2780   (vl_api_gpe_get_encap_mode_reply_t * mp)
2781 {
2782   vat_main_t *vam = &vat_main;
2783
2784   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
2785   vam->retval = ntohl (mp->retval);
2786   vam->result_ready = 1;
2787 }
2788
2789 static void
2790   vl_api_gpe_get_encap_mode_reply_t_handler_json
2791   (vl_api_gpe_get_encap_mode_reply_t * mp)
2792 {
2793   vat_main_t *vam = &vat_main;
2794   vat_json_node_t node;
2795
2796   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
2797   vec_add1 (encap_mode, 0);
2798
2799   vat_json_init_object (&node);
2800   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
2801
2802   vec_free (encap_mode);
2803   vat_json_print (vam->ofp, &node);
2804   vat_json_free (&node);
2805
2806   vam->retval = ntohl (mp->retval);
2807   vam->result_ready = 1;
2808 }
2809
2810 static void
2811   vl_api_gpe_fwd_entry_path_details_t_handler
2812   (vl_api_gpe_fwd_entry_path_details_t * mp)
2813 {
2814   vat_main_t *vam = &vat_main;
2815   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2816
2817   if (mp->lcl_loc.is_ip4)
2818     format_ip_address_fcn = format_ip4_address;
2819   else
2820     format_ip_address_fcn = format_ip6_address;
2821
2822   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
2823          format_ip_address_fcn, &mp->lcl_loc,
2824          format_ip_address_fcn, &mp->rmt_loc);
2825 }
2826
2827 static void
2828 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
2829 {
2830   struct in6_addr ip6;
2831   struct in_addr ip4;
2832
2833   if (loc->is_ip4)
2834     {
2835       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
2836       vat_json_object_add_ip4 (n, "address", ip4);
2837     }
2838   else
2839     {
2840       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
2841       vat_json_object_add_ip6 (n, "address", ip6);
2842     }
2843   vat_json_object_add_uint (n, "weight", loc->weight);
2844 }
2845
2846 static void
2847   vl_api_gpe_fwd_entry_path_details_t_handler_json
2848   (vl_api_gpe_fwd_entry_path_details_t * mp)
2849 {
2850   vat_main_t *vam = &vat_main;
2851   vat_json_node_t *node = NULL;
2852   vat_json_node_t *loc_node;
2853
2854   if (VAT_JSON_ARRAY != vam->json_tree.type)
2855     {
2856       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2857       vat_json_init_array (&vam->json_tree);
2858     }
2859   node = vat_json_array_add (&vam->json_tree);
2860   vat_json_init_object (node);
2861
2862   loc_node = vat_json_object_add (node, "local_locator");
2863   vat_json_init_object (loc_node);
2864   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
2865
2866   loc_node = vat_json_object_add (node, "remote_locator");
2867   vat_json_init_object (loc_node);
2868   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
2869 }
2870
2871 static void
2872   vl_api_gpe_fwd_entries_get_reply_t_handler
2873   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2874 {
2875   vat_main_t *vam = &vat_main;
2876   u32 i;
2877   int retval = clib_net_to_host_u32 (mp->retval);
2878   vl_api_gpe_fwd_entry_t *e;
2879
2880   if (retval)
2881     goto end;
2882
2883   gpe_fwd_entries_get_reply_t_net_to_host (mp);
2884
2885   for (i = 0; i < mp->count; i++)
2886     {
2887       e = &mp->entries[i];
2888       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
2889              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
2890              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
2891     }
2892
2893 end:
2894   vam->retval = retval;
2895   vam->result_ready = 1;
2896 }
2897
2898 static void
2899   vl_api_gpe_fwd_entries_get_reply_t_handler_json
2900   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2901 {
2902   u8 *s = 0;
2903   vat_main_t *vam = &vat_main;
2904   vat_json_node_t *e = 0, root;
2905   u32 i;
2906   int retval = clib_net_to_host_u32 (mp->retval);
2907   vl_api_gpe_fwd_entry_t *fwd;
2908
2909   if (retval)
2910     goto end;
2911
2912   gpe_fwd_entries_get_reply_t_net_to_host (mp);
2913   vat_json_init_array (&root);
2914
2915   for (i = 0; i < mp->count; i++)
2916     {
2917       e = vat_json_array_add (&root);
2918       fwd = &mp->entries[i];
2919
2920       vat_json_init_object (e);
2921       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
2922       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
2923
2924       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
2925                   fwd->leid_prefix_len);
2926       vec_add1 (s, 0);
2927       vat_json_object_add_string_copy (e, "leid", s);
2928       vec_free (s);
2929
2930       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
2931                   fwd->reid_prefix_len);
2932       vec_add1 (s, 0);
2933       vat_json_object_add_string_copy (e, "reid", s);
2934       vec_free (s);
2935     }
2936
2937   vat_json_print (vam->ofp, &root);
2938   vat_json_free (&root);
2939
2940 end:
2941   vam->retval = retval;
2942   vam->result_ready = 1;
2943 }
2944
2945 static void
2946   vl_api_one_adjacencies_get_reply_t_handler
2947   (vl_api_one_adjacencies_get_reply_t * mp)
2948 {
2949   vat_main_t *vam = &vat_main;
2950   u32 i, n;
2951   int retval = clib_net_to_host_u32 (mp->retval);
2952   vl_api_one_adjacency_t *a;
2953
2954   if (retval)
2955     goto end;
2956
2957   n = clib_net_to_host_u32 (mp->count);
2958
2959   for (i = 0; i < n; i++)
2960     {
2961       a = &mp->adjacencies[i];
2962       print (vam->ofp, "%U %40U",
2963              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2964              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
2965     }
2966
2967 end:
2968   vam->retval = retval;
2969   vam->result_ready = 1;
2970 }
2971
2972 static void
2973   vl_api_one_adjacencies_get_reply_t_handler_json
2974   (vl_api_one_adjacencies_get_reply_t * mp)
2975 {
2976   u8 *s = 0;
2977   vat_main_t *vam = &vat_main;
2978   vat_json_node_t *e = 0, root;
2979   u32 i, n;
2980   int retval = clib_net_to_host_u32 (mp->retval);
2981   vl_api_one_adjacency_t *a;
2982
2983   if (retval)
2984     goto end;
2985
2986   n = clib_net_to_host_u32 (mp->count);
2987   vat_json_init_array (&root);
2988
2989   for (i = 0; i < n; i++)
2990     {
2991       e = vat_json_array_add (&root);
2992       a = &mp->adjacencies[i];
2993
2994       vat_json_init_object (e);
2995       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2996                   a->leid_prefix_len);
2997       vec_add1 (s, 0);
2998       vat_json_object_add_string_copy (e, "leid", s);
2999       vec_free (s);
3000
3001       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3002                   a->reid_prefix_len);
3003       vec_add1 (s, 0);
3004       vat_json_object_add_string_copy (e, "reid", s);
3005       vec_free (s);
3006     }
3007
3008   vat_json_print (vam->ofp, &root);
3009   vat_json_free (&root);
3010
3011 end:
3012   vam->retval = retval;
3013   vam->result_ready = 1;
3014 }
3015
3016 static void
3017 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3018 {
3019   vat_main_t *vam = &vat_main;
3020
3021   print (vam->ofp, "%=20U",
3022          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3023          mp->ip_address);
3024 }
3025
3026 static void
3027   vl_api_one_map_server_details_t_handler_json
3028   (vl_api_one_map_server_details_t * mp)
3029 {
3030   vat_main_t *vam = &vat_main;
3031   vat_json_node_t *node = NULL;
3032   struct in6_addr ip6;
3033   struct in_addr ip4;
3034
3035   if (VAT_JSON_ARRAY != vam->json_tree.type)
3036     {
3037       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3038       vat_json_init_array (&vam->json_tree);
3039     }
3040   node = vat_json_array_add (&vam->json_tree);
3041
3042   vat_json_init_object (node);
3043   if (mp->is_ipv6)
3044     {
3045       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3046       vat_json_object_add_ip6 (node, "map-server", ip6);
3047     }
3048   else
3049     {
3050       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3051       vat_json_object_add_ip4 (node, "map-server", ip4);
3052     }
3053 }
3054
3055 static void
3056 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3057                                            * mp)
3058 {
3059   vat_main_t *vam = &vat_main;
3060
3061   print (vam->ofp, "%=20U",
3062          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3063          mp->ip_address);
3064 }
3065
3066 static void
3067   vl_api_one_map_resolver_details_t_handler_json
3068   (vl_api_one_map_resolver_details_t * mp)
3069 {
3070   vat_main_t *vam = &vat_main;
3071   vat_json_node_t *node = NULL;
3072   struct in6_addr ip6;
3073   struct in_addr ip4;
3074
3075   if (VAT_JSON_ARRAY != vam->json_tree.type)
3076     {
3077       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3078       vat_json_init_array (&vam->json_tree);
3079     }
3080   node = vat_json_array_add (&vam->json_tree);
3081
3082   vat_json_init_object (node);
3083   if (mp->is_ipv6)
3084     {
3085       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3086       vat_json_object_add_ip6 (node, "map resolver", ip6);
3087     }
3088   else
3089     {
3090       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3091       vat_json_object_add_ip4 (node, "map resolver", ip4);
3092     }
3093 }
3094
3095 static void
3096 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
3097 {
3098   vat_main_t *vam = &vat_main;
3099   i32 retval = ntohl (mp->retval);
3100
3101   if (0 <= retval)
3102     {
3103       print (vam->ofp, "feature: %s\ngpe: %s",
3104              mp->feature_status ? "enabled" : "disabled",
3105              mp->gpe_status ? "enabled" : "disabled");
3106     }
3107
3108   vam->retval = retval;
3109   vam->result_ready = 1;
3110 }
3111
3112 static void
3113   vl_api_show_one_status_reply_t_handler_json
3114   (vl_api_show_one_status_reply_t * mp)
3115 {
3116   vat_main_t *vam = &vat_main;
3117   vat_json_node_t node;
3118   u8 *gpe_status = NULL;
3119   u8 *feature_status = NULL;
3120
3121   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
3122   feature_status = format (0, "%s",
3123                            mp->feature_status ? "enabled" : "disabled");
3124   vec_add1 (gpe_status, 0);
3125   vec_add1 (feature_status, 0);
3126
3127   vat_json_init_object (&node);
3128   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
3129   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
3130
3131   vec_free (gpe_status);
3132   vec_free (feature_status);
3133
3134   vat_json_print (vam->ofp, &node);
3135   vat_json_free (&node);
3136
3137   vam->retval = ntohl (mp->retval);
3138   vam->result_ready = 1;
3139 }
3140
3141 static void
3142   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
3143   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3144 {
3145   vat_main_t *vam = &vat_main;
3146   i32 retval = ntohl (mp->retval);
3147
3148   if (retval >= 0)
3149     {
3150       print (vam->ofp, "%=20s", mp->locator_set_name);
3151     }
3152
3153   vam->retval = retval;
3154   vam->result_ready = 1;
3155 }
3156
3157 static void
3158   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
3159   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3160 {
3161   vat_main_t *vam = &vat_main;
3162   vat_json_node_t *node = NULL;
3163
3164   if (VAT_JSON_ARRAY != vam->json_tree.type)
3165     {
3166       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3167       vat_json_init_array (&vam->json_tree);
3168     }
3169   node = vat_json_array_add (&vam->json_tree);
3170
3171   vat_json_init_object (node);
3172   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
3173
3174   vat_json_print (vam->ofp, node);
3175   vat_json_free (node);
3176
3177   vam->retval = ntohl (mp->retval);
3178   vam->result_ready = 1;
3179 }
3180
3181 static u8 *
3182 format_lisp_map_request_mode (u8 * s, va_list * args)
3183 {
3184   u32 mode = va_arg (*args, u32);
3185
3186   switch (mode)
3187     {
3188     case 0:
3189       return format (0, "dst-only");
3190     case 1:
3191       return format (0, "src-dst");
3192     }
3193   return 0;
3194 }
3195
3196 static void
3197   vl_api_show_one_map_request_mode_reply_t_handler
3198   (vl_api_show_one_map_request_mode_reply_t * mp)
3199 {
3200   vat_main_t *vam = &vat_main;
3201   i32 retval = ntohl (mp->retval);
3202
3203   if (0 <= retval)
3204     {
3205       u32 mode = mp->mode;
3206       print (vam->ofp, "map_request_mode: %U",
3207              format_lisp_map_request_mode, mode);
3208     }
3209
3210   vam->retval = retval;
3211   vam->result_ready = 1;
3212 }
3213
3214 static void
3215   vl_api_show_one_map_request_mode_reply_t_handler_json
3216   (vl_api_show_one_map_request_mode_reply_t * mp)
3217 {
3218   vat_main_t *vam = &vat_main;
3219   vat_json_node_t node;
3220   u8 *s = 0;
3221   u32 mode;
3222
3223   mode = mp->mode;
3224   s = format (0, "%U", format_lisp_map_request_mode, mode);
3225   vec_add1 (s, 0);
3226
3227   vat_json_init_object (&node);
3228   vat_json_object_add_string_copy (&node, "map_request_mode", s);
3229   vat_json_print (vam->ofp, &node);
3230   vat_json_free (&node);
3231
3232   vec_free (s);
3233   vam->retval = ntohl (mp->retval);
3234   vam->result_ready = 1;
3235 }
3236
3237 static void
3238 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
3239 {
3240   vat_main_t *vam = &vat_main;
3241   i32 retval = ntohl (mp->retval);
3242
3243   if (0 <= retval)
3244     {
3245       print (vam->ofp, "%-20s%-16s",
3246              mp->status ? "enabled" : "disabled",
3247              mp->status ? (char *) mp->locator_set_name : "");
3248     }
3249
3250   vam->retval = retval;
3251   vam->result_ready = 1;
3252 }
3253
3254 static void
3255 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
3256 {
3257   vat_main_t *vam = &vat_main;
3258   vat_json_node_t node;
3259   u8 *status = 0;
3260
3261   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3262   vec_add1 (status, 0);
3263
3264   vat_json_init_object (&node);
3265   vat_json_object_add_string_copy (&node, "status", status);
3266   if (mp->status)
3267     {
3268       vat_json_object_add_string_copy (&node, "locator_set",
3269                                        mp->locator_set_name);
3270     }
3271
3272   vec_free (status);
3273
3274   vat_json_print (vam->ofp, &node);
3275   vat_json_free (&node);
3276
3277   vam->retval = ntohl (mp->retval);
3278   vam->result_ready = 1;
3279 }
3280
3281 static u8 *
3282 format_policer_type (u8 * s, va_list * va)
3283 {
3284   u32 i = va_arg (*va, u32);
3285
3286   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
3287     s = format (s, "1r2c");
3288   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
3289     s = format (s, "1r3c");
3290   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
3291     s = format (s, "2r3c-2698");
3292   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
3293     s = format (s, "2r3c-4115");
3294   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
3295     s = format (s, "2r3c-mef5cf1");
3296   else
3297     s = format (s, "ILLEGAL");
3298   return s;
3299 }
3300
3301 static u8 *
3302 format_policer_rate_type (u8 * s, va_list * va)
3303 {
3304   u32 i = va_arg (*va, u32);
3305
3306   if (i == SSE2_QOS_RATE_KBPS)
3307     s = format (s, "kbps");
3308   else if (i == SSE2_QOS_RATE_PPS)
3309     s = format (s, "pps");
3310   else
3311     s = format (s, "ILLEGAL");
3312   return s;
3313 }
3314
3315 static u8 *
3316 format_policer_round_type (u8 * s, va_list * va)
3317 {
3318   u32 i = va_arg (*va, u32);
3319
3320   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3321     s = format (s, "closest");
3322   else if (i == SSE2_QOS_ROUND_TO_UP)
3323     s = format (s, "up");
3324   else if (i == SSE2_QOS_ROUND_TO_DOWN)
3325     s = format (s, "down");
3326   else
3327     s = format (s, "ILLEGAL");
3328   return s;
3329 }
3330
3331 static u8 *
3332 format_policer_action_type (u8 * s, va_list * va)
3333 {
3334   u32 i = va_arg (*va, u32);
3335
3336   if (i == SSE2_QOS_ACTION_DROP)
3337     s = format (s, "drop");
3338   else if (i == SSE2_QOS_ACTION_TRANSMIT)
3339     s = format (s, "transmit");
3340   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3341     s = format (s, "mark-and-transmit");
3342   else
3343     s = format (s, "ILLEGAL");
3344   return s;
3345 }
3346
3347 static u8 *
3348 format_dscp (u8 * s, va_list * va)
3349 {
3350   u32 i = va_arg (*va, u32);
3351   char *t = 0;
3352
3353   switch (i)
3354     {
3355 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3356       foreach_vnet_dscp
3357 #undef _
3358     default:
3359       return format (s, "ILLEGAL");
3360     }
3361   s = format (s, "%s", t);
3362   return s;
3363 }
3364
3365 static void
3366 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3367 {
3368   vat_main_t *vam = &vat_main;
3369   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3370
3371   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3372     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3373   else
3374     conform_dscp_str = format (0, "");
3375
3376   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3377     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3378   else
3379     exceed_dscp_str = format (0, "");
3380
3381   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3382     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3383   else
3384     violate_dscp_str = format (0, "");
3385
3386   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3387          "rate type %U, round type %U, %s rate, %s color-aware, "
3388          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3389          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3390          "conform action %U%s, exceed action %U%s, violate action %U%s",
3391          mp->name,
3392          format_policer_type, mp->type,
3393          ntohl (mp->cir),
3394          ntohl (mp->eir),
3395          clib_net_to_host_u64 (mp->cb),
3396          clib_net_to_host_u64 (mp->eb),
3397          format_policer_rate_type, mp->rate_type,
3398          format_policer_round_type, mp->round_type,
3399          mp->single_rate ? "single" : "dual",
3400          mp->color_aware ? "is" : "not",
3401          ntohl (mp->cir_tokens_per_period),
3402          ntohl (mp->pir_tokens_per_period),
3403          ntohl (mp->scale),
3404          ntohl (mp->current_limit),
3405          ntohl (mp->current_bucket),
3406          ntohl (mp->extended_limit),
3407          ntohl (mp->extended_bucket),
3408          clib_net_to_host_u64 (mp->last_update_time),
3409          format_policer_action_type, mp->conform_action_type,
3410          conform_dscp_str,
3411          format_policer_action_type, mp->exceed_action_type,
3412          exceed_dscp_str,
3413          format_policer_action_type, mp->violate_action_type,
3414          violate_dscp_str);
3415
3416   vec_free (conform_dscp_str);
3417   vec_free (exceed_dscp_str);
3418   vec_free (violate_dscp_str);
3419 }
3420
3421 static void vl_api_policer_details_t_handler_json
3422   (vl_api_policer_details_t * mp)
3423 {
3424   vat_main_t *vam = &vat_main;
3425   vat_json_node_t *node;
3426   u8 *rate_type_str, *round_type_str, *type_str;
3427   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3428
3429   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3430   round_type_str =
3431     format (0, "%U", format_policer_round_type, mp->round_type);
3432   type_str = format (0, "%U", format_policer_type, mp->type);
3433   conform_action_str = format (0, "%U", format_policer_action_type,
3434                                mp->conform_action_type);
3435   exceed_action_str = format (0, "%U", format_policer_action_type,
3436                               mp->exceed_action_type);
3437   violate_action_str = format (0, "%U", format_policer_action_type,
3438                                mp->violate_action_type);
3439
3440   if (VAT_JSON_ARRAY != vam->json_tree.type)
3441     {
3442       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3443       vat_json_init_array (&vam->json_tree);
3444     }
3445   node = vat_json_array_add (&vam->json_tree);
3446
3447   vat_json_init_object (node);
3448   vat_json_object_add_string_copy (node, "name", mp->name);
3449   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3450   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3451   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3452   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3453   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3454   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3455   vat_json_object_add_string_copy (node, "type", type_str);
3456   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3457   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3458   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3459   vat_json_object_add_uint (node, "cir_tokens_per_period",
3460                             ntohl (mp->cir_tokens_per_period));
3461   vat_json_object_add_uint (node, "eir_tokens_per_period",
3462                             ntohl (mp->pir_tokens_per_period));
3463   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3464   vat_json_object_add_uint (node, "current_bucket",
3465                             ntohl (mp->current_bucket));
3466   vat_json_object_add_uint (node, "extended_limit",
3467                             ntohl (mp->extended_limit));
3468   vat_json_object_add_uint (node, "extended_bucket",
3469                             ntohl (mp->extended_bucket));
3470   vat_json_object_add_uint (node, "last_update_time",
3471                             ntohl (mp->last_update_time));
3472   vat_json_object_add_string_copy (node, "conform_action",
3473                                    conform_action_str);
3474   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3475     {
3476       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3477       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3478       vec_free (dscp_str);
3479     }
3480   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3481   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3482     {
3483       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3484       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3485       vec_free (dscp_str);
3486     }
3487   vat_json_object_add_string_copy (node, "violate_action",
3488                                    violate_action_str);
3489   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3490     {
3491       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3492       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3493       vec_free (dscp_str);
3494     }
3495
3496   vec_free (rate_type_str);
3497   vec_free (round_type_str);
3498   vec_free (type_str);
3499   vec_free (conform_action_str);
3500   vec_free (exceed_action_str);
3501   vec_free (violate_action_str);
3502 }
3503
3504 static void
3505 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3506                                            mp)
3507 {
3508   vat_main_t *vam = &vat_main;
3509   int i, count = ntohl (mp->count);
3510
3511   if (count > 0)
3512     print (vam->ofp, "classify table ids (%d) : ", count);
3513   for (i = 0; i < count; i++)
3514     {
3515       print (vam->ofp, "%d", ntohl (mp->ids[i]));
3516       print (vam->ofp, (i < count - 1) ? "," : "");
3517     }
3518   vam->retval = ntohl (mp->retval);
3519   vam->result_ready = 1;
3520 }
3521
3522 static void
3523   vl_api_classify_table_ids_reply_t_handler_json
3524   (vl_api_classify_table_ids_reply_t * mp)
3525 {
3526   vat_main_t *vam = &vat_main;
3527   int i, count = ntohl (mp->count);
3528
3529   if (count > 0)
3530     {
3531       vat_json_node_t node;
3532
3533       vat_json_init_object (&node);
3534       for (i = 0; i < count; i++)
3535         {
3536           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3537         }
3538       vat_json_print (vam->ofp, &node);
3539       vat_json_free (&node);
3540     }
3541   vam->retval = ntohl (mp->retval);
3542   vam->result_ready = 1;
3543 }
3544
3545 static void
3546   vl_api_classify_table_by_interface_reply_t_handler
3547   (vl_api_classify_table_by_interface_reply_t * mp)
3548 {
3549   vat_main_t *vam = &vat_main;
3550   u32 table_id;
3551
3552   table_id = ntohl (mp->l2_table_id);
3553   if (table_id != ~0)
3554     print (vam->ofp, "l2 table id : %d", table_id);
3555   else
3556     print (vam->ofp, "l2 table id : No input ACL tables configured");
3557   table_id = ntohl (mp->ip4_table_id);
3558   if (table_id != ~0)
3559     print (vam->ofp, "ip4 table id : %d", table_id);
3560   else
3561     print (vam->ofp, "ip4 table id : No input ACL tables configured");
3562   table_id = ntohl (mp->ip6_table_id);
3563   if (table_id != ~0)
3564     print (vam->ofp, "ip6 table id : %d", table_id);
3565   else
3566     print (vam->ofp, "ip6 table id : No input ACL tables configured");
3567   vam->retval = ntohl (mp->retval);
3568   vam->result_ready = 1;
3569 }
3570
3571 static void
3572   vl_api_classify_table_by_interface_reply_t_handler_json
3573   (vl_api_classify_table_by_interface_reply_t * mp)
3574 {
3575   vat_main_t *vam = &vat_main;
3576   vat_json_node_t node;
3577
3578   vat_json_init_object (&node);
3579
3580   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3581   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3582   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3583
3584   vat_json_print (vam->ofp, &node);
3585   vat_json_free (&node);
3586
3587   vam->retval = ntohl (mp->retval);
3588   vam->result_ready = 1;
3589 }
3590
3591 static void vl_api_policer_add_del_reply_t_handler
3592   (vl_api_policer_add_del_reply_t * mp)
3593 {
3594   vat_main_t *vam = &vat_main;
3595   i32 retval = ntohl (mp->retval);
3596   if (vam->async_mode)
3597     {
3598       vam->async_errors += (retval < 0);
3599     }
3600   else
3601     {
3602       vam->retval = retval;
3603       vam->result_ready = 1;
3604       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3605         /*
3606          * Note: this is just barely thread-safe, depends on
3607          * the main thread spinning waiting for an answer...
3608          */
3609         errmsg ("policer index %d", ntohl (mp->policer_index));
3610     }
3611 }
3612
3613 static void vl_api_policer_add_del_reply_t_handler_json
3614   (vl_api_policer_add_del_reply_t * mp)
3615 {
3616   vat_main_t *vam = &vat_main;
3617   vat_json_node_t node;
3618
3619   vat_json_init_object (&node);
3620   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3621   vat_json_object_add_uint (&node, "policer_index",
3622                             ntohl (mp->policer_index));
3623
3624   vat_json_print (vam->ofp, &node);
3625   vat_json_free (&node);
3626
3627   vam->retval = ntohl (mp->retval);
3628   vam->result_ready = 1;
3629 }
3630
3631 /* Format hex dump. */
3632 u8 *
3633 format_hex_bytes (u8 * s, va_list * va)
3634 {
3635   u8 *bytes = va_arg (*va, u8 *);
3636   int n_bytes = va_arg (*va, int);
3637   uword i;
3638
3639   /* Print short or long form depending on byte count. */
3640   uword short_form = n_bytes <= 32;
3641   uword indent = format_get_indent (s);
3642
3643   if (n_bytes == 0)
3644     return s;
3645
3646   for (i = 0; i < n_bytes; i++)
3647     {
3648       if (!short_form && (i % 32) == 0)
3649         s = format (s, "%08x: ", i);
3650       s = format (s, "%02x", bytes[i]);
3651       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3652         s = format (s, "\n%U", format_white_space, indent);
3653     }
3654
3655   return s;
3656 }
3657
3658 static void
3659 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3660                                             * mp)
3661 {
3662   vat_main_t *vam = &vat_main;
3663   i32 retval = ntohl (mp->retval);
3664   if (retval == 0)
3665     {
3666       print (vam->ofp, "classify table info :");
3667       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3668              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3669              ntohl (mp->miss_next_index));
3670       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3671              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3672              ntohl (mp->match_n_vectors));
3673       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3674              ntohl (mp->mask_length));
3675     }
3676   vam->retval = retval;
3677   vam->result_ready = 1;
3678 }
3679
3680 static void
3681   vl_api_classify_table_info_reply_t_handler_json
3682   (vl_api_classify_table_info_reply_t * mp)
3683 {
3684   vat_main_t *vam = &vat_main;
3685   vat_json_node_t node;
3686
3687   i32 retval = ntohl (mp->retval);
3688   if (retval == 0)
3689     {
3690       vat_json_init_object (&node);
3691
3692       vat_json_object_add_int (&node, "sessions",
3693                                ntohl (mp->active_sessions));
3694       vat_json_object_add_int (&node, "nexttbl",
3695                                ntohl (mp->next_table_index));
3696       vat_json_object_add_int (&node, "nextnode",
3697                                ntohl (mp->miss_next_index));
3698       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3699       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3700       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3701       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3702                       ntohl (mp->mask_length), 0);
3703       vat_json_object_add_string_copy (&node, "mask", s);
3704
3705       vat_json_print (vam->ofp, &node);
3706       vat_json_free (&node);
3707     }
3708   vam->retval = ntohl (mp->retval);
3709   vam->result_ready = 1;
3710 }
3711
3712 static void
3713 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3714                                            mp)
3715 {
3716   vat_main_t *vam = &vat_main;
3717
3718   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3719          ntohl (mp->hit_next_index), ntohl (mp->advance),
3720          ntohl (mp->opaque_index));
3721   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3722          ntohl (mp->match_length));
3723 }
3724
3725 static void
3726   vl_api_classify_session_details_t_handler_json
3727   (vl_api_classify_session_details_t * mp)
3728 {
3729   vat_main_t *vam = &vat_main;
3730   vat_json_node_t *node = NULL;
3731
3732   if (VAT_JSON_ARRAY != vam->json_tree.type)
3733     {
3734       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3735       vat_json_init_array (&vam->json_tree);
3736     }
3737   node = vat_json_array_add (&vam->json_tree);
3738
3739   vat_json_init_object (node);
3740   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3741   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3742   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3743   u8 *s =
3744     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3745             0);
3746   vat_json_object_add_string_copy (node, "match", s);
3747 }
3748
3749 static void vl_api_pg_create_interface_reply_t_handler
3750   (vl_api_pg_create_interface_reply_t * mp)
3751 {
3752   vat_main_t *vam = &vat_main;
3753
3754   vam->retval = ntohl (mp->retval);
3755   vam->result_ready = 1;
3756 }
3757
3758 static void vl_api_pg_create_interface_reply_t_handler_json
3759   (vl_api_pg_create_interface_reply_t * mp)
3760 {
3761   vat_main_t *vam = &vat_main;
3762   vat_json_node_t node;
3763
3764   i32 retval = ntohl (mp->retval);
3765   if (retval == 0)
3766     {
3767       vat_json_init_object (&node);
3768
3769       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3770
3771       vat_json_print (vam->ofp, &node);
3772       vat_json_free (&node);
3773     }
3774   vam->retval = ntohl (mp->retval);
3775   vam->result_ready = 1;
3776 }
3777
3778 static void vl_api_policer_classify_details_t_handler
3779   (vl_api_policer_classify_details_t * mp)
3780 {
3781   vat_main_t *vam = &vat_main;
3782
3783   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3784          ntohl (mp->table_index));
3785 }
3786
3787 static void vl_api_policer_classify_details_t_handler_json
3788   (vl_api_policer_classify_details_t * mp)
3789 {
3790   vat_main_t *vam = &vat_main;
3791   vat_json_node_t *node;
3792
3793   if (VAT_JSON_ARRAY != vam->json_tree.type)
3794     {
3795       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3796       vat_json_init_array (&vam->json_tree);
3797     }
3798   node = vat_json_array_add (&vam->json_tree);
3799
3800   vat_json_init_object (node);
3801   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3802   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3803 }
3804
3805 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3806   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3807 {
3808   vat_main_t *vam = &vat_main;
3809   i32 retval = ntohl (mp->retval);
3810   if (vam->async_mode)
3811     {
3812       vam->async_errors += (retval < 0);
3813     }
3814   else
3815     {
3816       vam->retval = retval;
3817       vam->sw_if_index = ntohl (mp->sw_if_index);
3818       vam->result_ready = 1;
3819     }
3820 }
3821
3822 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3823   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3824 {
3825   vat_main_t *vam = &vat_main;
3826   vat_json_node_t node;
3827
3828   vat_json_init_object (&node);
3829   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3830   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3831
3832   vat_json_print (vam->ofp, &node);
3833   vat_json_free (&node);
3834
3835   vam->retval = ntohl (mp->retval);
3836   vam->result_ready = 1;
3837 }
3838
3839 static void vl_api_flow_classify_details_t_handler
3840   (vl_api_flow_classify_details_t * mp)
3841 {
3842   vat_main_t *vam = &vat_main;
3843
3844   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3845          ntohl (mp->table_index));
3846 }
3847
3848 static void vl_api_flow_classify_details_t_handler_json
3849   (vl_api_flow_classify_details_t * mp)
3850 {
3851   vat_main_t *vam = &vat_main;
3852   vat_json_node_t *node;
3853
3854   if (VAT_JSON_ARRAY != vam->json_tree.type)
3855     {
3856       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3857       vat_json_init_array (&vam->json_tree);
3858     }
3859   node = vat_json_array_add (&vam->json_tree);
3860
3861   vat_json_init_object (node);
3862   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3863   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3864 }
3865
3866
3867
3868 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3869 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3870 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3871 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3872 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
3873 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
3874 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
3875 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
3876 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
3877 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
3878
3879 /*
3880  * Generate boilerplate reply handlers, which
3881  * dig the return value out of the xxx_reply_t API message,
3882  * stick it into vam->retval, and set vam->result_ready
3883  *
3884  * Could also do this by pointing N message decode slots at
3885  * a single function, but that could break in subtle ways.
3886  */
3887
3888 #define foreach_standard_reply_retval_handler           \
3889 _(sw_interface_set_flags_reply)                         \
3890 _(sw_interface_add_del_address_reply)                   \
3891 _(sw_interface_set_table_reply)                         \
3892 _(sw_interface_set_mpls_enable_reply)                   \
3893 _(sw_interface_set_vpath_reply)                         \
3894 _(sw_interface_set_vxlan_bypass_reply)                  \
3895 _(sw_interface_set_l2_bridge_reply)                     \
3896 _(bridge_domain_add_del_reply)                          \
3897 _(sw_interface_set_l2_xconnect_reply)                   \
3898 _(l2fib_add_del_reply)                                  \
3899 _(ip_add_del_route_reply)                               \
3900 _(ip_mroute_add_del_reply)                              \
3901 _(mpls_route_add_del_reply)                             \
3902 _(mpls_ip_bind_unbind_reply)                            \
3903 _(proxy_arp_add_del_reply)                              \
3904 _(proxy_arp_intfc_enable_disable_reply)                 \
3905 _(sw_interface_set_unnumbered_reply)                    \
3906 _(ip_neighbor_add_del_reply)                            \
3907 _(reset_vrf_reply)                                      \
3908 _(oam_add_del_reply)                                    \
3909 _(reset_fib_reply)                                      \
3910 _(dhcp_proxy_config_reply)                              \
3911 _(dhcp_proxy_set_vss_reply)                             \
3912 _(dhcp_client_config_reply)                             \
3913 _(set_ip_flow_hash_reply)                               \
3914 _(sw_interface_ip6_enable_disable_reply)                \
3915 _(sw_interface_ip6_set_link_local_address_reply)        \
3916 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3917 _(sw_interface_ip6nd_ra_config_reply)                   \
3918 _(set_arp_neighbor_limit_reply)                         \
3919 _(l2_patch_add_del_reply)                               \
3920 _(sr_policy_add_reply)                                  \
3921 _(sr_policy_mod_reply)                                  \
3922 _(sr_policy_del_reply)                                  \
3923 _(sr_localsid_add_del_reply)                            \
3924 _(sr_steering_add_del_reply)                            \
3925 _(classify_add_del_session_reply)                       \
3926 _(classify_set_interface_ip_table_reply)                \
3927 _(classify_set_interface_l2_tables_reply)               \
3928 _(l2tpv3_set_tunnel_cookies_reply)                      \
3929 _(l2tpv3_interface_enable_disable_reply)                \
3930 _(l2tpv3_set_lookup_key_reply)                          \
3931 _(l2_fib_clear_table_reply)                             \
3932 _(l2_interface_efp_filter_reply)                        \
3933 _(l2_interface_vlan_tag_rewrite_reply)                  \
3934 _(modify_vhost_user_if_reply)                           \
3935 _(delete_vhost_user_if_reply)                           \
3936 _(want_ip4_arp_events_reply)                            \
3937 _(want_ip6_nd_events_reply)                             \
3938 _(input_acl_set_interface_reply)                        \
3939 _(ipsec_spd_add_del_reply)                              \
3940 _(ipsec_interface_add_del_spd_reply)                    \
3941 _(ipsec_spd_add_del_entry_reply)                        \
3942 _(ipsec_sad_add_del_entry_reply)                        \
3943 _(ipsec_sa_set_key_reply)                               \
3944 _(ikev2_profile_add_del_reply)                          \
3945 _(ikev2_profile_set_auth_reply)                         \
3946 _(ikev2_profile_set_id_reply)                           \
3947 _(ikev2_profile_set_ts_reply)                           \
3948 _(ikev2_set_local_key_reply)                            \
3949 _(ikev2_set_responder_reply)                            \
3950 _(ikev2_set_ike_transforms_reply)                       \
3951 _(ikev2_set_esp_transforms_reply)                       \
3952 _(ikev2_set_sa_lifetime_reply)                          \
3953 _(ikev2_initiate_sa_init_reply)                         \
3954 _(ikev2_initiate_del_ike_sa_reply)                      \
3955 _(ikev2_initiate_del_child_sa_reply)                    \
3956 _(ikev2_initiate_rekey_child_sa_reply)                  \
3957 _(delete_loopback_reply)                                \
3958 _(bd_ip_mac_add_del_reply)                              \
3959 _(map_del_domain_reply)                                 \
3960 _(map_add_del_rule_reply)                               \
3961 _(want_interface_events_reply)                          \
3962 _(want_stats_reply)                                     \
3963 _(cop_interface_enable_disable_reply)                   \
3964 _(cop_whitelist_enable_disable_reply)                   \
3965 _(sw_interface_clear_stats_reply)                       \
3966 _(ioam_enable_reply)                              \
3967 _(ioam_disable_reply)                              \
3968 _(one_add_del_locator_reply)                            \
3969 _(one_add_del_local_eid_reply)                          \
3970 _(one_add_del_remote_mapping_reply)                     \
3971 _(one_add_del_adjacency_reply)                          \
3972 _(one_add_del_map_resolver_reply)                       \
3973 _(one_add_del_map_server_reply)                         \
3974 _(one_enable_disable_reply)                             \
3975 _(one_rloc_probe_enable_disable_reply)                  \
3976 _(one_map_register_enable_disable_reply)                \
3977 _(one_pitr_set_locator_set_reply)                       \
3978 _(one_map_request_mode_reply)                           \
3979 _(one_add_del_map_request_itr_rlocs_reply)              \
3980 _(one_eid_table_add_del_map_reply)                      \
3981 _(gpe_add_del_fwd_entry_reply)                          \
3982 _(gpe_enable_disable_reply)                             \
3983 _(gpe_set_encap_mode_reply)                             \
3984 _(gpe_add_del_iface_reply)                              \
3985 _(vxlan_gpe_add_del_tunnel_reply)                       \
3986 _(af_packet_delete_reply)                               \
3987 _(policer_classify_set_interface_reply)                 \
3988 _(netmap_create_reply)                                  \
3989 _(netmap_delete_reply)                                  \
3990 _(set_ipfix_exporter_reply)                             \
3991 _(set_ipfix_classify_stream_reply)                      \
3992 _(ipfix_classify_table_add_del_reply)                   \
3993 _(flow_classify_set_interface_reply)                    \
3994 _(sw_interface_span_enable_disable_reply)               \
3995 _(pg_capture_reply)                                     \
3996 _(pg_enable_disable_reply)                              \
3997 _(ip_source_and_port_range_check_add_del_reply)         \
3998 _(ip_source_and_port_range_check_interface_add_del_reply)\
3999 _(delete_subif_reply)                                   \
4000 _(l2_interface_pbb_tag_rewrite_reply)                   \
4001 _(punt_reply)                                           \
4002 _(feature_enable_disable_reply)                         \
4003 _(sw_interface_tag_add_del_reply)                       \
4004 _(sw_interface_set_mtu_reply)
4005
4006 #define _(n)                                    \
4007     static void vl_api_##n##_t_handler          \
4008     (vl_api_##n##_t * mp)                       \
4009     {                                           \
4010         vat_main_t * vam = &vat_main;           \
4011         i32 retval = ntohl(mp->retval);         \
4012         if (vam->async_mode) {                  \
4013             vam->async_errors += (retval < 0);  \
4014         } else {                                \
4015             vam->retval = retval;               \
4016             vam->result_ready = 1;              \
4017         }                                       \
4018     }
4019 foreach_standard_reply_retval_handler;
4020 #undef _
4021
4022 #define _(n)                                    \
4023     static void vl_api_##n##_t_handler_json     \
4024     (vl_api_##n##_t * mp)                       \
4025     {                                           \
4026         vat_main_t * vam = &vat_main;           \
4027         vat_json_node_t node;                   \
4028         vat_json_init_object(&node);            \
4029         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
4030         vat_json_print(vam->ofp, &node);        \
4031         vam->retval = ntohl(mp->retval);        \
4032         vam->result_ready = 1;                  \
4033     }
4034 foreach_standard_reply_retval_handler;
4035 #undef _
4036
4037 /*
4038  * Table of message reply handlers, must include boilerplate handlers
4039  * we just generated
4040  */
4041
4042 #define foreach_vpe_api_reply_msg                                       \
4043 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
4044 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
4045 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
4046 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
4047 _(CONTROL_PING_REPLY, control_ping_reply)                               \
4048 _(CLI_REPLY, cli_reply)                                                 \
4049 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
4050 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
4051   sw_interface_add_del_address_reply)                                   \
4052 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
4053 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
4054 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
4055 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
4056 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
4057   sw_interface_set_l2_xconnect_reply)                                   \
4058 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
4059   sw_interface_set_l2_bridge_reply)                                     \
4060 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
4061 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
4062 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
4063 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
4064 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
4065 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
4066 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
4067 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
4068 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
4069 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
4070 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
4071 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
4072 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
4073 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
4074 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
4075 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
4076   proxy_arp_intfc_enable_disable_reply)                                 \
4077 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
4078 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
4079   sw_interface_set_unnumbered_reply)                                    \
4080 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
4081 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
4082 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
4083 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
4084 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
4085 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
4086 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
4087 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
4088 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
4089 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
4090 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
4091 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
4092   sw_interface_ip6_enable_disable_reply)                                \
4093 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
4094   sw_interface_ip6_set_link_local_address_reply)                        \
4095 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
4096   sw_interface_ip6nd_ra_prefix_reply)                                   \
4097 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
4098   sw_interface_ip6nd_ra_config_reply)                                   \
4099 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
4100 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
4101 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
4102 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
4103 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
4104 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
4105 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
4106 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
4107 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
4108 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
4109 classify_set_interface_ip_table_reply)                                  \
4110 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
4111   classify_set_interface_l2_tables_reply)                               \
4112 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
4113 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
4114 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
4115 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
4116 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
4117   l2tpv3_interface_enable_disable_reply)                                \
4118 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
4119 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
4120 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
4121 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
4122 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
4123 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
4124 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
4125 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
4126 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4127 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
4128 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
4129 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
4130 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
4131 _(SHOW_VERSION_REPLY, show_version_reply)                               \
4132 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
4133 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
4134 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
4135 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
4136 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
4137 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
4138 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
4139 _(IP6_ND_EVENT, ip6_nd_event)                                           \
4140 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
4141 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
4142 _(IP_DETAILS, ip_details)                                               \
4143 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
4144 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4145 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
4146 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
4147 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
4148 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
4149 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
4150 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
4151 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
4152 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
4153 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
4154 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
4155 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
4156 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
4157 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
4158 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
4159 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
4160 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
4161 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
4162 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
4163 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
4164 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
4165 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
4166 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
4167 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
4168 _(MAP_RULE_DETAILS, map_rule_details)                                   \
4169 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
4170 _(WANT_STATS_REPLY, want_stats_reply)                                   \
4171 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
4172 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4173 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4174 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
4175 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
4176 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
4177 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
4178 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
4179 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
4180 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
4181 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
4182 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
4183 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
4184 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
4185 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
4186 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
4187   one_map_register_enable_disable_reply)                                \
4188 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
4189   one_rloc_probe_enable_disable_reply)                                  \
4190 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
4191 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
4192 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
4193 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
4194 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
4195 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
4196 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
4197 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
4198 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
4199 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
4200 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
4201 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
4202 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
4203 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
4204 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
4205 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
4206 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
4207 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
4208   gpe_fwd_entry_path_details)                                           \
4209 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
4210 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
4211   one_add_del_map_request_itr_rlocs_reply)                              \
4212 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
4213   one_get_map_request_itr_rlocs_reply)                                  \
4214 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
4215 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
4216 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
4217 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
4218   show_one_map_register_state_reply)                                    \
4219 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
4220 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
4221 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
4222 _(POLICER_DETAILS, policer_details)                                     \
4223 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4224 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
4225 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
4226 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
4227 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
4228 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
4229 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
4230 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4231 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
4232 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
4233 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
4234 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
4235 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
4236 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
4237 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4238 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
4239 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4240 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
4241 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
4242 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
4243 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
4244 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
4245 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
4246 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
4247 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
4248  ip_source_and_port_range_check_add_del_reply)                          \
4249 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
4250  ip_source_and_port_range_check_interface_add_del_reply)                \
4251 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
4252 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
4253 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
4254 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
4255 _(PUNT_REPLY, punt_reply)                                               \
4256 _(IP_FIB_DETAILS, ip_fib_details)                                       \
4257 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
4258 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
4259 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
4260 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
4261 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
4262 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
4263 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
4264
4265 #define foreach_standalone_reply_msg                                    \
4266 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
4267 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
4268 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
4269 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
4270 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
4271 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
4272
4273 typedef struct
4274 {
4275   u8 *name;
4276   u32 value;
4277 } name_sort_t;
4278
4279
4280 #define STR_VTR_OP_CASE(op)     \
4281     case L2_VTR_ ## op:         \
4282         return "" # op;
4283
4284 static const char *
4285 str_vtr_op (u32 vtr_op)
4286 {
4287   switch (vtr_op)
4288     {
4289       STR_VTR_OP_CASE (DISABLED);
4290       STR_VTR_OP_CASE (PUSH_1);
4291       STR_VTR_OP_CASE (PUSH_2);
4292       STR_VTR_OP_CASE (POP_1);
4293       STR_VTR_OP_CASE (POP_2);
4294       STR_VTR_OP_CASE (TRANSLATE_1_1);
4295       STR_VTR_OP_CASE (TRANSLATE_1_2);
4296       STR_VTR_OP_CASE (TRANSLATE_2_1);
4297       STR_VTR_OP_CASE (TRANSLATE_2_2);
4298     }
4299
4300   return "UNKNOWN";
4301 }
4302
4303 static int
4304 dump_sub_interface_table (vat_main_t * vam)
4305 {
4306   const sw_interface_subif_t *sub = NULL;
4307
4308   if (vam->json_output)
4309     {
4310       clib_warning
4311         ("JSON output supported only for VPE API calls and dump_stats_table");
4312       return -99;
4313     }
4314
4315   print (vam->ofp,
4316          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4317          "Interface", "sw_if_index",
4318          "sub id", "dot1ad", "tags", "outer id",
4319          "inner id", "exact", "default", "outer any", "inner any");
4320
4321   vec_foreach (sub, vam->sw_if_subif_table)
4322   {
4323     print (vam->ofp,
4324            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4325            sub->interface_name,
4326            sub->sw_if_index,
4327            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4328            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4329            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4330            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4331     if (sub->vtr_op != L2_VTR_DISABLED)
4332       {
4333         print (vam->ofp,
4334                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4335                "tag1: %d tag2: %d ]",
4336                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4337                sub->vtr_tag1, sub->vtr_tag2);
4338       }
4339   }
4340
4341   return 0;
4342 }
4343
4344 static int
4345 name_sort_cmp (void *a1, void *a2)
4346 {
4347   name_sort_t *n1 = a1;
4348   name_sort_t *n2 = a2;
4349
4350   return strcmp ((char *) n1->name, (char *) n2->name);
4351 }
4352
4353 static int
4354 dump_interface_table (vat_main_t * vam)
4355 {
4356   hash_pair_t *p;
4357   name_sort_t *nses = 0, *ns;
4358
4359   if (vam->json_output)
4360     {
4361       clib_warning
4362         ("JSON output supported only for VPE API calls and dump_stats_table");
4363       return -99;
4364     }
4365
4366   /* *INDENT-OFF* */
4367   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4368   ({
4369     vec_add2 (nses, ns, 1);
4370     ns->name = (u8 *)(p->key);
4371     ns->value = (u32) p->value[0];
4372   }));
4373   /* *INDENT-ON* */
4374
4375   vec_sort_with_function (nses, name_sort_cmp);
4376
4377   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4378   vec_foreach (ns, nses)
4379   {
4380     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4381   }
4382   vec_free (nses);
4383   return 0;
4384 }
4385
4386 static int
4387 dump_ip_table (vat_main_t * vam, int is_ipv6)
4388 {
4389   const ip_details_t *det = NULL;
4390   const ip_address_details_t *address = NULL;
4391   u32 i = ~0;
4392
4393   print (vam->ofp, "%-12s", "sw_if_index");
4394
4395   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4396   {
4397     i++;
4398     if (!det->present)
4399       {
4400         continue;
4401       }
4402     print (vam->ofp, "%-12d", i);
4403     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
4404     if (!det->addr)
4405       {
4406         continue;
4407       }
4408     vec_foreach (address, det->addr)
4409     {
4410       print (vam->ofp,
4411              "            %-30U%-13d",
4412              is_ipv6 ? format_ip6_address : format_ip4_address,
4413              address->ip, address->prefix_length);
4414     }
4415   }
4416
4417   return 0;
4418 }
4419
4420 static int
4421 dump_ipv4_table (vat_main_t * vam)
4422 {
4423   if (vam->json_output)
4424     {
4425       clib_warning
4426         ("JSON output supported only for VPE API calls and dump_stats_table");
4427       return -99;
4428     }
4429
4430   return dump_ip_table (vam, 0);
4431 }
4432
4433 static int
4434 dump_ipv6_table (vat_main_t * vam)
4435 {
4436   if (vam->json_output)
4437     {
4438       clib_warning
4439         ("JSON output supported only for VPE API calls and dump_stats_table");
4440       return -99;
4441     }
4442
4443   return dump_ip_table (vam, 1);
4444 }
4445
4446 static char *
4447 counter_type_to_str (u8 counter_type, u8 is_combined)
4448 {
4449   if (!is_combined)
4450     {
4451       switch (counter_type)
4452         {
4453         case VNET_INTERFACE_COUNTER_DROP:
4454           return "drop";
4455         case VNET_INTERFACE_COUNTER_PUNT:
4456           return "punt";
4457         case VNET_INTERFACE_COUNTER_IP4:
4458           return "ip4";
4459         case VNET_INTERFACE_COUNTER_IP6:
4460           return "ip6";
4461         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4462           return "rx-no-buf";
4463         case VNET_INTERFACE_COUNTER_RX_MISS:
4464           return "rx-miss";
4465         case VNET_INTERFACE_COUNTER_RX_ERROR:
4466           return "rx-error";
4467         case VNET_INTERFACE_COUNTER_TX_ERROR:
4468           return "tx-error";
4469         default:
4470           return "INVALID-COUNTER-TYPE";
4471         }
4472     }
4473   else
4474     {
4475       switch (counter_type)
4476         {
4477         case VNET_INTERFACE_COUNTER_RX:
4478           return "rx";
4479         case VNET_INTERFACE_COUNTER_TX:
4480           return "tx";
4481         default:
4482           return "INVALID-COUNTER-TYPE";
4483         }
4484     }
4485 }
4486
4487 static int
4488 dump_stats_table (vat_main_t * vam)
4489 {
4490   vat_json_node_t node;
4491   vat_json_node_t *msg_array;
4492   vat_json_node_t *msg;
4493   vat_json_node_t *counter_array;
4494   vat_json_node_t *counter;
4495   interface_counter_t c;
4496   u64 packets;
4497   ip4_fib_counter_t *c4;
4498   ip6_fib_counter_t *c6;
4499   ip4_nbr_counter_t *n4;
4500   ip6_nbr_counter_t *n6;
4501   int i, j;
4502
4503   if (!vam->json_output)
4504     {
4505       clib_warning ("dump_stats_table supported only in JSON format");
4506       return -99;
4507     }
4508
4509   vat_json_init_object (&node);
4510
4511   /* interface counters */
4512   msg_array = vat_json_object_add (&node, "interface_counters");
4513   vat_json_init_array (msg_array);
4514   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4515     {
4516       msg = vat_json_array_add (msg_array);
4517       vat_json_init_object (msg);
4518       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4519                                        (u8 *) counter_type_to_str (i, 0));
4520       vat_json_object_add_int (msg, "is_combined", 0);
4521       counter_array = vat_json_object_add (msg, "data");
4522       vat_json_init_array (counter_array);
4523       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4524         {
4525           packets = vam->simple_interface_counters[i][j];
4526           vat_json_array_add_uint (counter_array, packets);
4527         }
4528     }
4529   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4530     {
4531       msg = vat_json_array_add (msg_array);
4532       vat_json_init_object (msg);
4533       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4534                                        (u8 *) counter_type_to_str (i, 1));
4535       vat_json_object_add_int (msg, "is_combined", 1);
4536       counter_array = vat_json_object_add (msg, "data");
4537       vat_json_init_array (counter_array);
4538       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4539         {
4540           c = vam->combined_interface_counters[i][j];
4541           counter = vat_json_array_add (counter_array);
4542           vat_json_init_object (counter);
4543           vat_json_object_add_uint (counter, "packets", c.packets);
4544           vat_json_object_add_uint (counter, "bytes", c.bytes);
4545         }
4546     }
4547
4548   /* ip4 fib counters */
4549   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4550   vat_json_init_array (msg_array);
4551   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4552     {
4553       msg = vat_json_array_add (msg_array);
4554       vat_json_init_object (msg);
4555       vat_json_object_add_uint (msg, "vrf_id",
4556                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4557       counter_array = vat_json_object_add (msg, "c");
4558       vat_json_init_array (counter_array);
4559       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4560         {
4561           counter = vat_json_array_add (counter_array);
4562           vat_json_init_object (counter);
4563           c4 = &vam->ip4_fib_counters[i][j];
4564           vat_json_object_add_ip4 (counter, "address", c4->address);
4565           vat_json_object_add_uint (counter, "address_length",
4566                                     c4->address_length);
4567           vat_json_object_add_uint (counter, "packets", c4->packets);
4568           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4569         }
4570     }
4571
4572   /* ip6 fib counters */
4573   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4574   vat_json_init_array (msg_array);
4575   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4576     {
4577       msg = vat_json_array_add (msg_array);
4578       vat_json_init_object (msg);
4579       vat_json_object_add_uint (msg, "vrf_id",
4580                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4581       counter_array = vat_json_object_add (msg, "c");
4582       vat_json_init_array (counter_array);
4583       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4584         {
4585           counter = vat_json_array_add (counter_array);
4586           vat_json_init_object (counter);
4587           c6 = &vam->ip6_fib_counters[i][j];
4588           vat_json_object_add_ip6 (counter, "address", c6->address);
4589           vat_json_object_add_uint (counter, "address_length",
4590                                     c6->address_length);
4591           vat_json_object_add_uint (counter, "packets", c6->packets);
4592           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4593         }
4594     }
4595
4596   /* ip4 nbr counters */
4597   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
4598   vat_json_init_array (msg_array);
4599   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
4600     {
4601       msg = vat_json_array_add (msg_array);
4602       vat_json_init_object (msg);
4603       vat_json_object_add_uint (msg, "sw_if_index", i);
4604       counter_array = vat_json_object_add (msg, "c");
4605       vat_json_init_array (counter_array);
4606       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
4607         {
4608           counter = vat_json_array_add (counter_array);
4609           vat_json_init_object (counter);
4610           n4 = &vam->ip4_nbr_counters[i][j];
4611           vat_json_object_add_ip4 (counter, "address", n4->address);
4612           vat_json_object_add_uint (counter, "link-type", n4->linkt);
4613           vat_json_object_add_uint (counter, "packets", n4->packets);
4614           vat_json_object_add_uint (counter, "bytes", n4->bytes);
4615         }
4616     }
4617
4618   /* ip6 nbr counters */
4619   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
4620   vat_json_init_array (msg_array);
4621   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
4622     {
4623       msg = vat_json_array_add (msg_array);
4624       vat_json_init_object (msg);
4625       vat_json_object_add_uint (msg, "sw_if_index", i);
4626       counter_array = vat_json_object_add (msg, "c");
4627       vat_json_init_array (counter_array);
4628       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
4629         {
4630           counter = vat_json_array_add (counter_array);
4631           vat_json_init_object (counter);
4632           n6 = &vam->ip6_nbr_counters[i][j];
4633           vat_json_object_add_ip6 (counter, "address", n6->address);
4634           vat_json_object_add_uint (counter, "packets", n6->packets);
4635           vat_json_object_add_uint (counter, "bytes", n6->bytes);
4636         }
4637     }
4638
4639   vat_json_print (vam->ofp, &node);
4640   vat_json_free (&node);
4641
4642   return 0;
4643 }
4644
4645 int
4646 exec (vat_main_t * vam)
4647 {
4648   api_main_t *am = &api_main;
4649   vl_api_cli_request_t *mp;
4650   f64 timeout;
4651   void *oldheap;
4652   u8 *cmd = 0;
4653   unformat_input_t *i = vam->input;
4654
4655   if (vec_len (i->buffer) == 0)
4656     return -1;
4657
4658   if (vam->exec_mode == 0 && unformat (i, "mode"))
4659     {
4660       vam->exec_mode = 1;
4661       return 0;
4662     }
4663   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4664     {
4665       vam->exec_mode = 0;
4666       return 0;
4667     }
4668
4669
4670   M (CLI_REQUEST, mp);
4671
4672   /*
4673    * Copy cmd into shared memory.
4674    * In order for the CLI command to work, it
4675    * must be a vector ending in \n, not a C-string ending
4676    * in \n\0.
4677    */
4678   pthread_mutex_lock (&am->vlib_rp->mutex);
4679   oldheap = svm_push_data_heap (am->vlib_rp);
4680
4681   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4682   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4683
4684   svm_pop_heap (oldheap);
4685   pthread_mutex_unlock (&am->vlib_rp->mutex);
4686
4687   mp->cmd_in_shmem = (u64) cmd;
4688   S (mp);
4689   timeout = vat_time_now (vam) + 10.0;
4690
4691   while (vat_time_now (vam) < timeout)
4692     {
4693       if (vam->result_ready == 1)
4694         {
4695           u8 *free_me;
4696           if (vam->shmem_result != NULL)
4697             print (vam->ofp, "%s", vam->shmem_result);
4698           pthread_mutex_lock (&am->vlib_rp->mutex);
4699           oldheap = svm_push_data_heap (am->vlib_rp);
4700
4701           free_me = (u8 *) vam->shmem_result;
4702           vec_free (free_me);
4703
4704           svm_pop_heap (oldheap);
4705           pthread_mutex_unlock (&am->vlib_rp->mutex);
4706           return 0;
4707         }
4708     }
4709   return -99;
4710 }
4711
4712 /*
4713  * Future replacement of exec() that passes CLI buffers directly in
4714  * the API messages instead of an additional shared memory area.
4715  */
4716 static int
4717 exec_inband (vat_main_t * vam)
4718 {
4719   vl_api_cli_inband_t *mp;
4720   unformat_input_t *i = vam->input;
4721   int ret;
4722
4723   if (vec_len (i->buffer) == 0)
4724     return -1;
4725
4726   if (vam->exec_mode == 0 && unformat (i, "mode"))
4727     {
4728       vam->exec_mode = 1;
4729       return 0;
4730     }
4731   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4732     {
4733       vam->exec_mode = 0;
4734       return 0;
4735     }
4736
4737   /*
4738    * In order for the CLI command to work, it
4739    * must be a vector ending in \n, not a C-string ending
4740    * in \n\0.
4741    */
4742   u32 len = vec_len (vam->input->buffer);
4743   M2 (CLI_INBAND, mp, len);
4744   clib_memcpy (mp->cmd, vam->input->buffer, len);
4745   mp->length = htonl (len);
4746
4747   S (mp);
4748   W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
4749   return ret;
4750 }
4751
4752 static int
4753 api_create_loopback (vat_main_t * vam)
4754 {
4755   unformat_input_t *i = vam->input;
4756   vl_api_create_loopback_t *mp;
4757   vl_api_create_loopback_instance_t *mp_lbi;
4758   u8 mac_address[6];
4759   u8 mac_set = 0;
4760   u8 is_specified = 0;
4761   u32 user_instance = 0;
4762   int ret;
4763
4764   memset (mac_address, 0, sizeof (mac_address));
4765
4766   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4767     {
4768       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4769         mac_set = 1;
4770       if (unformat (i, "instance %d", &user_instance))
4771         is_specified = 1;
4772       else
4773         break;
4774     }
4775
4776   if (is_specified)
4777     {
4778       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
4779       mp_lbi->is_specified = is_specified;
4780       if (is_specified)
4781         mp_lbi->user_instance = htonl (user_instance);
4782       if (mac_set)
4783         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
4784       S (mp_lbi);
4785     }
4786   else
4787     {
4788       /* Construct the API message */
4789       M (CREATE_LOOPBACK, mp);
4790       if (mac_set)
4791         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4792       S (mp);
4793     }
4794
4795   W (ret);
4796   return ret;
4797 }
4798
4799 static int
4800 api_delete_loopback (vat_main_t * vam)
4801 {
4802   unformat_input_t *i = vam->input;
4803   vl_api_delete_loopback_t *mp;
4804   u32 sw_if_index = ~0;
4805   int ret;
4806
4807   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4808     {
4809       if (unformat (i, "sw_if_index %d", &sw_if_index))
4810         ;
4811       else
4812         break;
4813     }
4814
4815   if (sw_if_index == ~0)
4816     {
4817       errmsg ("missing sw_if_index");
4818       return -99;
4819     }
4820
4821   /* Construct the API message */
4822   M (DELETE_LOOPBACK, mp);
4823   mp->sw_if_index = ntohl (sw_if_index);
4824
4825   S (mp);
4826   W (ret);
4827   return ret;
4828 }
4829
4830 static int
4831 api_want_stats (vat_main_t * vam)
4832 {
4833   unformat_input_t *i = vam->input;
4834   vl_api_want_stats_t *mp;
4835   int enable = -1;
4836   int ret;
4837
4838   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4839     {
4840       if (unformat (i, "enable"))
4841         enable = 1;
4842       else if (unformat (i, "disable"))
4843         enable = 0;
4844       else
4845         break;
4846     }
4847
4848   if (enable == -1)
4849     {
4850       errmsg ("missing enable|disable");
4851       return -99;
4852     }
4853
4854   M (WANT_STATS, mp);
4855   mp->enable_disable = enable;
4856
4857   S (mp);
4858   W (ret);
4859   return ret;
4860 }
4861
4862 static int
4863 api_want_interface_events (vat_main_t * vam)
4864 {
4865   unformat_input_t *i = vam->input;
4866   vl_api_want_interface_events_t *mp;
4867   int enable = -1;
4868   int ret;
4869
4870   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4871     {
4872       if (unformat (i, "enable"))
4873         enable = 1;
4874       else if (unformat (i, "disable"))
4875         enable = 0;
4876       else
4877         break;
4878     }
4879
4880   if (enable == -1)
4881     {
4882       errmsg ("missing enable|disable");
4883       return -99;
4884     }
4885
4886   M (WANT_INTERFACE_EVENTS, mp);
4887   mp->enable_disable = enable;
4888
4889   vam->interface_event_display = enable;
4890
4891   S (mp);
4892   W (ret);
4893   return ret;
4894 }
4895
4896
4897 /* Note: non-static, called once to set up the initial intfc table */
4898 int
4899 api_sw_interface_dump (vat_main_t * vam)
4900 {
4901   vl_api_sw_interface_dump_t *mp;
4902   vl_api_control_ping_t *mp_ping;
4903   hash_pair_t *p;
4904   name_sort_t *nses = 0, *ns;
4905   sw_interface_subif_t *sub = NULL;
4906   int ret;
4907
4908   /* Toss the old name table */
4909   /* *INDENT-OFF* */
4910   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4911   ({
4912     vec_add2 (nses, ns, 1);
4913     ns->name = (u8 *)(p->key);
4914     ns->value = (u32) p->value[0];
4915   }));
4916   /* *INDENT-ON* */
4917
4918   hash_free (vam->sw_if_index_by_interface_name);
4919
4920   vec_foreach (ns, nses) vec_free (ns->name);
4921
4922   vec_free (nses);
4923
4924   vec_foreach (sub, vam->sw_if_subif_table)
4925   {
4926     vec_free (sub->interface_name);
4927   }
4928   vec_free (vam->sw_if_subif_table);
4929
4930   /* recreate the interface name hash table */
4931   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4932
4933   /* Get list of ethernets */
4934   M (SW_INTERFACE_DUMP, mp);
4935   mp->name_filter_valid = 1;
4936   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4937   S (mp);
4938
4939   /* and local / loopback interfaces */
4940   M (SW_INTERFACE_DUMP, mp);
4941   mp->name_filter_valid = 1;
4942   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4943   S (mp);
4944
4945   /* and packet-generator interfaces */
4946   M (SW_INTERFACE_DUMP, mp);
4947   mp->name_filter_valid = 1;
4948   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4949   S (mp);
4950
4951   /* and vxlan-gpe tunnel interfaces */
4952   M (SW_INTERFACE_DUMP, mp);
4953   mp->name_filter_valid = 1;
4954   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4955            sizeof (mp->name_filter) - 1);
4956   S (mp);
4957
4958   /* and vxlan tunnel interfaces */
4959   M (SW_INTERFACE_DUMP, mp);
4960   mp->name_filter_valid = 1;
4961   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4962   S (mp);
4963
4964   /* and host (af_packet) interfaces */
4965   M (SW_INTERFACE_DUMP, mp);
4966   mp->name_filter_valid = 1;
4967   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4968   S (mp);
4969
4970   /* and l2tpv3 tunnel interfaces */
4971   M (SW_INTERFACE_DUMP, mp);
4972   mp->name_filter_valid = 1;
4973   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4974            sizeof (mp->name_filter) - 1);
4975   S (mp);
4976
4977   /* and GRE tunnel interfaces */
4978   M (SW_INTERFACE_DUMP, mp);
4979   mp->name_filter_valid = 1;
4980   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4981   S (mp);
4982
4983   /* and LISP-GPE interfaces */
4984   M (SW_INTERFACE_DUMP, mp);
4985   mp->name_filter_valid = 1;
4986   strncpy ((char *) mp->name_filter, "lisp_gpe",
4987            sizeof (mp->name_filter) - 1);
4988   S (mp);
4989
4990   /* and IPSEC tunnel interfaces */
4991   M (SW_INTERFACE_DUMP, mp);
4992   mp->name_filter_valid = 1;
4993   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4994   S (mp);
4995
4996   /* Use a control ping for synchronization */
4997   M (CONTROL_PING, mp_ping);
4998   S (mp_ping);
4999
5000   W (ret);
5001   return ret;
5002 }
5003
5004 static int
5005 api_sw_interface_set_flags (vat_main_t * vam)
5006 {
5007   unformat_input_t *i = vam->input;
5008   vl_api_sw_interface_set_flags_t *mp;
5009   u32 sw_if_index;
5010   u8 sw_if_index_set = 0;
5011   u8 admin_up = 0, link_up = 0;
5012   int ret;
5013
5014   /* Parse args required to build the message */
5015   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5016     {
5017       if (unformat (i, "admin-up"))
5018         admin_up = 1;
5019       else if (unformat (i, "admin-down"))
5020         admin_up = 0;
5021       else if (unformat (i, "link-up"))
5022         link_up = 1;
5023       else if (unformat (i, "link-down"))
5024         link_up = 0;
5025       else
5026         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5027         sw_if_index_set = 1;
5028       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5029         sw_if_index_set = 1;
5030       else
5031         break;
5032     }
5033
5034   if (sw_if_index_set == 0)
5035     {
5036       errmsg ("missing interface name or sw_if_index");
5037       return -99;
5038     }
5039
5040   /* Construct the API message */
5041   M (SW_INTERFACE_SET_FLAGS, mp);
5042   mp->sw_if_index = ntohl (sw_if_index);
5043   mp->admin_up_down = admin_up;
5044   mp->link_up_down = link_up;
5045
5046   /* send it... */
5047   S (mp);
5048
5049   /* Wait for a reply, return the good/bad news... */
5050   W (ret);
5051   return ret;
5052 }
5053
5054 static int
5055 api_sw_interface_clear_stats (vat_main_t * vam)
5056 {
5057   unformat_input_t *i = vam->input;
5058   vl_api_sw_interface_clear_stats_t *mp;
5059   u32 sw_if_index;
5060   u8 sw_if_index_set = 0;
5061   int ret;
5062
5063   /* Parse args required to build the message */
5064   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5065     {
5066       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5067         sw_if_index_set = 1;
5068       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5069         sw_if_index_set = 1;
5070       else
5071         break;
5072     }
5073
5074   /* Construct the API message */
5075   M (SW_INTERFACE_CLEAR_STATS, mp);
5076
5077   if (sw_if_index_set == 1)
5078     mp->sw_if_index = ntohl (sw_if_index);
5079   else
5080     mp->sw_if_index = ~0;
5081
5082   /* send it... */
5083   S (mp);
5084
5085   /* Wait for a reply, return the good/bad news... */
5086   W (ret);
5087   return ret;
5088 }
5089
5090 static int
5091 api_sw_interface_add_del_address (vat_main_t * vam)
5092 {
5093   unformat_input_t *i = vam->input;
5094   vl_api_sw_interface_add_del_address_t *mp;
5095   u32 sw_if_index;
5096   u8 sw_if_index_set = 0;
5097   u8 is_add = 1, del_all = 0;
5098   u32 address_length = 0;
5099   u8 v4_address_set = 0;
5100   u8 v6_address_set = 0;
5101   ip4_address_t v4address;
5102   ip6_address_t v6address;
5103   int ret;
5104
5105   /* Parse args required to build the message */
5106   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5107     {
5108       if (unformat (i, "del-all"))
5109         del_all = 1;
5110       else if (unformat (i, "del"))
5111         is_add = 0;
5112       else
5113         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5114         sw_if_index_set = 1;
5115       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5116         sw_if_index_set = 1;
5117       else if (unformat (i, "%U/%d",
5118                          unformat_ip4_address, &v4address, &address_length))
5119         v4_address_set = 1;
5120       else if (unformat (i, "%U/%d",
5121                          unformat_ip6_address, &v6address, &address_length))
5122         v6_address_set = 1;
5123       else
5124         break;
5125     }
5126
5127   if (sw_if_index_set == 0)
5128     {
5129       errmsg ("missing interface name or sw_if_index");
5130       return -99;
5131     }
5132   if (v4_address_set && v6_address_set)
5133     {
5134       errmsg ("both v4 and v6 addresses set");
5135       return -99;
5136     }
5137   if (!v4_address_set && !v6_address_set && !del_all)
5138     {
5139       errmsg ("no addresses set");
5140       return -99;
5141     }
5142
5143   /* Construct the API message */
5144   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
5145
5146   mp->sw_if_index = ntohl (sw_if_index);
5147   mp->is_add = is_add;
5148   mp->del_all = del_all;
5149   if (v6_address_set)
5150     {
5151       mp->is_ipv6 = 1;
5152       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5153     }
5154   else
5155     {
5156       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5157     }
5158   mp->address_length = address_length;
5159
5160   /* send it... */
5161   S (mp);
5162
5163   /* Wait for a reply, return good/bad news  */
5164   W (ret);
5165   return ret;
5166 }
5167
5168 static int
5169 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5170 {
5171   unformat_input_t *i = vam->input;
5172   vl_api_sw_interface_set_mpls_enable_t *mp;
5173   u32 sw_if_index;
5174   u8 sw_if_index_set = 0;
5175   u8 enable = 1;
5176   int ret;
5177
5178   /* Parse args required to build the message */
5179   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5180     {
5181       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5182         sw_if_index_set = 1;
5183       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5184         sw_if_index_set = 1;
5185       else if (unformat (i, "disable"))
5186         enable = 0;
5187       else if (unformat (i, "dis"))
5188         enable = 0;
5189       else
5190         break;
5191     }
5192
5193   if (sw_if_index_set == 0)
5194     {
5195       errmsg ("missing interface name or sw_if_index");
5196       return -99;
5197     }
5198
5199   /* Construct the API message */
5200   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
5201
5202   mp->sw_if_index = ntohl (sw_if_index);
5203   mp->enable = enable;
5204
5205   /* send it... */
5206   S (mp);
5207
5208   /* Wait for a reply... */
5209   W (ret);
5210   return ret;
5211 }
5212
5213 static int
5214 api_sw_interface_set_table (vat_main_t * vam)
5215 {
5216   unformat_input_t *i = vam->input;
5217   vl_api_sw_interface_set_table_t *mp;
5218   u32 sw_if_index, vrf_id = 0;
5219   u8 sw_if_index_set = 0;
5220   u8 is_ipv6 = 0;
5221   int ret;
5222
5223   /* Parse args required to build the message */
5224   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5225     {
5226       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5227         sw_if_index_set = 1;
5228       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5229         sw_if_index_set = 1;
5230       else if (unformat (i, "vrf %d", &vrf_id))
5231         ;
5232       else if (unformat (i, "ipv6"))
5233         is_ipv6 = 1;
5234       else
5235         break;
5236     }
5237
5238   if (sw_if_index_set == 0)
5239     {
5240       errmsg ("missing interface name or sw_if_index");
5241       return -99;
5242     }
5243
5244   /* Construct the API message */
5245   M (SW_INTERFACE_SET_TABLE, mp);
5246
5247   mp->sw_if_index = ntohl (sw_if_index);
5248   mp->is_ipv6 = is_ipv6;
5249   mp->vrf_id = ntohl (vrf_id);
5250
5251   /* send it... */
5252   S (mp);
5253
5254   /* Wait for a reply... */
5255   W (ret);
5256   return ret;
5257 }
5258
5259 static void vl_api_sw_interface_get_table_reply_t_handler
5260   (vl_api_sw_interface_get_table_reply_t * mp)
5261 {
5262   vat_main_t *vam = &vat_main;
5263
5264   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5265
5266   vam->retval = ntohl (mp->retval);
5267   vam->result_ready = 1;
5268
5269 }
5270
5271 static void vl_api_sw_interface_get_table_reply_t_handler_json
5272   (vl_api_sw_interface_get_table_reply_t * mp)
5273 {
5274   vat_main_t *vam = &vat_main;
5275   vat_json_node_t node;
5276
5277   vat_json_init_object (&node);
5278   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5279   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5280
5281   vat_json_print (vam->ofp, &node);
5282   vat_json_free (&node);
5283
5284   vam->retval = ntohl (mp->retval);
5285   vam->result_ready = 1;
5286 }
5287
5288 static int
5289 api_sw_interface_get_table (vat_main_t * vam)
5290 {
5291   unformat_input_t *i = vam->input;
5292   vl_api_sw_interface_get_table_t *mp;
5293   u32 sw_if_index;
5294   u8 sw_if_index_set = 0;
5295   u8 is_ipv6 = 0;
5296   int ret;
5297
5298   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5299     {
5300       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5301         sw_if_index_set = 1;
5302       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5303         sw_if_index_set = 1;
5304       else if (unformat (i, "ipv6"))
5305         is_ipv6 = 1;
5306       else
5307         break;
5308     }
5309
5310   if (sw_if_index_set == 0)
5311     {
5312       errmsg ("missing interface name or sw_if_index");
5313       return -99;
5314     }
5315
5316   M (SW_INTERFACE_GET_TABLE, mp);
5317   mp->sw_if_index = htonl (sw_if_index);
5318   mp->is_ipv6 = is_ipv6;
5319
5320   S (mp);
5321   W (ret);
5322   return ret;
5323 }
5324
5325 static int
5326 api_sw_interface_set_vpath (vat_main_t * vam)
5327 {
5328   unformat_input_t *i = vam->input;
5329   vl_api_sw_interface_set_vpath_t *mp;
5330   u32 sw_if_index = 0;
5331   u8 sw_if_index_set = 0;
5332   u8 is_enable = 0;
5333   int ret;
5334
5335   /* Parse args required to build the message */
5336   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5337     {
5338       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5339         sw_if_index_set = 1;
5340       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5341         sw_if_index_set = 1;
5342       else if (unformat (i, "enable"))
5343         is_enable = 1;
5344       else if (unformat (i, "disable"))
5345         is_enable = 0;
5346       else
5347         break;
5348     }
5349
5350   if (sw_if_index_set == 0)
5351     {
5352       errmsg ("missing interface name or sw_if_index");
5353       return -99;
5354     }
5355
5356   /* Construct the API message */
5357   M (SW_INTERFACE_SET_VPATH, mp);
5358
5359   mp->sw_if_index = ntohl (sw_if_index);
5360   mp->enable = is_enable;
5361
5362   /* send it... */
5363   S (mp);
5364
5365   /* Wait for a reply... */
5366   W (ret);
5367   return ret;
5368 }
5369
5370 static int
5371 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5372 {
5373   unformat_input_t *i = vam->input;
5374   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5375   u32 sw_if_index = 0;
5376   u8 sw_if_index_set = 0;
5377   u8 is_enable = 1;
5378   u8 is_ipv6 = 0;
5379   int ret;
5380
5381   /* Parse args required to build the message */
5382   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5383     {
5384       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5385         sw_if_index_set = 1;
5386       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5387         sw_if_index_set = 1;
5388       else if (unformat (i, "enable"))
5389         is_enable = 1;
5390       else if (unformat (i, "disable"))
5391         is_enable = 0;
5392       else if (unformat (i, "ip4"))
5393         is_ipv6 = 0;
5394       else if (unformat (i, "ip6"))
5395         is_ipv6 = 1;
5396       else
5397         break;
5398     }
5399
5400   if (sw_if_index_set == 0)
5401     {
5402       errmsg ("missing interface name or sw_if_index");
5403       return -99;
5404     }
5405
5406   /* Construct the API message */
5407   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
5408
5409   mp->sw_if_index = ntohl (sw_if_index);
5410   mp->enable = is_enable;
5411   mp->is_ipv6 = is_ipv6;
5412
5413   /* send it... */
5414   S (mp);
5415
5416   /* Wait for a reply... */
5417   W (ret);
5418   return ret;
5419 }
5420
5421 static int
5422 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5423 {
5424   unformat_input_t *i = vam->input;
5425   vl_api_sw_interface_set_l2_xconnect_t *mp;
5426   u32 rx_sw_if_index;
5427   u8 rx_sw_if_index_set = 0;
5428   u32 tx_sw_if_index;
5429   u8 tx_sw_if_index_set = 0;
5430   u8 enable = 1;
5431   int ret;
5432
5433   /* Parse args required to build the message */
5434   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5435     {
5436       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5437         rx_sw_if_index_set = 1;
5438       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5439         tx_sw_if_index_set = 1;
5440       else if (unformat (i, "rx"))
5441         {
5442           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5443             {
5444               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5445                             &rx_sw_if_index))
5446                 rx_sw_if_index_set = 1;
5447             }
5448           else
5449             break;
5450         }
5451       else if (unformat (i, "tx"))
5452         {
5453           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5454             {
5455               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5456                             &tx_sw_if_index))
5457                 tx_sw_if_index_set = 1;
5458             }
5459           else
5460             break;
5461         }
5462       else if (unformat (i, "enable"))
5463         enable = 1;
5464       else if (unformat (i, "disable"))
5465         enable = 0;
5466       else
5467         break;
5468     }
5469
5470   if (rx_sw_if_index_set == 0)
5471     {
5472       errmsg ("missing rx interface name or rx_sw_if_index");
5473       return -99;
5474     }
5475
5476   if (enable && (tx_sw_if_index_set == 0))
5477     {
5478       errmsg ("missing tx interface name or tx_sw_if_index");
5479       return -99;
5480     }
5481
5482   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
5483
5484   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5485   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5486   mp->enable = enable;
5487
5488   S (mp);
5489   W (ret);
5490   return ret;
5491 }
5492
5493 static int
5494 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5495 {
5496   unformat_input_t *i = vam->input;
5497   vl_api_sw_interface_set_l2_bridge_t *mp;
5498   u32 rx_sw_if_index;
5499   u8 rx_sw_if_index_set = 0;
5500   u32 bd_id;
5501   u8 bd_id_set = 0;
5502   u8 bvi = 0;
5503   u32 shg = 0;
5504   u8 enable = 1;
5505   int ret;
5506
5507   /* Parse args required to build the message */
5508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5509     {
5510       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5511         rx_sw_if_index_set = 1;
5512       else if (unformat (i, "bd_id %d", &bd_id))
5513         bd_id_set = 1;
5514       else
5515         if (unformat
5516             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5517         rx_sw_if_index_set = 1;
5518       else if (unformat (i, "shg %d", &shg))
5519         ;
5520       else if (unformat (i, "bvi"))
5521         bvi = 1;
5522       else if (unformat (i, "enable"))
5523         enable = 1;
5524       else if (unformat (i, "disable"))
5525         enable = 0;
5526       else
5527         break;
5528     }
5529
5530   if (rx_sw_if_index_set == 0)
5531     {
5532       errmsg ("missing rx interface name or sw_if_index");
5533       return -99;
5534     }
5535
5536   if (enable && (bd_id_set == 0))
5537     {
5538       errmsg ("missing bridge domain");
5539       return -99;
5540     }
5541
5542   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
5543
5544   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5545   mp->bd_id = ntohl (bd_id);
5546   mp->shg = (u8) shg;
5547   mp->bvi = bvi;
5548   mp->enable = enable;
5549
5550   S (mp);
5551   W (ret);
5552   return ret;
5553 }
5554
5555 static int
5556 api_bridge_domain_dump (vat_main_t * vam)
5557 {
5558   unformat_input_t *i = vam->input;
5559   vl_api_bridge_domain_dump_t *mp;
5560   vl_api_control_ping_t *mp_ping;
5561   u32 bd_id = ~0;
5562   int ret;
5563
5564   /* Parse args required to build the message */
5565   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5566     {
5567       if (unformat (i, "bd_id %d", &bd_id))
5568         ;
5569       else
5570         break;
5571     }
5572
5573   M (BRIDGE_DOMAIN_DUMP, mp);
5574   mp->bd_id = ntohl (bd_id);
5575   S (mp);
5576
5577   /* Use a control ping for synchronization */
5578   M (CONTROL_PING, mp_ping);
5579   S (mp_ping);
5580
5581   W (ret);
5582   return ret;
5583 }
5584
5585 static int
5586 api_bridge_domain_add_del (vat_main_t * vam)
5587 {
5588   unformat_input_t *i = vam->input;
5589   vl_api_bridge_domain_add_del_t *mp;
5590   u32 bd_id = ~0;
5591   u8 is_add = 1;
5592   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5593   u32 mac_age = 0;
5594   int ret;
5595
5596   /* Parse args required to build the message */
5597   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5598     {
5599       if (unformat (i, "bd_id %d", &bd_id))
5600         ;
5601       else if (unformat (i, "flood %d", &flood))
5602         ;
5603       else if (unformat (i, "uu-flood %d", &uu_flood))
5604         ;
5605       else if (unformat (i, "forward %d", &forward))
5606         ;
5607       else if (unformat (i, "learn %d", &learn))
5608         ;
5609       else if (unformat (i, "arp-term %d", &arp_term))
5610         ;
5611       else if (unformat (i, "mac-age %d", &mac_age))
5612         ;
5613       else if (unformat (i, "del"))
5614         {
5615           is_add = 0;
5616           flood = uu_flood = forward = learn = 0;
5617         }
5618       else
5619         break;
5620     }
5621
5622   if (bd_id == ~0)
5623     {
5624       errmsg ("missing bridge domain");
5625       return -99;
5626     }
5627
5628   if (mac_age > 255)
5629     {
5630       errmsg ("mac age must be less than 256 ");
5631       return -99;
5632     }
5633
5634   M (BRIDGE_DOMAIN_ADD_DEL, mp);
5635
5636   mp->bd_id = ntohl (bd_id);
5637   mp->flood = flood;
5638   mp->uu_flood = uu_flood;
5639   mp->forward = forward;
5640   mp->learn = learn;
5641   mp->arp_term = arp_term;
5642   mp->is_add = is_add;
5643   mp->mac_age = (u8) mac_age;
5644
5645   S (mp);
5646   W (ret);
5647   return ret;
5648 }
5649
5650 static int
5651 api_l2fib_add_del (vat_main_t * vam)
5652 {
5653   unformat_input_t *i = vam->input;
5654   vl_api_l2fib_add_del_t *mp;
5655   f64 timeout;
5656   u64 mac = 0;
5657   u8 mac_set = 0;
5658   u32 bd_id;
5659   u8 bd_id_set = 0;
5660   u32 sw_if_index = ~0;
5661   u8 sw_if_index_set = 0;
5662   u8 is_add = 1;
5663   u8 static_mac = 0;
5664   u8 filter_mac = 0;
5665   u8 bvi_mac = 0;
5666   int count = 1;
5667   f64 before = 0;
5668   int j;
5669
5670   /* Parse args required to build the message */
5671   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5672     {
5673       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5674         mac_set = 1;
5675       else if (unformat (i, "bd_id %d", &bd_id))
5676         bd_id_set = 1;
5677       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5678         sw_if_index_set = 1;
5679       else if (unformat (i, "sw_if"))
5680         {
5681           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5682             {
5683               if (unformat
5684                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5685                 sw_if_index_set = 1;
5686             }
5687           else
5688             break;
5689         }
5690       else if (unformat (i, "static"))
5691         static_mac = 1;
5692       else if (unformat (i, "filter"))
5693         {
5694           filter_mac = 1;
5695           static_mac = 1;
5696         }
5697       else if (unformat (i, "bvi"))
5698         {
5699           bvi_mac = 1;
5700           static_mac = 1;
5701         }
5702       else if (unformat (i, "del"))
5703         is_add = 0;
5704       else if (unformat (i, "count %d", &count))
5705         ;
5706       else
5707         break;
5708     }
5709
5710   if (mac_set == 0)
5711     {
5712       errmsg ("missing mac address");
5713       return -99;
5714     }
5715
5716   if (bd_id_set == 0)
5717     {
5718       errmsg ("missing bridge domain");
5719       return -99;
5720     }
5721
5722   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
5723     {
5724       errmsg ("missing interface name or sw_if_index");
5725       return -99;
5726     }
5727
5728   if (count > 1)
5729     {
5730       /* Turn on async mode */
5731       vam->async_mode = 1;
5732       vam->async_errors = 0;
5733       before = vat_time_now (vam);
5734     }
5735
5736   for (j = 0; j < count; j++)
5737     {
5738       M (L2FIB_ADD_DEL, mp);
5739
5740       mp->mac = mac;
5741       mp->bd_id = ntohl (bd_id);
5742       mp->is_add = is_add;
5743
5744       if (is_add)
5745         {
5746           mp->sw_if_index = ntohl (sw_if_index);
5747           mp->static_mac = static_mac;
5748           mp->filter_mac = filter_mac;
5749           mp->bvi_mac = bvi_mac;
5750         }
5751       increment_mac_address (&mac);
5752       /* send it... */
5753       S (mp);
5754     }
5755
5756   if (count > 1)
5757     {
5758       vl_api_control_ping_t *mp_ping;
5759       f64 after;
5760
5761       /* Shut off async mode */
5762       vam->async_mode = 0;
5763
5764       M (CONTROL_PING, mp_ping);
5765       S (mp_ping);
5766
5767       timeout = vat_time_now (vam) + 1.0;
5768       while (vat_time_now (vam) < timeout)
5769         if (vam->result_ready == 1)
5770           goto out;
5771       vam->retval = -99;
5772
5773     out:
5774       if (vam->retval == -99)
5775         errmsg ("timeout");
5776
5777       if (vam->async_errors > 0)
5778         {
5779           errmsg ("%d asynchronous errors", vam->async_errors);
5780           vam->retval = -98;
5781         }
5782       vam->async_errors = 0;
5783       after = vat_time_now (vam);
5784
5785       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
5786              count, after - before, count / (after - before));
5787     }
5788   else
5789     {
5790       int ret;
5791
5792       /* Wait for a reply... */
5793       W (ret);
5794       return ret;
5795     }
5796   /* Return the good/bad news */
5797   return (vam->retval);
5798 }
5799
5800 static int
5801 api_l2_flags (vat_main_t * vam)
5802 {
5803   unformat_input_t *i = vam->input;
5804   vl_api_l2_flags_t *mp;
5805   u32 sw_if_index;
5806   u32 feature_bitmap = 0;
5807   u8 sw_if_index_set = 0;
5808   int ret;
5809
5810   /* Parse args required to build the message */
5811   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5812     {
5813       if (unformat (i, "sw_if_index %d", &sw_if_index))
5814         sw_if_index_set = 1;
5815       else if (unformat (i, "sw_if"))
5816         {
5817           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5818             {
5819               if (unformat
5820                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5821                 sw_if_index_set = 1;
5822             }
5823           else
5824             break;
5825         }
5826       else if (unformat (i, "learn"))
5827         feature_bitmap |= L2INPUT_FEAT_LEARN;
5828       else if (unformat (i, "forward"))
5829         feature_bitmap |= L2INPUT_FEAT_FWD;
5830       else if (unformat (i, "flood"))
5831         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5832       else if (unformat (i, "uu-flood"))
5833         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5834       else
5835         break;
5836     }
5837
5838   if (sw_if_index_set == 0)
5839     {
5840       errmsg ("missing interface name or sw_if_index");
5841       return -99;
5842     }
5843
5844   M (L2_FLAGS, mp);
5845
5846   mp->sw_if_index = ntohl (sw_if_index);
5847   mp->feature_bitmap = ntohl (feature_bitmap);
5848
5849   S (mp);
5850   W (ret);
5851   return ret;
5852 }
5853
5854 static int
5855 api_bridge_flags (vat_main_t * vam)
5856 {
5857   unformat_input_t *i = vam->input;
5858   vl_api_bridge_flags_t *mp;
5859   u32 bd_id;
5860   u8 bd_id_set = 0;
5861   u8 is_set = 1;
5862   u32 flags = 0;
5863   int ret;
5864
5865   /* Parse args required to build the message */
5866   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5867     {
5868       if (unformat (i, "bd_id %d", &bd_id))
5869         bd_id_set = 1;
5870       else if (unformat (i, "learn"))
5871         flags |= L2_LEARN;
5872       else if (unformat (i, "forward"))
5873         flags |= L2_FWD;
5874       else if (unformat (i, "flood"))
5875         flags |= L2_FLOOD;
5876       else if (unformat (i, "uu-flood"))
5877         flags |= L2_UU_FLOOD;
5878       else if (unformat (i, "arp-term"))
5879         flags |= L2_ARP_TERM;
5880       else if (unformat (i, "off"))
5881         is_set = 0;
5882       else if (unformat (i, "disable"))
5883         is_set = 0;
5884       else
5885         break;
5886     }
5887
5888   if (bd_id_set == 0)
5889     {
5890       errmsg ("missing bridge domain");
5891       return -99;
5892     }
5893
5894   M (BRIDGE_FLAGS, mp);
5895
5896   mp->bd_id = ntohl (bd_id);
5897   mp->feature_bitmap = ntohl (flags);
5898   mp->is_set = is_set;
5899
5900   S (mp);
5901   W (ret);
5902   return ret;
5903 }
5904
5905 static int
5906 api_bd_ip_mac_add_del (vat_main_t * vam)
5907 {
5908   unformat_input_t *i = vam->input;
5909   vl_api_bd_ip_mac_add_del_t *mp;
5910   u32 bd_id;
5911   u8 is_ipv6 = 0;
5912   u8 is_add = 1;
5913   u8 bd_id_set = 0;
5914   u8 ip_set = 0;
5915   u8 mac_set = 0;
5916   ip4_address_t v4addr;
5917   ip6_address_t v6addr;
5918   u8 macaddr[6];
5919   int ret;
5920
5921
5922   /* Parse args required to build the message */
5923   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5924     {
5925       if (unformat (i, "bd_id %d", &bd_id))
5926         {
5927           bd_id_set++;
5928         }
5929       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5930         {
5931           ip_set++;
5932         }
5933       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5934         {
5935           ip_set++;
5936           is_ipv6++;
5937         }
5938       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5939         {
5940           mac_set++;
5941         }
5942       else if (unformat (i, "del"))
5943         is_add = 0;
5944       else
5945         break;
5946     }
5947
5948   if (bd_id_set == 0)
5949     {
5950       errmsg ("missing bridge domain");
5951       return -99;
5952     }
5953   else if (ip_set == 0)
5954     {
5955       errmsg ("missing IP address");
5956       return -99;
5957     }
5958   else if (mac_set == 0)
5959     {
5960       errmsg ("missing MAC address");
5961       return -99;
5962     }
5963
5964   M (BD_IP_MAC_ADD_DEL, mp);
5965
5966   mp->bd_id = ntohl (bd_id);
5967   mp->is_ipv6 = is_ipv6;
5968   mp->is_add = is_add;
5969   if (is_ipv6)
5970     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5971   else
5972     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5973   clib_memcpy (mp->mac_address, macaddr, 6);
5974   S (mp);
5975   W (ret);
5976   return ret;
5977 }
5978
5979 static int
5980 api_tap_connect (vat_main_t * vam)
5981 {
5982   unformat_input_t *i = vam->input;
5983   vl_api_tap_connect_t *mp;
5984   u8 mac_address[6];
5985   u8 random_mac = 1;
5986   u8 name_set = 0;
5987   u8 *tap_name;
5988   u8 *tag = 0;
5989   ip4_address_t ip4_address;
5990   u32 ip4_mask_width;
5991   int ip4_address_set = 0;
5992   ip6_address_t ip6_address;
5993   u32 ip6_mask_width;
5994   int ip6_address_set = 0;
5995   int ret;
5996
5997   memset (mac_address, 0, sizeof (mac_address));
5998
5999   /* Parse args required to build the message */
6000   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6001     {
6002       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6003         {
6004           random_mac = 0;
6005         }
6006       else if (unformat (i, "random-mac"))
6007         random_mac = 1;
6008       else if (unformat (i, "tapname %s", &tap_name))
6009         name_set = 1;
6010       else if (unformat (i, "tag %s", &tag))
6011         ;
6012       else if (unformat (i, "address %U/%d",
6013                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
6014         ip4_address_set = 1;
6015       else if (unformat (i, "address %U/%d",
6016                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
6017         ip6_address_set = 1;
6018       else
6019         break;
6020     }
6021
6022   if (name_set == 0)
6023     {
6024       errmsg ("missing tap name");
6025       return -99;
6026     }
6027   if (vec_len (tap_name) > 63)
6028     {
6029       errmsg ("tap name too long");
6030       return -99;
6031     }
6032   vec_add1 (tap_name, 0);
6033
6034   if (vec_len (tag) > 63)
6035     {
6036       errmsg ("tag too long");
6037       return -99;
6038     }
6039
6040   /* Construct the API message */
6041   M (TAP_CONNECT, mp);
6042
6043   mp->use_random_mac = random_mac;
6044   clib_memcpy (mp->mac_address, mac_address, 6);
6045   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6046   if (tag)
6047     clib_memcpy (mp->tag, tag, vec_len (tag));
6048
6049   if (ip4_address_set)
6050     {
6051       mp->ip4_address_set = 1;
6052       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6053       mp->ip4_mask_width = ip4_mask_width;
6054     }
6055   if (ip6_address_set)
6056     {
6057       mp->ip6_address_set = 1;
6058       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6059       mp->ip6_mask_width = ip6_mask_width;
6060     }
6061
6062   vec_free (tap_name);
6063   vec_free (tag);
6064
6065   /* send it... */
6066   S (mp);
6067
6068   /* Wait for a reply... */
6069   W (ret);
6070   return ret;
6071 }
6072
6073 static int
6074 api_tap_modify (vat_main_t * vam)
6075 {
6076   unformat_input_t *i = vam->input;
6077   vl_api_tap_modify_t *mp;
6078   u8 mac_address[6];
6079   u8 random_mac = 1;
6080   u8 name_set = 0;
6081   u8 *tap_name;
6082   u32 sw_if_index = ~0;
6083   u8 sw_if_index_set = 0;
6084   int ret;
6085
6086   memset (mac_address, 0, sizeof (mac_address));
6087
6088   /* Parse args required to build the message */
6089   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6090     {
6091       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6092         sw_if_index_set = 1;
6093       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6094         sw_if_index_set = 1;
6095       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6096         {
6097           random_mac = 0;
6098         }
6099       else if (unformat (i, "random-mac"))
6100         random_mac = 1;
6101       else if (unformat (i, "tapname %s", &tap_name))
6102         name_set = 1;
6103       else
6104         break;
6105     }
6106
6107   if (sw_if_index_set == 0)
6108     {
6109       errmsg ("missing vpp interface name");
6110       return -99;
6111     }
6112   if (name_set == 0)
6113     {
6114       errmsg ("missing tap name");
6115       return -99;
6116     }
6117   if (vec_len (tap_name) > 63)
6118     {
6119       errmsg ("tap name too long");
6120     }
6121   vec_add1 (tap_name, 0);
6122
6123   /* Construct the API message */
6124   M (TAP_MODIFY, mp);
6125
6126   mp->use_random_mac = random_mac;
6127   mp->sw_if_index = ntohl (sw_if_index);
6128   clib_memcpy (mp->mac_address, mac_address, 6);
6129   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6130   vec_free (tap_name);
6131
6132   /* send it... */
6133   S (mp);
6134
6135   /* Wait for a reply... */
6136   W (ret);
6137   return ret;
6138 }
6139
6140 static int
6141 api_tap_delete (vat_main_t * vam)
6142 {
6143   unformat_input_t *i = vam->input;
6144   vl_api_tap_delete_t *mp;
6145   u32 sw_if_index = ~0;
6146   u8 sw_if_index_set = 0;
6147   int ret;
6148
6149   /* Parse args required to build the message */
6150   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6151     {
6152       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6153         sw_if_index_set = 1;
6154       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6155         sw_if_index_set = 1;
6156       else
6157         break;
6158     }
6159
6160   if (sw_if_index_set == 0)
6161     {
6162       errmsg ("missing vpp interface name");
6163       return -99;
6164     }
6165
6166   /* Construct the API message */
6167   M (TAP_DELETE, mp);
6168
6169   mp->sw_if_index = ntohl (sw_if_index);
6170
6171   /* send it... */
6172   S (mp);
6173
6174   /* Wait for a reply... */
6175   W (ret);
6176   return ret;
6177 }
6178
6179 static int
6180 api_ip_add_del_route (vat_main_t * vam)
6181 {
6182   unformat_input_t *i = vam->input;
6183   vl_api_ip_add_del_route_t *mp;
6184   u32 sw_if_index = ~0, vrf_id = 0;
6185   u8 is_ipv6 = 0;
6186   u8 is_local = 0, is_drop = 0;
6187   u8 is_unreach = 0, is_prohibit = 0;
6188   u8 create_vrf_if_needed = 0;
6189   u8 is_add = 1;
6190   u32 next_hop_weight = 1;
6191   u8 not_last = 0;
6192   u8 is_multipath = 0;
6193   u8 address_set = 0;
6194   u8 address_length_set = 0;
6195   u32 next_hop_table_id = 0;
6196   u32 resolve_attempts = 0;
6197   u32 dst_address_length = 0;
6198   u8 next_hop_set = 0;
6199   ip4_address_t v4_dst_address, v4_next_hop_address;
6200   ip6_address_t v6_dst_address, v6_next_hop_address;
6201   int count = 1;
6202   int j;
6203   f64 before = 0;
6204   u32 random_add_del = 0;
6205   u32 *random_vector = 0;
6206   uword *random_hash;
6207   u32 random_seed = 0xdeaddabe;
6208   u32 classify_table_index = ~0;
6209   u8 is_classify = 0;
6210   u8 resolve_host = 0, resolve_attached = 0;
6211   mpls_label_t *next_hop_out_label_stack = NULL;
6212   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6213   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6214
6215   /* Parse args required to build the message */
6216   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6217     {
6218       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6219         ;
6220       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6221         ;
6222       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6223         {
6224           address_set = 1;
6225           is_ipv6 = 0;
6226         }
6227       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6228         {
6229           address_set = 1;
6230           is_ipv6 = 1;
6231         }
6232       else if (unformat (i, "/%d", &dst_address_length))
6233         {
6234           address_length_set = 1;
6235         }
6236
6237       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6238                                          &v4_next_hop_address))
6239         {
6240           next_hop_set = 1;
6241         }
6242       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6243                                          &v6_next_hop_address))
6244         {
6245           next_hop_set = 1;
6246         }
6247       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6248         ;
6249       else if (unformat (i, "weight %d", &next_hop_weight))
6250         ;
6251       else if (unformat (i, "drop"))
6252         {
6253           is_drop = 1;
6254         }
6255       else if (unformat (i, "null-send-unreach"))
6256         {
6257           is_unreach = 1;
6258         }
6259       else if (unformat (i, "null-send-prohibit"))
6260         {
6261           is_prohibit = 1;
6262         }
6263       else if (unformat (i, "local"))
6264         {
6265           is_local = 1;
6266         }
6267       else if (unformat (i, "classify %d", &classify_table_index))
6268         {
6269           is_classify = 1;
6270         }
6271       else if (unformat (i, "del"))
6272         is_add = 0;
6273       else if (unformat (i, "add"))
6274         is_add = 1;
6275       else if (unformat (i, "not-last"))
6276         not_last = 1;
6277       else if (unformat (i, "resolve-via-host"))
6278         resolve_host = 1;
6279       else if (unformat (i, "resolve-via-attached"))
6280         resolve_attached = 1;
6281       else if (unformat (i, "multipath"))
6282         is_multipath = 1;
6283       else if (unformat (i, "vrf %d", &vrf_id))
6284         ;
6285       else if (unformat (i, "create-vrf"))
6286         create_vrf_if_needed = 1;
6287       else if (unformat (i, "count %d", &count))
6288         ;
6289       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6290         ;
6291       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6292         ;
6293       else if (unformat (i, "out-label %d", &next_hop_out_label))
6294         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6295       else if (unformat (i, "via-label %d", &next_hop_via_label))
6296         ;
6297       else if (unformat (i, "random"))
6298         random_add_del = 1;
6299       else if (unformat (i, "seed %d", &random_seed))
6300         ;
6301       else
6302         {
6303           clib_warning ("parse error '%U'", format_unformat_error, i);
6304           return -99;
6305         }
6306     }
6307
6308   if (!next_hop_set && !is_drop && !is_local &&
6309       !is_classify && !is_unreach && !is_prohibit &&
6310       MPLS_LABEL_INVALID == next_hop_via_label)
6311     {
6312       errmsg
6313         ("next hop / local / drop / unreach / prohibit / classify not set");
6314       return -99;
6315     }
6316
6317   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6318     {
6319       errmsg ("next hop and next-hop via label set");
6320       return -99;
6321     }
6322   if (address_set == 0)
6323     {
6324       errmsg ("missing addresses");
6325       return -99;
6326     }
6327
6328   if (address_length_set == 0)
6329     {
6330       errmsg ("missing address length");
6331       return -99;
6332     }
6333
6334   /* Generate a pile of unique, random routes */
6335   if (random_add_del)
6336     {
6337       u32 this_random_address;
6338       random_hash = hash_create (count, sizeof (uword));
6339
6340       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6341       for (j = 0; j <= count; j++)
6342         {
6343           do
6344             {
6345               this_random_address = random_u32 (&random_seed);
6346               this_random_address =
6347                 clib_host_to_net_u32 (this_random_address);
6348             }
6349           while (hash_get (random_hash, this_random_address));
6350           vec_add1 (random_vector, this_random_address);
6351           hash_set (random_hash, this_random_address, 1);
6352         }
6353       hash_free (random_hash);
6354       v4_dst_address.as_u32 = random_vector[0];
6355     }
6356
6357   if (count > 1)
6358     {
6359       /* Turn on async mode */
6360       vam->async_mode = 1;
6361       vam->async_errors = 0;
6362       before = vat_time_now (vam);
6363     }
6364
6365   for (j = 0; j < count; j++)
6366     {
6367       /* Construct the API message */
6368       M2 (IP_ADD_DEL_ROUTE, mp,
6369           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6370
6371       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6372       mp->table_id = ntohl (vrf_id);
6373       mp->create_vrf_if_needed = create_vrf_if_needed;
6374
6375       mp->is_add = is_add;
6376       mp->is_drop = is_drop;
6377       mp->is_unreach = is_unreach;
6378       mp->is_prohibit = is_prohibit;
6379       mp->is_ipv6 = is_ipv6;
6380       mp->is_local = is_local;
6381       mp->is_classify = is_classify;
6382       mp->is_multipath = is_multipath;
6383       mp->is_resolve_host = resolve_host;
6384       mp->is_resolve_attached = resolve_attached;
6385       mp->not_last = not_last;
6386       mp->next_hop_weight = next_hop_weight;
6387       mp->dst_address_length = dst_address_length;
6388       mp->next_hop_table_id = ntohl (next_hop_table_id);
6389       mp->classify_table_index = ntohl (classify_table_index);
6390       mp->next_hop_via_label = ntohl (next_hop_via_label);
6391       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6392       if (0 != mp->next_hop_n_out_labels)
6393         {
6394           memcpy (mp->next_hop_out_label_stack,
6395                   next_hop_out_label_stack,
6396                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6397           vec_free (next_hop_out_label_stack);
6398         }
6399
6400       if (is_ipv6)
6401         {
6402           clib_memcpy (mp->dst_address, &v6_dst_address,
6403                        sizeof (v6_dst_address));
6404           if (next_hop_set)
6405             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6406                          sizeof (v6_next_hop_address));
6407           increment_v6_address (&v6_dst_address);
6408         }
6409       else
6410         {
6411           clib_memcpy (mp->dst_address, &v4_dst_address,
6412                        sizeof (v4_dst_address));
6413           if (next_hop_set)
6414             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6415                          sizeof (v4_next_hop_address));
6416           if (random_add_del)
6417             v4_dst_address.as_u32 = random_vector[j + 1];
6418           else
6419             increment_v4_address (&v4_dst_address);
6420         }
6421       /* send it... */
6422       S (mp);
6423       /* If we receive SIGTERM, stop now... */
6424       if (vam->do_exit)
6425         break;
6426     }
6427
6428   /* When testing multiple add/del ops, use a control-ping to sync */
6429   if (count > 1)
6430     {
6431       vl_api_control_ping_t *mp_ping;
6432       f64 after;
6433       f64 timeout;
6434
6435       /* Shut off async mode */
6436       vam->async_mode = 0;
6437
6438       M (CONTROL_PING, mp_ping);
6439       S (mp_ping);
6440
6441       timeout = vat_time_now (vam) + 1.0;
6442       while (vat_time_now (vam) < timeout)
6443         if (vam->result_ready == 1)
6444           goto out;
6445       vam->retval = -99;
6446
6447     out:
6448       if (vam->retval == -99)
6449         errmsg ("timeout");
6450
6451       if (vam->async_errors > 0)
6452         {
6453           errmsg ("%d asynchronous errors", vam->async_errors);
6454           vam->retval = -98;
6455         }
6456       vam->async_errors = 0;
6457       after = vat_time_now (vam);
6458
6459       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6460       if (j > 0)
6461         count = j;
6462
6463       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6464              count, after - before, count / (after - before));
6465     }
6466   else
6467     {
6468       int ret;
6469
6470       /* Wait for a reply... */
6471       W (ret);
6472       return ret;
6473     }
6474
6475   /* Return the good/bad news */
6476   return (vam->retval);
6477 }
6478
6479 static int
6480 api_ip_mroute_add_del (vat_main_t * vam)
6481 {
6482   unformat_input_t *i = vam->input;
6483   vl_api_ip_mroute_add_del_t *mp;
6484   u32 sw_if_index = ~0, vrf_id = 0;
6485   u8 is_ipv6 = 0;
6486   u8 is_local = 0;
6487   u8 create_vrf_if_needed = 0;
6488   u8 is_add = 1;
6489   u8 address_set = 0;
6490   u32 grp_address_length = 0;
6491   ip4_address_t v4_grp_address, v4_src_address;
6492   ip6_address_t v6_grp_address, v6_src_address;
6493   mfib_itf_flags_t iflags = 0;
6494   mfib_entry_flags_t eflags = 0;
6495   int ret;
6496
6497   /* Parse args required to build the message */
6498   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6499     {
6500       if (unformat (i, "sw_if_index %d", &sw_if_index))
6501         ;
6502       else if (unformat (i, "%U %U",
6503                          unformat_ip4_address, &v4_src_address,
6504                          unformat_ip4_address, &v4_grp_address))
6505         {
6506           grp_address_length = 64;
6507           address_set = 1;
6508           is_ipv6 = 0;
6509         }
6510       else if (unformat (i, "%U %U",
6511                          unformat_ip6_address, &v6_src_address,
6512                          unformat_ip6_address, &v6_grp_address))
6513         {
6514           grp_address_length = 256;
6515           address_set = 1;
6516           is_ipv6 = 1;
6517         }
6518       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
6519         {
6520           memset (&v4_src_address, 0, sizeof (v4_src_address));
6521           grp_address_length = 32;
6522           address_set = 1;
6523           is_ipv6 = 0;
6524         }
6525       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
6526         {
6527           memset (&v6_src_address, 0, sizeof (v6_src_address));
6528           grp_address_length = 128;
6529           address_set = 1;
6530           is_ipv6 = 1;
6531         }
6532       else if (unformat (i, "/%d", &grp_address_length))
6533         ;
6534       else if (unformat (i, "local"))
6535         {
6536           is_local = 1;
6537         }
6538       else if (unformat (i, "del"))
6539         is_add = 0;
6540       else if (unformat (i, "add"))
6541         is_add = 1;
6542       else if (unformat (i, "vrf %d", &vrf_id))
6543         ;
6544       else if (unformat (i, "create-vrf"))
6545         create_vrf_if_needed = 1;
6546       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
6547         ;
6548       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6549         ;
6550       else
6551         {
6552           clib_warning ("parse error '%U'", format_unformat_error, i);
6553           return -99;
6554         }
6555     }
6556
6557   if (address_set == 0)
6558     {
6559       errmsg ("missing addresses\n");
6560       return -99;
6561     }
6562
6563   /* Construct the API message */
6564   M (IP_MROUTE_ADD_DEL, mp);
6565
6566   mp->next_hop_sw_if_index = ntohl (sw_if_index);
6567   mp->table_id = ntohl (vrf_id);
6568   mp->create_vrf_if_needed = create_vrf_if_needed;
6569
6570   mp->is_add = is_add;
6571   mp->is_ipv6 = is_ipv6;
6572   mp->is_local = is_local;
6573   mp->itf_flags = ntohl (iflags);
6574   mp->entry_flags = ntohl (eflags);
6575   mp->grp_address_length = grp_address_length;
6576   mp->grp_address_length = ntohs (mp->grp_address_length);
6577
6578   if (is_ipv6)
6579     {
6580       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
6581       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
6582     }
6583   else
6584     {
6585       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
6586       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
6587
6588     }
6589
6590   /* send it... */
6591   S (mp);
6592   /* Wait for a reply... */
6593   W (ret);
6594   return ret;
6595 }
6596
6597 static int
6598 api_mpls_route_add_del (vat_main_t * vam)
6599 {
6600   unformat_input_t *i = vam->input;
6601   vl_api_mpls_route_add_del_t *mp;
6602   u32 sw_if_index = ~0, table_id = 0;
6603   u8 create_table_if_needed = 0;
6604   u8 is_add = 1;
6605   u32 next_hop_weight = 1;
6606   u8 is_multipath = 0;
6607   u32 next_hop_table_id = 0;
6608   u8 next_hop_set = 0;
6609   ip4_address_t v4_next_hop_address = {
6610     .as_u32 = 0,
6611   };
6612   ip6_address_t v6_next_hop_address = { {0} };
6613   int count = 1;
6614   int j;
6615   f64 before = 0;
6616   u32 classify_table_index = ~0;
6617   u8 is_classify = 0;
6618   u8 resolve_host = 0, resolve_attached = 0;
6619   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6620   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6621   mpls_label_t *next_hop_out_label_stack = NULL;
6622   mpls_label_t local_label = MPLS_LABEL_INVALID;
6623   u8 is_eos = 0;
6624   u8 next_hop_proto_is_ip4 = 1;
6625
6626   /* Parse args required to build the message */
6627   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6628     {
6629       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6630         ;
6631       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6632         ;
6633       else if (unformat (i, "%d", &local_label))
6634         ;
6635       else if (unformat (i, "eos"))
6636         is_eos = 1;
6637       else if (unformat (i, "non-eos"))
6638         is_eos = 0;
6639       else if (unformat (i, "via %U", unformat_ip4_address,
6640                          &v4_next_hop_address))
6641         {
6642           next_hop_set = 1;
6643           next_hop_proto_is_ip4 = 1;
6644         }
6645       else if (unformat (i, "via %U", unformat_ip6_address,
6646                          &v6_next_hop_address))
6647         {
6648           next_hop_set = 1;
6649           next_hop_proto_is_ip4 = 0;
6650         }
6651       else if (unformat (i, "weight %d", &next_hop_weight))
6652         ;
6653       else if (unformat (i, "create-table"))
6654         create_table_if_needed = 1;
6655       else if (unformat (i, "classify %d", &classify_table_index))
6656         {
6657           is_classify = 1;
6658         }
6659       else if (unformat (i, "del"))
6660         is_add = 0;
6661       else if (unformat (i, "add"))
6662         is_add = 1;
6663       else if (unformat (i, "resolve-via-host"))
6664         resolve_host = 1;
6665       else if (unformat (i, "resolve-via-attached"))
6666         resolve_attached = 1;
6667       else if (unformat (i, "multipath"))
6668         is_multipath = 1;
6669       else if (unformat (i, "count %d", &count))
6670         ;
6671       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6672         {
6673           next_hop_set = 1;
6674           next_hop_proto_is_ip4 = 1;
6675         }
6676       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6677         {
6678           next_hop_set = 1;
6679           next_hop_proto_is_ip4 = 0;
6680         }
6681       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6682         ;
6683       else if (unformat (i, "via-label %d", &next_hop_via_label))
6684         ;
6685       else if (unformat (i, "out-label %d", &next_hop_out_label))
6686         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6687       else
6688         {
6689           clib_warning ("parse error '%U'", format_unformat_error, i);
6690           return -99;
6691         }
6692     }
6693
6694   if (!next_hop_set && !is_classify)
6695     {
6696       errmsg ("next hop / classify not set");
6697       return -99;
6698     }
6699
6700   if (MPLS_LABEL_INVALID == local_label)
6701     {
6702       errmsg ("missing label");
6703       return -99;
6704     }
6705
6706   if (count > 1)
6707     {
6708       /* Turn on async mode */
6709       vam->async_mode = 1;
6710       vam->async_errors = 0;
6711       before = vat_time_now (vam);
6712     }
6713
6714   for (j = 0; j < count; j++)
6715     {
6716       /* Construct the API message */
6717       M2 (MPLS_ROUTE_ADD_DEL, mp,
6718           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6719
6720       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6721       mp->mr_table_id = ntohl (table_id);
6722       mp->mr_create_table_if_needed = create_table_if_needed;
6723
6724       mp->mr_is_add = is_add;
6725       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6726       mp->mr_is_classify = is_classify;
6727       mp->mr_is_multipath = is_multipath;
6728       mp->mr_is_resolve_host = resolve_host;
6729       mp->mr_is_resolve_attached = resolve_attached;
6730       mp->mr_next_hop_weight = next_hop_weight;
6731       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6732       mp->mr_classify_table_index = ntohl (classify_table_index);
6733       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
6734       mp->mr_label = ntohl (local_label);
6735       mp->mr_eos = is_eos;
6736
6737       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6738       if (0 != mp->mr_next_hop_n_out_labels)
6739         {
6740           memcpy (mp->mr_next_hop_out_label_stack,
6741                   next_hop_out_label_stack,
6742                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6743           vec_free (next_hop_out_label_stack);
6744         }
6745
6746       if (next_hop_set)
6747         {
6748           if (next_hop_proto_is_ip4)
6749             {
6750               clib_memcpy (mp->mr_next_hop,
6751                            &v4_next_hop_address,
6752                            sizeof (v4_next_hop_address));
6753             }
6754           else
6755             {
6756               clib_memcpy (mp->mr_next_hop,
6757                            &v6_next_hop_address,
6758                            sizeof (v6_next_hop_address));
6759             }
6760         }
6761       local_label++;
6762
6763       /* send it... */
6764       S (mp);
6765       /* If we receive SIGTERM, stop now... */
6766       if (vam->do_exit)
6767         break;
6768     }
6769
6770   /* When testing multiple add/del ops, use a control-ping to sync */
6771   if (count > 1)
6772     {
6773       vl_api_control_ping_t *mp_ping;
6774       f64 after;
6775       f64 timeout;
6776
6777       /* Shut off async mode */
6778       vam->async_mode = 0;
6779
6780       M (CONTROL_PING, mp_ping);
6781       S (mp_ping);
6782
6783       timeout = vat_time_now (vam) + 1.0;
6784       while (vat_time_now (vam) < timeout)
6785         if (vam->result_ready == 1)
6786           goto out;
6787       vam->retval = -99;
6788
6789     out:
6790       if (vam->retval == -99)
6791         errmsg ("timeout");
6792
6793       if (vam->async_errors > 0)
6794         {
6795           errmsg ("%d asynchronous errors", vam->async_errors);
6796           vam->retval = -98;
6797         }
6798       vam->async_errors = 0;
6799       after = vat_time_now (vam);
6800
6801       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6802       if (j > 0)
6803         count = j;
6804
6805       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6806              count, after - before, count / (after - before));
6807     }
6808   else
6809     {
6810       int ret;
6811
6812       /* Wait for a reply... */
6813       W (ret);
6814       return ret;
6815     }
6816
6817   /* Return the good/bad news */
6818   return (vam->retval);
6819 }
6820
6821 static int
6822 api_mpls_ip_bind_unbind (vat_main_t * vam)
6823 {
6824   unformat_input_t *i = vam->input;
6825   vl_api_mpls_ip_bind_unbind_t *mp;
6826   u32 ip_table_id = 0;
6827   u8 create_table_if_needed = 0;
6828   u8 is_bind = 1;
6829   u8 is_ip4 = 1;
6830   ip4_address_t v4_address;
6831   ip6_address_t v6_address;
6832   u32 address_length;
6833   u8 address_set = 0;
6834   mpls_label_t local_label = MPLS_LABEL_INVALID;
6835   int ret;
6836
6837   /* Parse args required to build the message */
6838   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6839     {
6840       if (unformat (i, "%U/%d", unformat_ip4_address,
6841                     &v4_address, &address_length))
6842         {
6843           is_ip4 = 1;
6844           address_set = 1;
6845         }
6846       else if (unformat (i, "%U/%d", unformat_ip6_address,
6847                          &v6_address, &address_length))
6848         {
6849           is_ip4 = 0;
6850           address_set = 1;
6851         }
6852       else if (unformat (i, "%d", &local_label))
6853         ;
6854       else if (unformat (i, "create-table"))
6855         create_table_if_needed = 1;
6856       else if (unformat (i, "table-id %d", &ip_table_id))
6857         ;
6858       else if (unformat (i, "unbind"))
6859         is_bind = 0;
6860       else if (unformat (i, "bind"))
6861         is_bind = 1;
6862       else
6863         {
6864           clib_warning ("parse error '%U'", format_unformat_error, i);
6865           return -99;
6866         }
6867     }
6868
6869   if (!address_set)
6870     {
6871       errmsg ("IP addres not set");
6872       return -99;
6873     }
6874
6875   if (MPLS_LABEL_INVALID == local_label)
6876     {
6877       errmsg ("missing label");
6878       return -99;
6879     }
6880
6881   /* Construct the API message */
6882   M (MPLS_IP_BIND_UNBIND, mp);
6883
6884   mp->mb_create_table_if_needed = create_table_if_needed;
6885   mp->mb_is_bind = is_bind;
6886   mp->mb_is_ip4 = is_ip4;
6887   mp->mb_ip_table_id = ntohl (ip_table_id);
6888   mp->mb_mpls_table_id = 0;
6889   mp->mb_label = ntohl (local_label);
6890   mp->mb_address_length = address_length;
6891
6892   if (is_ip4)
6893     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
6894   else
6895     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
6896
6897   /* send it... */
6898   S (mp);
6899
6900   /* Wait for a reply... */
6901   W (ret);
6902   return ret;
6903 }
6904
6905 static int
6906 api_proxy_arp_add_del (vat_main_t * vam)
6907 {
6908   unformat_input_t *i = vam->input;
6909   vl_api_proxy_arp_add_del_t *mp;
6910   u32 vrf_id = 0;
6911   u8 is_add = 1;
6912   ip4_address_t lo, hi;
6913   u8 range_set = 0;
6914   int ret;
6915
6916   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6917     {
6918       if (unformat (i, "vrf %d", &vrf_id))
6919         ;
6920       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
6921                          unformat_ip4_address, &hi))
6922         range_set = 1;
6923       else if (unformat (i, "del"))
6924         is_add = 0;
6925       else
6926         {
6927           clib_warning ("parse error '%U'", format_unformat_error, i);
6928           return -99;
6929         }
6930     }
6931
6932   if (range_set == 0)
6933     {
6934       errmsg ("address range not set");
6935       return -99;
6936     }
6937
6938   M (PROXY_ARP_ADD_DEL, mp);
6939
6940   mp->vrf_id = ntohl (vrf_id);
6941   mp->is_add = is_add;
6942   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
6943   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
6944
6945   S (mp);
6946   W (ret);
6947   return ret;
6948 }
6949
6950 static int
6951 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
6952 {
6953   unformat_input_t *i = vam->input;
6954   vl_api_proxy_arp_intfc_enable_disable_t *mp;
6955   u32 sw_if_index;
6956   u8 enable = 1;
6957   u8 sw_if_index_set = 0;
6958   int ret;
6959
6960   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6961     {
6962       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6963         sw_if_index_set = 1;
6964       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6965         sw_if_index_set = 1;
6966       else if (unformat (i, "enable"))
6967         enable = 1;
6968       else if (unformat (i, "disable"))
6969         enable = 0;
6970       else
6971         {
6972           clib_warning ("parse error '%U'", format_unformat_error, i);
6973           return -99;
6974         }
6975     }
6976
6977   if (sw_if_index_set == 0)
6978     {
6979       errmsg ("missing interface name or sw_if_index");
6980       return -99;
6981     }
6982
6983   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
6984
6985   mp->sw_if_index = ntohl (sw_if_index);
6986   mp->enable_disable = enable;
6987
6988   S (mp);
6989   W (ret);
6990   return ret;
6991 }
6992
6993 static int
6994 api_mpls_tunnel_add_del (vat_main_t * vam)
6995 {
6996   unformat_input_t *i = vam->input;
6997   vl_api_mpls_tunnel_add_del_t *mp;
6998
6999   u8 is_add = 1;
7000   u8 l2_only = 0;
7001   u32 sw_if_index = ~0;
7002   u32 next_hop_sw_if_index = ~0;
7003   u32 next_hop_proto_is_ip4 = 1;
7004
7005   u32 next_hop_table_id = 0;
7006   ip4_address_t v4_next_hop_address = {
7007     .as_u32 = 0,
7008   };
7009   ip6_address_t v6_next_hop_address = { {0} };
7010   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
7011   int ret;
7012
7013   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7014     {
7015       if (unformat (i, "add"))
7016         is_add = 1;
7017       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7018         is_add = 0;
7019       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7020         ;
7021       else if (unformat (i, "via %U",
7022                          unformat_ip4_address, &v4_next_hop_address))
7023         {
7024           next_hop_proto_is_ip4 = 1;
7025         }
7026       else if (unformat (i, "via %U",
7027                          unformat_ip6_address, &v6_next_hop_address))
7028         {
7029           next_hop_proto_is_ip4 = 0;
7030         }
7031       else if (unformat (i, "l2-only"))
7032         l2_only = 1;
7033       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7034         ;
7035       else if (unformat (i, "out-label %d", &next_hop_out_label))
7036         vec_add1 (labels, ntohl (next_hop_out_label));
7037       else
7038         {
7039           clib_warning ("parse error '%U'", format_unformat_error, i);
7040           return -99;
7041         }
7042     }
7043
7044   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
7045
7046   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
7047   mp->mt_sw_if_index = ntohl (sw_if_index);
7048   mp->mt_is_add = is_add;
7049   mp->mt_l2_only = l2_only;
7050   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
7051   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7052
7053   mp->mt_next_hop_n_out_labels = vec_len (labels);
7054
7055   if (0 != mp->mt_next_hop_n_out_labels)
7056     {
7057       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7058                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7059       vec_free (labels);
7060     }
7061
7062   if (next_hop_proto_is_ip4)
7063     {
7064       clib_memcpy (mp->mt_next_hop,
7065                    &v4_next_hop_address, sizeof (v4_next_hop_address));
7066     }
7067   else
7068     {
7069       clib_memcpy (mp->mt_next_hop,
7070                    &v6_next_hop_address, sizeof (v6_next_hop_address));
7071     }
7072
7073   S (mp);
7074   W (ret);
7075   return ret;
7076 }
7077
7078 static int
7079 api_sw_interface_set_unnumbered (vat_main_t * vam)
7080 {
7081   unformat_input_t *i = vam->input;
7082   vl_api_sw_interface_set_unnumbered_t *mp;
7083   u32 sw_if_index;
7084   u32 unnum_sw_index = ~0;
7085   u8 is_add = 1;
7086   u8 sw_if_index_set = 0;
7087   int ret;
7088
7089   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7090     {
7091       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7092         sw_if_index_set = 1;
7093       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7094         sw_if_index_set = 1;
7095       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7096         ;
7097       else if (unformat (i, "del"))
7098         is_add = 0;
7099       else
7100         {
7101           clib_warning ("parse error '%U'", format_unformat_error, i);
7102           return -99;
7103         }
7104     }
7105
7106   if (sw_if_index_set == 0)
7107     {
7108       errmsg ("missing interface name or sw_if_index");
7109       return -99;
7110     }
7111
7112   M (SW_INTERFACE_SET_UNNUMBERED, mp);
7113
7114   mp->sw_if_index = ntohl (sw_if_index);
7115   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7116   mp->is_add = is_add;
7117
7118   S (mp);
7119   W (ret);
7120   return ret;
7121 }
7122
7123 static int
7124 api_ip_neighbor_add_del (vat_main_t * vam)
7125 {
7126   unformat_input_t *i = vam->input;
7127   vl_api_ip_neighbor_add_del_t *mp;
7128   u32 sw_if_index;
7129   u8 sw_if_index_set = 0;
7130   u8 is_add = 1;
7131   u8 is_static = 0;
7132   u8 mac_address[6];
7133   u8 mac_set = 0;
7134   u8 v4_address_set = 0;
7135   u8 v6_address_set = 0;
7136   ip4_address_t v4address;
7137   ip6_address_t v6address;
7138   int ret;
7139
7140   memset (mac_address, 0, sizeof (mac_address));
7141
7142   /* Parse args required to build the message */
7143   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7144     {
7145       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7146         {
7147           mac_set = 1;
7148         }
7149       else if (unformat (i, "del"))
7150         is_add = 0;
7151       else
7152         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7153         sw_if_index_set = 1;
7154       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7155         sw_if_index_set = 1;
7156       else if (unformat (i, "is_static"))
7157         is_static = 1;
7158       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
7159         v4_address_set = 1;
7160       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
7161         v6_address_set = 1;
7162       else
7163         {
7164           clib_warning ("parse error '%U'", format_unformat_error, i);
7165           return -99;
7166         }
7167     }
7168
7169   if (sw_if_index_set == 0)
7170     {
7171       errmsg ("missing interface name or sw_if_index");
7172       return -99;
7173     }
7174   if (v4_address_set && v6_address_set)
7175     {
7176       errmsg ("both v4 and v6 addresses set");
7177       return -99;
7178     }
7179   if (!v4_address_set && !v6_address_set)
7180     {
7181       errmsg ("no address set");
7182       return -99;
7183     }
7184
7185   /* Construct the API message */
7186   M (IP_NEIGHBOR_ADD_DEL, mp);
7187
7188   mp->sw_if_index = ntohl (sw_if_index);
7189   mp->is_add = is_add;
7190   mp->is_static = is_static;
7191   if (mac_set)
7192     clib_memcpy (mp->mac_address, mac_address, 6);
7193   if (v6_address_set)
7194     {
7195       mp->is_ipv6 = 1;
7196       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
7197     }
7198   else
7199     {
7200       /* mp->is_ipv6 = 0; via memset in M macro above */
7201       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
7202     }
7203
7204   /* send it... */
7205   S (mp);
7206
7207   /* Wait for a reply, return good/bad news  */
7208   W (ret);
7209   return ret;
7210 }
7211
7212 static int
7213 api_reset_vrf (vat_main_t * vam)
7214 {
7215   unformat_input_t *i = vam->input;
7216   vl_api_reset_vrf_t *mp;
7217   u32 vrf_id = 0;
7218   u8 is_ipv6 = 0;
7219   u8 vrf_id_set = 0;
7220   int ret;
7221
7222   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7223     {
7224       if (unformat (i, "vrf %d", &vrf_id))
7225         vrf_id_set = 1;
7226       else if (unformat (i, "ipv6"))
7227         is_ipv6 = 1;
7228       else
7229         {
7230           clib_warning ("parse error '%U'", format_unformat_error, i);
7231           return -99;
7232         }
7233     }
7234
7235   if (vrf_id_set == 0)
7236     {
7237       errmsg ("missing vrf id");
7238       return -99;
7239     }
7240
7241   M (RESET_VRF, mp);
7242
7243   mp->vrf_id = ntohl (vrf_id);
7244   mp->is_ipv6 = is_ipv6;
7245
7246   S (mp);
7247   W (ret);
7248   return ret;
7249 }
7250
7251 static int
7252 api_create_vlan_subif (vat_main_t * vam)
7253 {
7254   unformat_input_t *i = vam->input;
7255   vl_api_create_vlan_subif_t *mp;
7256   u32 sw_if_index;
7257   u8 sw_if_index_set = 0;
7258   u32 vlan_id;
7259   u8 vlan_id_set = 0;
7260   int ret;
7261
7262   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7263     {
7264       if (unformat (i, "sw_if_index %d", &sw_if_index))
7265         sw_if_index_set = 1;
7266       else
7267         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7268         sw_if_index_set = 1;
7269       else if (unformat (i, "vlan %d", &vlan_id))
7270         vlan_id_set = 1;
7271       else
7272         {
7273           clib_warning ("parse error '%U'", format_unformat_error, i);
7274           return -99;
7275         }
7276     }
7277
7278   if (sw_if_index_set == 0)
7279     {
7280       errmsg ("missing interface name or sw_if_index");
7281       return -99;
7282     }
7283
7284   if (vlan_id_set == 0)
7285     {
7286       errmsg ("missing vlan_id");
7287       return -99;
7288     }
7289   M (CREATE_VLAN_SUBIF, mp);
7290
7291   mp->sw_if_index = ntohl (sw_if_index);
7292   mp->vlan_id = ntohl (vlan_id);
7293
7294   S (mp);
7295   W (ret);
7296   return ret;
7297 }
7298
7299 #define foreach_create_subif_bit                \
7300 _(no_tags)                                      \
7301 _(one_tag)                                      \
7302 _(two_tags)                                     \
7303 _(dot1ad)                                       \
7304 _(exact_match)                                  \
7305 _(default_sub)                                  \
7306 _(outer_vlan_id_any)                            \
7307 _(inner_vlan_id_any)
7308
7309 static int
7310 api_create_subif (vat_main_t * vam)
7311 {
7312   unformat_input_t *i = vam->input;
7313   vl_api_create_subif_t *mp;
7314   u32 sw_if_index;
7315   u8 sw_if_index_set = 0;
7316   u32 sub_id;
7317   u8 sub_id_set = 0;
7318   u32 no_tags = 0;
7319   u32 one_tag = 0;
7320   u32 two_tags = 0;
7321   u32 dot1ad = 0;
7322   u32 exact_match = 0;
7323   u32 default_sub = 0;
7324   u32 outer_vlan_id_any = 0;
7325   u32 inner_vlan_id_any = 0;
7326   u32 tmp;
7327   u16 outer_vlan_id = 0;
7328   u16 inner_vlan_id = 0;
7329   int ret;
7330
7331   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7332     {
7333       if (unformat (i, "sw_if_index %d", &sw_if_index))
7334         sw_if_index_set = 1;
7335       else
7336         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7337         sw_if_index_set = 1;
7338       else if (unformat (i, "sub_id %d", &sub_id))
7339         sub_id_set = 1;
7340       else if (unformat (i, "outer_vlan_id %d", &tmp))
7341         outer_vlan_id = tmp;
7342       else if (unformat (i, "inner_vlan_id %d", &tmp))
7343         inner_vlan_id = tmp;
7344
7345 #define _(a) else if (unformat (i, #a)) a = 1 ;
7346       foreach_create_subif_bit
7347 #undef _
7348         else
7349         {
7350           clib_warning ("parse error '%U'", format_unformat_error, i);
7351           return -99;
7352         }
7353     }
7354
7355   if (sw_if_index_set == 0)
7356     {
7357       errmsg ("missing interface name or sw_if_index");
7358       return -99;
7359     }
7360
7361   if (sub_id_set == 0)
7362     {
7363       errmsg ("missing sub_id");
7364       return -99;
7365     }
7366   M (CREATE_SUBIF, mp);
7367
7368   mp->sw_if_index = ntohl (sw_if_index);
7369   mp->sub_id = ntohl (sub_id);
7370
7371 #define _(a) mp->a = a;
7372   foreach_create_subif_bit;
7373 #undef _
7374
7375   mp->outer_vlan_id = ntohs (outer_vlan_id);
7376   mp->inner_vlan_id = ntohs (inner_vlan_id);
7377
7378   S (mp);
7379   W (ret);
7380   return ret;
7381 }
7382
7383 static int
7384 api_oam_add_del (vat_main_t * vam)
7385 {
7386   unformat_input_t *i = vam->input;
7387   vl_api_oam_add_del_t *mp;
7388   u32 vrf_id = 0;
7389   u8 is_add = 1;
7390   ip4_address_t src, dst;
7391   u8 src_set = 0;
7392   u8 dst_set = 0;
7393   int ret;
7394
7395   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7396     {
7397       if (unformat (i, "vrf %d", &vrf_id))
7398         ;
7399       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7400         src_set = 1;
7401       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7402         dst_set = 1;
7403       else if (unformat (i, "del"))
7404         is_add = 0;
7405       else
7406         {
7407           clib_warning ("parse error '%U'", format_unformat_error, i);
7408           return -99;
7409         }
7410     }
7411
7412   if (src_set == 0)
7413     {
7414       errmsg ("missing src addr");
7415       return -99;
7416     }
7417
7418   if (dst_set == 0)
7419     {
7420       errmsg ("missing dst addr");
7421       return -99;
7422     }
7423
7424   M (OAM_ADD_DEL, mp);
7425
7426   mp->vrf_id = ntohl (vrf_id);
7427   mp->is_add = is_add;
7428   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7429   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7430
7431   S (mp);
7432   W (ret);
7433   return ret;
7434 }
7435
7436 static int
7437 api_reset_fib (vat_main_t * vam)
7438 {
7439   unformat_input_t *i = vam->input;
7440   vl_api_reset_fib_t *mp;
7441   u32 vrf_id = 0;
7442   u8 is_ipv6 = 0;
7443   u8 vrf_id_set = 0;
7444
7445   int ret;
7446   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7447     {
7448       if (unformat (i, "vrf %d", &vrf_id))
7449         vrf_id_set = 1;
7450       else if (unformat (i, "ipv6"))
7451         is_ipv6 = 1;
7452       else
7453         {
7454           clib_warning ("parse error '%U'", format_unformat_error, i);
7455           return -99;
7456         }
7457     }
7458
7459   if (vrf_id_set == 0)
7460     {
7461       errmsg ("missing vrf id");
7462       return -99;
7463     }
7464
7465   M (RESET_FIB, mp);
7466
7467   mp->vrf_id = ntohl (vrf_id);
7468   mp->is_ipv6 = is_ipv6;
7469
7470   S (mp);
7471   W (ret);
7472   return ret;
7473 }
7474
7475 static int
7476 api_dhcp_proxy_config (vat_main_t * vam)
7477 {
7478   unformat_input_t *i = vam->input;
7479   vl_api_dhcp_proxy_config_t *mp;
7480   u32 rx_vrf_id = 0;
7481   u32 server_vrf_id = 0;
7482   u8 is_add = 1;
7483   u8 v4_address_set = 0;
7484   u8 v6_address_set = 0;
7485   ip4_address_t v4address;
7486   ip6_address_t v6address;
7487   u8 v4_src_address_set = 0;
7488   u8 v6_src_address_set = 0;
7489   ip4_address_t v4srcaddress;
7490   ip6_address_t v6srcaddress;
7491   int ret;
7492
7493   /* Parse args required to build the message */
7494   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7495     {
7496       if (unformat (i, "del"))
7497         is_add = 0;
7498       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7499         ;
7500       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7501         ;
7502       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7503         v4_address_set = 1;
7504       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7505         v6_address_set = 1;
7506       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7507         v4_src_address_set = 1;
7508       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7509         v6_src_address_set = 1;
7510       else
7511         break;
7512     }
7513
7514   if (v4_address_set && v6_address_set)
7515     {
7516       errmsg ("both v4 and v6 server addresses set");
7517       return -99;
7518     }
7519   if (!v4_address_set && !v6_address_set)
7520     {
7521       errmsg ("no server addresses set");
7522       return -99;
7523     }
7524
7525   if (v4_src_address_set && v6_src_address_set)
7526     {
7527       errmsg ("both v4 and v6  src addresses set");
7528       return -99;
7529     }
7530   if (!v4_src_address_set && !v6_src_address_set)
7531     {
7532       errmsg ("no src addresses set");
7533       return -99;
7534     }
7535
7536   if (!(v4_src_address_set && v4_address_set) &&
7537       !(v6_src_address_set && v6_address_set))
7538     {
7539       errmsg ("no matching server and src addresses set");
7540       return -99;
7541     }
7542
7543   /* Construct the API message */
7544   M (DHCP_PROXY_CONFIG, mp);
7545
7546   mp->is_add = is_add;
7547   mp->rx_vrf_id = ntohl (rx_vrf_id);
7548   mp->server_vrf_id = ntohl (server_vrf_id);
7549   if (v6_address_set)
7550     {
7551       mp->is_ipv6 = 1;
7552       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7553       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7554     }
7555   else
7556     {
7557       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7558       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7559     }
7560
7561   /* send it... */
7562   S (mp);
7563
7564   /* Wait for a reply, return good/bad news  */
7565   W (ret);
7566   return ret;
7567 }
7568
7569 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
7570 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
7571
7572 static void
7573 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
7574 {
7575   vat_main_t *vam = &vat_main;
7576   u32 i, count = mp->count;
7577   vl_api_dhcp_server_t *s;
7578
7579   if (mp->is_ipv6)
7580     print (vam->ofp,
7581            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7582            ntohl (mp->rx_vrf_id),
7583            format_ip6_address, mp->dhcp_src_address,
7584            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7585   else
7586     print (vam->ofp,
7587            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7588            ntohl (mp->rx_vrf_id),
7589            format_ip4_address, mp->dhcp_src_address,
7590            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7591
7592   for (i = 0; i < count; i++)
7593     {
7594       s = &mp->servers[i];
7595
7596       if (mp->is_ipv6)
7597         print (vam->ofp,
7598                " Server Table-ID %d, Server Address %U",
7599                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
7600       else
7601         print (vam->ofp,
7602                " Server Table-ID %d, Server Address %U",
7603                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
7604     }
7605 }
7606
7607 static void vl_api_dhcp_proxy_details_t_handler_json
7608   (vl_api_dhcp_proxy_details_t * mp)
7609 {
7610   vat_main_t *vam = &vat_main;
7611   vat_json_node_t *node = NULL;
7612   u32 i, count = mp->count;
7613   struct in_addr ip4;
7614   struct in6_addr ip6;
7615   vl_api_dhcp_server_t *s;
7616
7617   if (VAT_JSON_ARRAY != vam->json_tree.type)
7618     {
7619       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7620       vat_json_init_array (&vam->json_tree);
7621     }
7622   node = vat_json_array_add (&vam->json_tree);
7623
7624   vat_json_init_object (node);
7625   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
7626   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
7627   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
7628
7629   if (mp->is_ipv6)
7630     {
7631       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
7632       vat_json_object_add_ip6 (node, "src_address", ip6);
7633     }
7634   else
7635     {
7636       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
7637       vat_json_object_add_ip4 (node, "src_address", ip4);
7638     }
7639
7640   for (i = 0; i < count; i++)
7641     {
7642       s = &mp->servers[i];
7643
7644       vat_json_object_add_uint (node, "server-table-id",
7645                                 ntohl (s->server_vrf_id));
7646
7647       if (mp->is_ipv6)
7648         {
7649           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
7650           vat_json_object_add_ip4 (node, "src_address", ip4);
7651         }
7652       else
7653         {
7654           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
7655           vat_json_object_add_ip6 (node, "server_address", ip6);
7656         }
7657     }
7658 }
7659
7660 static int
7661 api_dhcp_proxy_dump (vat_main_t * vam)
7662 {
7663   unformat_input_t *i = vam->input;
7664   vl_api_control_ping_t *mp_ping;
7665   vl_api_dhcp_proxy_dump_t *mp;
7666   u8 is_ipv6 = 0;
7667   int ret;
7668
7669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7670     {
7671       if (unformat (i, "ipv6"))
7672         is_ipv6 = 1;
7673       else
7674         {
7675           clib_warning ("parse error '%U'", format_unformat_error, i);
7676           return -99;
7677         }
7678     }
7679
7680   M (DHCP_PROXY_DUMP, mp);
7681
7682   mp->is_ip6 = is_ipv6;
7683   S (mp);
7684
7685   /* Use a control ping for synchronization */
7686   M (CONTROL_PING, mp_ping);
7687   S (mp_ping);
7688
7689   W (ret);
7690   return ret;
7691 }
7692
7693 static int
7694 api_dhcp_proxy_set_vss (vat_main_t * vam)
7695 {
7696   unformat_input_t *i = vam->input;
7697   vl_api_dhcp_proxy_set_vss_t *mp;
7698   u8 is_ipv6 = 0;
7699   u8 is_add = 1;
7700   u32 tbl_id;
7701   u8 tbl_id_set = 0;
7702   u32 oui;
7703   u8 oui_set = 0;
7704   u32 fib_id;
7705   u8 fib_id_set = 0;
7706   int ret;
7707
7708   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7709     {
7710       if (unformat (i, "tbl_id %d", &tbl_id))
7711         tbl_id_set = 1;
7712       if (unformat (i, "fib_id %d", &fib_id))
7713         fib_id_set = 1;
7714       if (unformat (i, "oui %d", &oui))
7715         oui_set = 1;
7716       else if (unformat (i, "ipv6"))
7717         is_ipv6 = 1;
7718       else if (unformat (i, "del"))
7719         is_add = 0;
7720       else
7721         {
7722           clib_warning ("parse error '%U'", format_unformat_error, i);
7723           return -99;
7724         }
7725     }
7726
7727   if (tbl_id_set == 0)
7728     {
7729       errmsg ("missing tbl id");
7730       return -99;
7731     }
7732
7733   if (fib_id_set == 0)
7734     {
7735       errmsg ("missing fib id");
7736       return -99;
7737     }
7738   if (oui_set == 0)
7739     {
7740       errmsg ("missing oui");
7741       return -99;
7742     }
7743
7744   M (DHCP_PROXY_SET_VSS, mp);
7745   mp->tbl_id = ntohl (tbl_id);
7746   mp->fib_id = ntohl (fib_id);
7747   mp->oui = ntohl (oui);
7748   mp->is_ipv6 = is_ipv6;
7749   mp->is_add = is_add;
7750
7751   S (mp);
7752   W (ret);
7753   return ret;
7754 }
7755
7756 static int
7757 api_dhcp_client_config (vat_main_t * vam)
7758 {
7759   unformat_input_t *i = vam->input;
7760   vl_api_dhcp_client_config_t *mp;
7761   u32 sw_if_index;
7762   u8 sw_if_index_set = 0;
7763   u8 is_add = 1;
7764   u8 *hostname = 0;
7765   u8 disable_event = 0;
7766   int ret;
7767
7768   /* Parse args required to build the message */
7769   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7770     {
7771       if (unformat (i, "del"))
7772         is_add = 0;
7773       else
7774         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7775         sw_if_index_set = 1;
7776       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7777         sw_if_index_set = 1;
7778       else if (unformat (i, "hostname %s", &hostname))
7779         ;
7780       else if (unformat (i, "disable_event"))
7781         disable_event = 1;
7782       else
7783         break;
7784     }
7785
7786   if (sw_if_index_set == 0)
7787     {
7788       errmsg ("missing interface name or sw_if_index");
7789       return -99;
7790     }
7791
7792   if (vec_len (hostname) > 63)
7793     {
7794       errmsg ("hostname too long");
7795     }
7796   vec_add1 (hostname, 0);
7797
7798   /* Construct the API message */
7799   M (DHCP_CLIENT_CONFIG, mp);
7800
7801   mp->sw_if_index = ntohl (sw_if_index);
7802   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7803   vec_free (hostname);
7804   mp->is_add = is_add;
7805   mp->want_dhcp_event = disable_event ? 0 : 1;
7806   mp->pid = getpid ();
7807
7808   /* send it... */
7809   S (mp);
7810
7811   /* Wait for a reply, return good/bad news  */
7812   W (ret);
7813   return ret;
7814 }
7815
7816 static int
7817 api_set_ip_flow_hash (vat_main_t * vam)
7818 {
7819   unformat_input_t *i = vam->input;
7820   vl_api_set_ip_flow_hash_t *mp;
7821   u32 vrf_id = 0;
7822   u8 is_ipv6 = 0;
7823   u8 vrf_id_set = 0;
7824   u8 src = 0;
7825   u8 dst = 0;
7826   u8 sport = 0;
7827   u8 dport = 0;
7828   u8 proto = 0;
7829   u8 reverse = 0;
7830   int ret;
7831
7832   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7833     {
7834       if (unformat (i, "vrf %d", &vrf_id))
7835         vrf_id_set = 1;
7836       else if (unformat (i, "ipv6"))
7837         is_ipv6 = 1;
7838       else if (unformat (i, "src"))
7839         src = 1;
7840       else if (unformat (i, "dst"))
7841         dst = 1;
7842       else if (unformat (i, "sport"))
7843         sport = 1;
7844       else if (unformat (i, "dport"))
7845         dport = 1;
7846       else if (unformat (i, "proto"))
7847         proto = 1;
7848       else if (unformat (i, "reverse"))
7849         reverse = 1;
7850
7851       else
7852         {
7853           clib_warning ("parse error '%U'", format_unformat_error, i);
7854           return -99;
7855         }
7856     }
7857
7858   if (vrf_id_set == 0)
7859     {
7860       errmsg ("missing vrf id");
7861       return -99;
7862     }
7863
7864   M (SET_IP_FLOW_HASH, mp);
7865   mp->src = src;
7866   mp->dst = dst;
7867   mp->sport = sport;
7868   mp->dport = dport;
7869   mp->proto = proto;
7870   mp->reverse = reverse;
7871   mp->vrf_id = ntohl (vrf_id);
7872   mp->is_ipv6 = is_ipv6;
7873
7874   S (mp);
7875   W (ret);
7876   return ret;
7877 }
7878
7879 static int
7880 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7881 {
7882   unformat_input_t *i = vam->input;
7883   vl_api_sw_interface_ip6_enable_disable_t *mp;
7884   u32 sw_if_index;
7885   u8 sw_if_index_set = 0;
7886   u8 enable = 0;
7887   int ret;
7888
7889   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7890     {
7891       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7892         sw_if_index_set = 1;
7893       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7894         sw_if_index_set = 1;
7895       else if (unformat (i, "enable"))
7896         enable = 1;
7897       else if (unformat (i, "disable"))
7898         enable = 0;
7899       else
7900         {
7901           clib_warning ("parse error '%U'", format_unformat_error, i);
7902           return -99;
7903         }
7904     }
7905
7906   if (sw_if_index_set == 0)
7907     {
7908       errmsg ("missing interface name or sw_if_index");
7909       return -99;
7910     }
7911
7912   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
7913
7914   mp->sw_if_index = ntohl (sw_if_index);
7915   mp->enable = enable;
7916
7917   S (mp);
7918   W (ret);
7919   return ret;
7920 }
7921
7922 static int
7923 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7924 {
7925   unformat_input_t *i = vam->input;
7926   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7927   u32 sw_if_index;
7928   u8 sw_if_index_set = 0;
7929   u8 v6_address_set = 0;
7930   ip6_address_t v6address;
7931   int ret;
7932
7933   /* Parse args required to build the message */
7934   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7935     {
7936       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7937         sw_if_index_set = 1;
7938       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7939         sw_if_index_set = 1;
7940       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
7941         v6_address_set = 1;
7942       else
7943         break;
7944     }
7945
7946   if (sw_if_index_set == 0)
7947     {
7948       errmsg ("missing interface name or sw_if_index");
7949       return -99;
7950     }
7951   if (!v6_address_set)
7952     {
7953       errmsg ("no address set");
7954       return -99;
7955     }
7956
7957   /* Construct the API message */
7958   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
7959
7960   mp->sw_if_index = ntohl (sw_if_index);
7961   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7962
7963   /* send it... */
7964   S (mp);
7965
7966   /* Wait for a reply, return good/bad news  */
7967   W (ret);
7968   return ret;
7969 }
7970
7971
7972 static int
7973 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7974 {
7975   unformat_input_t *i = vam->input;
7976   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7977   u32 sw_if_index;
7978   u8 sw_if_index_set = 0;
7979   u32 address_length = 0;
7980   u8 v6_address_set = 0;
7981   ip6_address_t v6address;
7982   u8 use_default = 0;
7983   u8 no_advertise = 0;
7984   u8 off_link = 0;
7985   u8 no_autoconfig = 0;
7986   u8 no_onlink = 0;
7987   u8 is_no = 0;
7988   u32 val_lifetime = 0;
7989   u32 pref_lifetime = 0;
7990   int ret;
7991
7992   /* Parse args required to build the message */
7993   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7994     {
7995       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7996         sw_if_index_set = 1;
7997       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7998         sw_if_index_set = 1;
7999       else if (unformat (i, "%U/%d",
8000                          unformat_ip6_address, &v6address, &address_length))
8001         v6_address_set = 1;
8002       else if (unformat (i, "val_life %d", &val_lifetime))
8003         ;
8004       else if (unformat (i, "pref_life %d", &pref_lifetime))
8005         ;
8006       else if (unformat (i, "def"))
8007         use_default = 1;
8008       else if (unformat (i, "noadv"))
8009         no_advertise = 1;
8010       else if (unformat (i, "offl"))
8011         off_link = 1;
8012       else if (unformat (i, "noauto"))
8013         no_autoconfig = 1;
8014       else if (unformat (i, "nolink"))
8015         no_onlink = 1;
8016       else if (unformat (i, "isno"))
8017         is_no = 1;
8018       else
8019         {
8020           clib_warning ("parse error '%U'", format_unformat_error, i);
8021           return -99;
8022         }
8023     }
8024
8025   if (sw_if_index_set == 0)
8026     {
8027       errmsg ("missing interface name or sw_if_index");
8028       return -99;
8029     }
8030   if (!v6_address_set)
8031     {
8032       errmsg ("no address set");
8033       return -99;
8034     }
8035
8036   /* Construct the API message */
8037   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
8038
8039   mp->sw_if_index = ntohl (sw_if_index);
8040   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8041   mp->address_length = address_length;
8042   mp->use_default = use_default;
8043   mp->no_advertise = no_advertise;
8044   mp->off_link = off_link;
8045   mp->no_autoconfig = no_autoconfig;
8046   mp->no_onlink = no_onlink;
8047   mp->is_no = is_no;
8048   mp->val_lifetime = ntohl (val_lifetime);
8049   mp->pref_lifetime = ntohl (pref_lifetime);
8050
8051   /* send it... */
8052   S (mp);
8053
8054   /* Wait for a reply, return good/bad news  */
8055   W (ret);
8056   return ret;
8057 }
8058
8059 static int
8060 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
8061 {
8062   unformat_input_t *i = vam->input;
8063   vl_api_sw_interface_ip6nd_ra_config_t *mp;
8064   u32 sw_if_index;
8065   u8 sw_if_index_set = 0;
8066   u8 suppress = 0;
8067   u8 managed = 0;
8068   u8 other = 0;
8069   u8 ll_option = 0;
8070   u8 send_unicast = 0;
8071   u8 cease = 0;
8072   u8 is_no = 0;
8073   u8 default_router = 0;
8074   u32 max_interval = 0;
8075   u32 min_interval = 0;
8076   u32 lifetime = 0;
8077   u32 initial_count = 0;
8078   u32 initial_interval = 0;
8079   int ret;
8080
8081
8082   /* Parse args required to build the message */
8083   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8084     {
8085       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8086         sw_if_index_set = 1;
8087       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8088         sw_if_index_set = 1;
8089       else if (unformat (i, "maxint %d", &max_interval))
8090         ;
8091       else if (unformat (i, "minint %d", &min_interval))
8092         ;
8093       else if (unformat (i, "life %d", &lifetime))
8094         ;
8095       else if (unformat (i, "count %d", &initial_count))
8096         ;
8097       else if (unformat (i, "interval %d", &initial_interval))
8098         ;
8099       else if (unformat (i, "suppress") || unformat (i, "surpress"))
8100         suppress = 1;
8101       else if (unformat (i, "managed"))
8102         managed = 1;
8103       else if (unformat (i, "other"))
8104         other = 1;
8105       else if (unformat (i, "ll"))
8106         ll_option = 1;
8107       else if (unformat (i, "send"))
8108         send_unicast = 1;
8109       else if (unformat (i, "cease"))
8110         cease = 1;
8111       else if (unformat (i, "isno"))
8112         is_no = 1;
8113       else if (unformat (i, "def"))
8114         default_router = 1;
8115       else
8116         {
8117           clib_warning ("parse error '%U'", format_unformat_error, i);
8118           return -99;
8119         }
8120     }
8121
8122   if (sw_if_index_set == 0)
8123     {
8124       errmsg ("missing interface name or sw_if_index");
8125       return -99;
8126     }
8127
8128   /* Construct the API message */
8129   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
8130
8131   mp->sw_if_index = ntohl (sw_if_index);
8132   mp->max_interval = ntohl (max_interval);
8133   mp->min_interval = ntohl (min_interval);
8134   mp->lifetime = ntohl (lifetime);
8135   mp->initial_count = ntohl (initial_count);
8136   mp->initial_interval = ntohl (initial_interval);
8137   mp->suppress = suppress;
8138   mp->managed = managed;
8139   mp->other = other;
8140   mp->ll_option = ll_option;
8141   mp->send_unicast = send_unicast;
8142   mp->cease = cease;
8143   mp->is_no = is_no;
8144   mp->default_router = default_router;
8145
8146   /* send it... */
8147   S (mp);
8148
8149   /* Wait for a reply, return good/bad news  */
8150   W (ret);
8151   return ret;
8152 }
8153
8154 static int
8155 api_set_arp_neighbor_limit (vat_main_t * vam)
8156 {
8157   unformat_input_t *i = vam->input;
8158   vl_api_set_arp_neighbor_limit_t *mp;
8159   u32 arp_nbr_limit;
8160   u8 limit_set = 0;
8161   u8 is_ipv6 = 0;
8162   int ret;
8163
8164   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8165     {
8166       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
8167         limit_set = 1;
8168       else if (unformat (i, "ipv6"))
8169         is_ipv6 = 1;
8170       else
8171         {
8172           clib_warning ("parse error '%U'", format_unformat_error, i);
8173           return -99;
8174         }
8175     }
8176
8177   if (limit_set == 0)
8178     {
8179       errmsg ("missing limit value");
8180       return -99;
8181     }
8182
8183   M (SET_ARP_NEIGHBOR_LIMIT, mp);
8184
8185   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
8186   mp->is_ipv6 = is_ipv6;
8187
8188   S (mp);
8189   W (ret);
8190   return ret;
8191 }
8192
8193 static int
8194 api_l2_patch_add_del (vat_main_t * vam)
8195 {
8196   unformat_input_t *i = vam->input;
8197   vl_api_l2_patch_add_del_t *mp;
8198   u32 rx_sw_if_index;
8199   u8 rx_sw_if_index_set = 0;
8200   u32 tx_sw_if_index;
8201   u8 tx_sw_if_index_set = 0;
8202   u8 is_add = 1;
8203   int ret;
8204
8205   /* Parse args required to build the message */
8206   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8207     {
8208       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
8209         rx_sw_if_index_set = 1;
8210       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
8211         tx_sw_if_index_set = 1;
8212       else if (unformat (i, "rx"))
8213         {
8214           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8215             {
8216               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8217                             &rx_sw_if_index))
8218                 rx_sw_if_index_set = 1;
8219             }
8220           else
8221             break;
8222         }
8223       else if (unformat (i, "tx"))
8224         {
8225           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8226             {
8227               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8228                             &tx_sw_if_index))
8229                 tx_sw_if_index_set = 1;
8230             }
8231           else
8232             break;
8233         }
8234       else if (unformat (i, "del"))
8235         is_add = 0;
8236       else
8237         break;
8238     }
8239
8240   if (rx_sw_if_index_set == 0)
8241     {
8242       errmsg ("missing rx interface name or rx_sw_if_index");
8243       return -99;
8244     }
8245
8246   if (tx_sw_if_index_set == 0)
8247     {
8248       errmsg ("missing tx interface name or tx_sw_if_index");
8249       return -99;
8250     }
8251
8252   M (L2_PATCH_ADD_DEL, mp);
8253
8254   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
8255   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
8256   mp->is_add = is_add;
8257
8258   S (mp);
8259   W (ret);
8260   return ret;
8261 }
8262
8263 u8 is_del;
8264 u8 localsid_addr[16];
8265 u8 end_psp;
8266 u8 behavior;
8267 u32 sw_if_index;
8268 u32 vlan_index;
8269 u32 fib_table;
8270 u8 nh_addr[16];
8271
8272 static int
8273 api_sr_localsid_add_del (vat_main_t * vam)
8274 {
8275   unformat_input_t *i = vam->input;
8276   vl_api_sr_localsid_add_del_t *mp;
8277
8278   u8 is_del;
8279   ip6_address_t localsid;
8280   u8 end_psp = 0;
8281   u8 behavior = ~0;
8282   u32 sw_if_index;
8283   u32 fib_table = ~(u32) 0;
8284   ip6_address_t next_hop;
8285
8286   bool nexthop_set = 0;
8287
8288   int ret;
8289
8290   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8291     {
8292       if (unformat (i, "del"))
8293         is_del = 1;
8294       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
8295       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
8296         nexthop_set = 1;
8297       else if (unformat (i, "behavior %u", &behavior));
8298       else if (unformat (i, "sw_if_index %u", &sw_if_index));
8299       else if (unformat (i, "fib-table %u", &fib_table));
8300       else if (unformat (i, "end.psp %u", &behavior));
8301       else
8302         break;
8303     }
8304
8305   M (SR_LOCALSID_ADD_DEL, mp);
8306
8307   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
8308   if (nexthop_set)
8309     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
8310   mp->behavior = behavior;
8311   mp->sw_if_index = ntohl (sw_if_index);
8312   mp->fib_table = ntohl (fib_table);
8313   mp->end_psp = end_psp;
8314   mp->is_del = is_del;
8315
8316   S (mp);
8317   W (ret);
8318   return ret;
8319 }
8320
8321 static int
8322 api_ioam_enable (vat_main_t * vam)
8323 {
8324   unformat_input_t *input = vam->input;
8325   vl_api_ioam_enable_t *mp;
8326   u32 id = 0;
8327   int has_trace_option = 0;
8328   int has_pot_option = 0;
8329   int has_seqno_option = 0;
8330   int has_analyse_option = 0;
8331   int ret;
8332
8333   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8334     {
8335       if (unformat (input, "trace"))
8336         has_trace_option = 1;
8337       else if (unformat (input, "pot"))
8338         has_pot_option = 1;
8339       else if (unformat (input, "seqno"))
8340         has_seqno_option = 1;
8341       else if (unformat (input, "analyse"))
8342         has_analyse_option = 1;
8343       else
8344         break;
8345     }
8346   M (IOAM_ENABLE, mp);
8347   mp->id = htons (id);
8348   mp->seqno = has_seqno_option;
8349   mp->analyse = has_analyse_option;
8350   mp->pot_enable = has_pot_option;
8351   mp->trace_enable = has_trace_option;
8352
8353   S (mp);
8354   W (ret);
8355   return ret;
8356 }
8357
8358
8359 static int
8360 api_ioam_disable (vat_main_t * vam)
8361 {
8362   vl_api_ioam_disable_t *mp;
8363   int ret;
8364
8365   M (IOAM_DISABLE, mp);
8366   S (mp);
8367   W (ret);
8368   return ret;
8369 }
8370
8371 #define foreach_tcp_proto_field                 \
8372 _(src_port)                                     \
8373 _(dst_port)
8374
8375 #define foreach_udp_proto_field                 \
8376 _(src_port)                                     \
8377 _(dst_port)
8378
8379 #define foreach_ip4_proto_field                 \
8380 _(src_address)                                  \
8381 _(dst_address)                                  \
8382 _(tos)                                          \
8383 _(length)                                       \
8384 _(fragment_id)                                  \
8385 _(ttl)                                          \
8386 _(protocol)                                     \
8387 _(checksum)
8388
8389 typedef struct
8390 {
8391   u16 src_port, dst_port;
8392 } tcpudp_header_t;
8393
8394 #if VPP_API_TEST_BUILTIN == 0
8395 uword
8396 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8397 {
8398   u8 **maskp = va_arg (*args, u8 **);
8399   u8 *mask = 0;
8400   u8 found_something = 0;
8401   tcp_header_t *tcp;
8402
8403 #define _(a) u8 a=0;
8404   foreach_tcp_proto_field;
8405 #undef _
8406
8407   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8408     {
8409       if (0);
8410 #define _(a) else if (unformat (input, #a)) a=1;
8411       foreach_tcp_proto_field
8412 #undef _
8413         else
8414         break;
8415     }
8416
8417 #define _(a) found_something += a;
8418   foreach_tcp_proto_field;
8419 #undef _
8420
8421   if (found_something == 0)
8422     return 0;
8423
8424   vec_validate (mask, sizeof (*tcp) - 1);
8425
8426   tcp = (tcp_header_t *) mask;
8427
8428 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8429   foreach_tcp_proto_field;
8430 #undef _
8431
8432   *maskp = mask;
8433   return 1;
8434 }
8435
8436 uword
8437 unformat_udp_mask (unformat_input_t * input, va_list * args)
8438 {
8439   u8 **maskp = va_arg (*args, u8 **);
8440   u8 *mask = 0;
8441   u8 found_something = 0;
8442   udp_header_t *udp;
8443
8444 #define _(a) u8 a=0;
8445   foreach_udp_proto_field;
8446 #undef _
8447
8448   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8449     {
8450       if (0);
8451 #define _(a) else if (unformat (input, #a)) a=1;
8452       foreach_udp_proto_field
8453 #undef _
8454         else
8455         break;
8456     }
8457
8458 #define _(a) found_something += a;
8459   foreach_udp_proto_field;
8460 #undef _
8461
8462   if (found_something == 0)
8463     return 0;
8464
8465   vec_validate (mask, sizeof (*udp) - 1);
8466
8467   udp = (udp_header_t *) mask;
8468
8469 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8470   foreach_udp_proto_field;
8471 #undef _
8472
8473   *maskp = mask;
8474   return 1;
8475 }
8476
8477 uword
8478 unformat_l4_mask (unformat_input_t * input, va_list * args)
8479 {
8480   u8 **maskp = va_arg (*args, u8 **);
8481   u16 src_port = 0, dst_port = 0;
8482   tcpudp_header_t *tcpudp;
8483
8484   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8485     {
8486       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8487         return 1;
8488       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8489         return 1;
8490       else if (unformat (input, "src_port"))
8491         src_port = 0xFFFF;
8492       else if (unformat (input, "dst_port"))
8493         dst_port = 0xFFFF;
8494       else
8495         return 0;
8496     }
8497
8498   if (!src_port && !dst_port)
8499     return 0;
8500
8501   u8 *mask = 0;
8502   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8503
8504   tcpudp = (tcpudp_header_t *) mask;
8505   tcpudp->src_port = src_port;
8506   tcpudp->dst_port = dst_port;
8507
8508   *maskp = mask;
8509
8510   return 1;
8511 }
8512
8513 uword
8514 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8515 {
8516   u8 **maskp = va_arg (*args, u8 **);
8517   u8 *mask = 0;
8518   u8 found_something = 0;
8519   ip4_header_t *ip;
8520
8521 #define _(a) u8 a=0;
8522   foreach_ip4_proto_field;
8523 #undef _
8524   u8 version = 0;
8525   u8 hdr_length = 0;
8526
8527
8528   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8529     {
8530       if (unformat (input, "version"))
8531         version = 1;
8532       else if (unformat (input, "hdr_length"))
8533         hdr_length = 1;
8534       else if (unformat (input, "src"))
8535         src_address = 1;
8536       else if (unformat (input, "dst"))
8537         dst_address = 1;
8538       else if (unformat (input, "proto"))
8539         protocol = 1;
8540
8541 #define _(a) else if (unformat (input, #a)) a=1;
8542       foreach_ip4_proto_field
8543 #undef _
8544         else
8545         break;
8546     }
8547
8548 #define _(a) found_something += a;
8549   foreach_ip4_proto_field;
8550 #undef _
8551
8552   if (found_something == 0)
8553     return 0;
8554
8555   vec_validate (mask, sizeof (*ip) - 1);
8556
8557   ip = (ip4_header_t *) mask;
8558
8559 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8560   foreach_ip4_proto_field;
8561 #undef _
8562
8563   ip->ip_version_and_header_length = 0;
8564
8565   if (version)
8566     ip->ip_version_and_header_length |= 0xF0;
8567
8568   if (hdr_length)
8569     ip->ip_version_and_header_length |= 0x0F;
8570
8571   *maskp = mask;
8572   return 1;
8573 }
8574
8575 #define foreach_ip6_proto_field                 \
8576 _(src_address)                                  \
8577 _(dst_address)                                  \
8578 _(payload_length)                               \
8579 _(hop_limit)                                    \
8580 _(protocol)
8581
8582 uword
8583 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8584 {
8585   u8 **maskp = va_arg (*args, u8 **);
8586   u8 *mask = 0;
8587   u8 found_something = 0;
8588   ip6_header_t *ip;
8589   u32 ip_version_traffic_class_and_flow_label;
8590
8591 #define _(a) u8 a=0;
8592   foreach_ip6_proto_field;
8593 #undef _
8594   u8 version = 0;
8595   u8 traffic_class = 0;
8596   u8 flow_label = 0;
8597
8598   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8599     {
8600       if (unformat (input, "version"))
8601         version = 1;
8602       else if (unformat (input, "traffic-class"))
8603         traffic_class = 1;
8604       else if (unformat (input, "flow-label"))
8605         flow_label = 1;
8606       else if (unformat (input, "src"))
8607         src_address = 1;
8608       else if (unformat (input, "dst"))
8609         dst_address = 1;
8610       else if (unformat (input, "proto"))
8611         protocol = 1;
8612
8613 #define _(a) else if (unformat (input, #a)) a=1;
8614       foreach_ip6_proto_field
8615 #undef _
8616         else
8617         break;
8618     }
8619
8620 #define _(a) found_something += a;
8621   foreach_ip6_proto_field;
8622 #undef _
8623
8624   if (found_something == 0)
8625     return 0;
8626
8627   vec_validate (mask, sizeof (*ip) - 1);
8628
8629   ip = (ip6_header_t *) mask;
8630
8631 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8632   foreach_ip6_proto_field;
8633 #undef _
8634
8635   ip_version_traffic_class_and_flow_label = 0;
8636
8637   if (version)
8638     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8639
8640   if (traffic_class)
8641     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8642
8643   if (flow_label)
8644     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8645
8646   ip->ip_version_traffic_class_and_flow_label =
8647     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8648
8649   *maskp = mask;
8650   return 1;
8651 }
8652
8653 uword
8654 unformat_l3_mask (unformat_input_t * input, va_list * args)
8655 {
8656   u8 **maskp = va_arg (*args, u8 **);
8657
8658   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8659     {
8660       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8661         return 1;
8662       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8663         return 1;
8664       else
8665         break;
8666     }
8667   return 0;
8668 }
8669
8670 uword
8671 unformat_l2_mask (unformat_input_t * input, va_list * args)
8672 {
8673   u8 **maskp = va_arg (*args, u8 **);
8674   u8 *mask = 0;
8675   u8 src = 0;
8676   u8 dst = 0;
8677   u8 proto = 0;
8678   u8 tag1 = 0;
8679   u8 tag2 = 0;
8680   u8 ignore_tag1 = 0;
8681   u8 ignore_tag2 = 0;
8682   u8 cos1 = 0;
8683   u8 cos2 = 0;
8684   u8 dot1q = 0;
8685   u8 dot1ad = 0;
8686   int len = 14;
8687
8688   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8689     {
8690       if (unformat (input, "src"))
8691         src = 1;
8692       else if (unformat (input, "dst"))
8693         dst = 1;
8694       else if (unformat (input, "proto"))
8695         proto = 1;
8696       else if (unformat (input, "tag1"))
8697         tag1 = 1;
8698       else if (unformat (input, "tag2"))
8699         tag2 = 1;
8700       else if (unformat (input, "ignore-tag1"))
8701         ignore_tag1 = 1;
8702       else if (unformat (input, "ignore-tag2"))
8703         ignore_tag2 = 1;
8704       else if (unformat (input, "cos1"))
8705         cos1 = 1;
8706       else if (unformat (input, "cos2"))
8707         cos2 = 1;
8708       else if (unformat (input, "dot1q"))
8709         dot1q = 1;
8710       else if (unformat (input, "dot1ad"))
8711         dot1ad = 1;
8712       else
8713         break;
8714     }
8715   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8716        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8717     return 0;
8718
8719   if (tag1 || ignore_tag1 || cos1 || dot1q)
8720     len = 18;
8721   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8722     len = 22;
8723
8724   vec_validate (mask, len - 1);
8725
8726   if (dst)
8727     memset (mask, 0xff, 6);
8728
8729   if (src)
8730     memset (mask + 6, 0xff, 6);
8731
8732   if (tag2 || dot1ad)
8733     {
8734       /* inner vlan tag */
8735       if (tag2)
8736         {
8737           mask[19] = 0xff;
8738           mask[18] = 0x0f;
8739         }
8740       if (cos2)
8741         mask[18] |= 0xe0;
8742       if (proto)
8743         mask[21] = mask[20] = 0xff;
8744       if (tag1)
8745         {
8746           mask[15] = 0xff;
8747           mask[14] = 0x0f;
8748         }
8749       if (cos1)
8750         mask[14] |= 0xe0;
8751       *maskp = mask;
8752       return 1;
8753     }
8754   if (tag1 | dot1q)
8755     {
8756       if (tag1)
8757         {
8758           mask[15] = 0xff;
8759           mask[14] = 0x0f;
8760         }
8761       if (cos1)
8762         mask[14] |= 0xe0;
8763       if (proto)
8764         mask[16] = mask[17] = 0xff;
8765
8766       *maskp = mask;
8767       return 1;
8768     }
8769   if (cos2)
8770     mask[18] |= 0xe0;
8771   if (cos1)
8772     mask[14] |= 0xe0;
8773   if (proto)
8774     mask[12] = mask[13] = 0xff;
8775
8776   *maskp = mask;
8777   return 1;
8778 }
8779
8780 uword
8781 unformat_classify_mask (unformat_input_t * input, va_list * args)
8782 {
8783   u8 **maskp = va_arg (*args, u8 **);
8784   u32 *skipp = va_arg (*args, u32 *);
8785   u32 *matchp = va_arg (*args, u32 *);
8786   u32 match;
8787   u8 *mask = 0;
8788   u8 *l2 = 0;
8789   u8 *l3 = 0;
8790   u8 *l4 = 0;
8791   int i;
8792
8793   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8794     {
8795       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8796         ;
8797       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8798         ;
8799       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8800         ;
8801       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8802         ;
8803       else
8804         break;
8805     }
8806
8807   if (l4 && !l3)
8808     {
8809       vec_free (mask);
8810       vec_free (l2);
8811       vec_free (l4);
8812       return 0;
8813     }
8814
8815   if (mask || l2 || l3 || l4)
8816     {
8817       if (l2 || l3 || l4)
8818         {
8819           /* "With a free Ethernet header in every package" */
8820           if (l2 == 0)
8821             vec_validate (l2, 13);
8822           mask = l2;
8823           if (vec_len (l3))
8824             {
8825               vec_append (mask, l3);
8826               vec_free (l3);
8827             }
8828           if (vec_len (l4))
8829             {
8830               vec_append (mask, l4);
8831               vec_free (l4);
8832             }
8833         }
8834
8835       /* Scan forward looking for the first significant mask octet */
8836       for (i = 0; i < vec_len (mask); i++)
8837         if (mask[i])
8838           break;
8839
8840       /* compute (skip, match) params */
8841       *skipp = i / sizeof (u32x4);
8842       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8843
8844       /* Pad mask to an even multiple of the vector size */
8845       while (vec_len (mask) % sizeof (u32x4))
8846         vec_add1 (mask, 0);
8847
8848       match = vec_len (mask) / sizeof (u32x4);
8849
8850       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8851         {
8852           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8853           if (*tmp || *(tmp + 1))
8854             break;
8855           match--;
8856         }
8857       if (match == 0)
8858         clib_warning ("BUG: match 0");
8859
8860       _vec_len (mask) = match * sizeof (u32x4);
8861
8862       *matchp = match;
8863       *maskp = mask;
8864
8865       return 1;
8866     }
8867
8868   return 0;
8869 }
8870 #endif /* VPP_API_TEST_BUILTIN */
8871
8872 #define foreach_l2_next                         \
8873 _(drop, DROP)                                   \
8874 _(ethernet, ETHERNET_INPUT)                     \
8875 _(ip4, IP4_INPUT)                               \
8876 _(ip6, IP6_INPUT)
8877
8878 uword
8879 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8880 {
8881   u32 *miss_next_indexp = va_arg (*args, u32 *);
8882   u32 next_index = 0;
8883   u32 tmp;
8884
8885 #define _(n,N) \
8886   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8887   foreach_l2_next;
8888 #undef _
8889
8890   if (unformat (input, "%d", &tmp))
8891     {
8892       next_index = tmp;
8893       goto out;
8894     }
8895
8896   return 0;
8897
8898 out:
8899   *miss_next_indexp = next_index;
8900   return 1;
8901 }
8902
8903 #define foreach_ip_next                         \
8904 _(drop, DROP)                                   \
8905 _(local, LOCAL)                                 \
8906 _(rewrite, REWRITE)
8907
8908 uword
8909 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
8910 {
8911   u32 *miss_next_indexp = va_arg (*args, u32 *);
8912   u32 next_index = 0;
8913   u32 tmp;
8914
8915 #define _(n,N) \
8916   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8917   foreach_ip_next;
8918 #undef _
8919
8920   if (unformat (input, "%d", &tmp))
8921     {
8922       next_index = tmp;
8923       goto out;
8924     }
8925
8926   return 0;
8927
8928 out:
8929   *miss_next_indexp = next_index;
8930   return 1;
8931 }
8932
8933 #define foreach_acl_next                        \
8934 _(deny, DENY)
8935
8936 uword
8937 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
8938 {
8939   u32 *miss_next_indexp = va_arg (*args, u32 *);
8940   u32 next_index = 0;
8941   u32 tmp;
8942
8943 #define _(n,N) \
8944   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8945   foreach_acl_next;
8946 #undef _
8947
8948   if (unformat (input, "permit"))
8949     {
8950       next_index = ~0;
8951       goto out;
8952     }
8953   else if (unformat (input, "%d", &tmp))
8954     {
8955       next_index = tmp;
8956       goto out;
8957     }
8958
8959   return 0;
8960
8961 out:
8962   *miss_next_indexp = next_index;
8963   return 1;
8964 }
8965
8966 uword
8967 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8968 {
8969   u32 *r = va_arg (*args, u32 *);
8970
8971   if (unformat (input, "conform-color"))
8972     *r = POLICE_CONFORM;
8973   else if (unformat (input, "exceed-color"))
8974     *r = POLICE_EXCEED;
8975   else
8976     return 0;
8977
8978   return 1;
8979 }
8980
8981 static int
8982 api_classify_add_del_table (vat_main_t * vam)
8983 {
8984   unformat_input_t *i = vam->input;
8985   vl_api_classify_add_del_table_t *mp;
8986
8987   u32 nbuckets = 2;
8988   u32 skip = ~0;
8989   u32 match = ~0;
8990   int is_add = 1;
8991   int del_chain = 0;
8992   u32 table_index = ~0;
8993   u32 next_table_index = ~0;
8994   u32 miss_next_index = ~0;
8995   u32 memory_size = 32 << 20;
8996   u8 *mask = 0;
8997   u32 current_data_flag = 0;
8998   int current_data_offset = 0;
8999   int ret;
9000
9001   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9002     {
9003       if (unformat (i, "del"))
9004         is_add = 0;
9005       else if (unformat (i, "del-chain"))
9006         {
9007           is_add = 0;
9008           del_chain = 1;
9009         }
9010       else if (unformat (i, "buckets %d", &nbuckets))
9011         ;
9012       else if (unformat (i, "memory_size %d", &memory_size))
9013         ;
9014       else if (unformat (i, "skip %d", &skip))
9015         ;
9016       else if (unformat (i, "match %d", &match))
9017         ;
9018       else if (unformat (i, "table %d", &table_index))
9019         ;
9020       else if (unformat (i, "mask %U", unformat_classify_mask,
9021                          &mask, &skip, &match))
9022         ;
9023       else if (unformat (i, "next-table %d", &next_table_index))
9024         ;
9025       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
9026                          &miss_next_index))
9027         ;
9028       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
9029                          &miss_next_index))
9030         ;
9031       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
9032                          &miss_next_index))
9033         ;
9034       else if (unformat (i, "current-data-flag %d", &current_data_flag))
9035         ;
9036       else if (unformat (i, "current-data-offset %d", &current_data_offset))
9037         ;
9038       else
9039         break;
9040     }
9041
9042   if (is_add && mask == 0)
9043     {
9044       errmsg ("Mask required");
9045       return -99;
9046     }
9047
9048   if (is_add && skip == ~0)
9049     {
9050       errmsg ("skip count required");
9051       return -99;
9052     }
9053
9054   if (is_add && match == ~0)
9055     {
9056       errmsg ("match count required");
9057       return -99;
9058     }
9059
9060   if (!is_add && table_index == ~0)
9061     {
9062       errmsg ("table index required for delete");
9063       return -99;
9064     }
9065
9066   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
9067
9068   mp->is_add = is_add;
9069   mp->del_chain = del_chain;
9070   mp->table_index = ntohl (table_index);
9071   mp->nbuckets = ntohl (nbuckets);
9072   mp->memory_size = ntohl (memory_size);
9073   mp->skip_n_vectors = ntohl (skip);
9074   mp->match_n_vectors = ntohl (match);
9075   mp->next_table_index = ntohl (next_table_index);
9076   mp->miss_next_index = ntohl (miss_next_index);
9077   mp->current_data_flag = ntohl (current_data_flag);
9078   mp->current_data_offset = ntohl (current_data_offset);
9079   clib_memcpy (mp->mask, mask, vec_len (mask));
9080
9081   vec_free (mask);
9082
9083   S (mp);
9084   W (ret);
9085   return ret;
9086 }
9087
9088 #if VPP_API_TEST_BUILTIN == 0
9089 uword
9090 unformat_l4_match (unformat_input_t * input, va_list * args)
9091 {
9092   u8 **matchp = va_arg (*args, u8 **);
9093
9094   u8 *proto_header = 0;
9095   int src_port = 0;
9096   int dst_port = 0;
9097
9098   tcpudp_header_t h;
9099
9100   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9101     {
9102       if (unformat (input, "src_port %d", &src_port))
9103         ;
9104       else if (unformat (input, "dst_port %d", &dst_port))
9105         ;
9106       else
9107         return 0;
9108     }
9109
9110   h.src_port = clib_host_to_net_u16 (src_port);
9111   h.dst_port = clib_host_to_net_u16 (dst_port);
9112   vec_validate (proto_header, sizeof (h) - 1);
9113   memcpy (proto_header, &h, sizeof (h));
9114
9115   *matchp = proto_header;
9116
9117   return 1;
9118 }
9119
9120 uword
9121 unformat_ip4_match (unformat_input_t * input, va_list * args)
9122 {
9123   u8 **matchp = va_arg (*args, u8 **);
9124   u8 *match = 0;
9125   ip4_header_t *ip;
9126   int version = 0;
9127   u32 version_val;
9128   int hdr_length = 0;
9129   u32 hdr_length_val;
9130   int src = 0, dst = 0;
9131   ip4_address_t src_val, dst_val;
9132   int proto = 0;
9133   u32 proto_val;
9134   int tos = 0;
9135   u32 tos_val;
9136   int length = 0;
9137   u32 length_val;
9138   int fragment_id = 0;
9139   u32 fragment_id_val;
9140   int ttl = 0;
9141   int ttl_val;
9142   int checksum = 0;
9143   u32 checksum_val;
9144
9145   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9146     {
9147       if (unformat (input, "version %d", &version_val))
9148         version = 1;
9149       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9150         hdr_length = 1;
9151       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9152         src = 1;
9153       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9154         dst = 1;
9155       else if (unformat (input, "proto %d", &proto_val))
9156         proto = 1;
9157       else if (unformat (input, "tos %d", &tos_val))
9158         tos = 1;
9159       else if (unformat (input, "length %d", &length_val))
9160         length = 1;
9161       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9162         fragment_id = 1;
9163       else if (unformat (input, "ttl %d", &ttl_val))
9164         ttl = 1;
9165       else if (unformat (input, "checksum %d", &checksum_val))
9166         checksum = 1;
9167       else
9168         break;
9169     }
9170
9171   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9172       + ttl + checksum == 0)
9173     return 0;
9174
9175   /*
9176    * Aligned because we use the real comparison functions
9177    */
9178   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9179
9180   ip = (ip4_header_t *) match;
9181
9182   /* These are realistically matched in practice */
9183   if (src)
9184     ip->src_address.as_u32 = src_val.as_u32;
9185
9186   if (dst)
9187     ip->dst_address.as_u32 = dst_val.as_u32;
9188
9189   if (proto)
9190     ip->protocol = proto_val;
9191
9192
9193   /* These are not, but they're included for completeness */
9194   if (version)
9195     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9196
9197   if (hdr_length)
9198     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9199
9200   if (tos)
9201     ip->tos = tos_val;
9202
9203   if (length)
9204     ip->length = clib_host_to_net_u16 (length_val);
9205
9206   if (ttl)
9207     ip->ttl = ttl_val;
9208
9209   if (checksum)
9210     ip->checksum = clib_host_to_net_u16 (checksum_val);
9211
9212   *matchp = match;
9213   return 1;
9214 }
9215
9216 uword
9217 unformat_ip6_match (unformat_input_t * input, va_list * args)
9218 {
9219   u8 **matchp = va_arg (*args, u8 **);
9220   u8 *match = 0;
9221   ip6_header_t *ip;
9222   int version = 0;
9223   u32 version_val;
9224   u8 traffic_class = 0;
9225   u32 traffic_class_val = 0;
9226   u8 flow_label = 0;
9227   u8 flow_label_val;
9228   int src = 0, dst = 0;
9229   ip6_address_t src_val, dst_val;
9230   int proto = 0;
9231   u32 proto_val;
9232   int payload_length = 0;
9233   u32 payload_length_val;
9234   int hop_limit = 0;
9235   int hop_limit_val;
9236   u32 ip_version_traffic_class_and_flow_label;
9237
9238   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9239     {
9240       if (unformat (input, "version %d", &version_val))
9241         version = 1;
9242       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9243         traffic_class = 1;
9244       else if (unformat (input, "flow_label %d", &flow_label_val))
9245         flow_label = 1;
9246       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9247         src = 1;
9248       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9249         dst = 1;
9250       else if (unformat (input, "proto %d", &proto_val))
9251         proto = 1;
9252       else if (unformat (input, "payload_length %d", &payload_length_val))
9253         payload_length = 1;
9254       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9255         hop_limit = 1;
9256       else
9257         break;
9258     }
9259
9260   if (version + traffic_class + flow_label + src + dst + proto +
9261       payload_length + hop_limit == 0)
9262     return 0;
9263
9264   /*
9265    * Aligned because we use the real comparison functions
9266    */
9267   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9268
9269   ip = (ip6_header_t *) match;
9270
9271   if (src)
9272     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9273
9274   if (dst)
9275     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9276
9277   if (proto)
9278     ip->protocol = proto_val;
9279
9280   ip_version_traffic_class_and_flow_label = 0;
9281
9282   if (version)
9283     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9284
9285   if (traffic_class)
9286     ip_version_traffic_class_and_flow_label |=
9287       (traffic_class_val & 0xFF) << 20;
9288
9289   if (flow_label)
9290     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9291
9292   ip->ip_version_traffic_class_and_flow_label =
9293     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9294
9295   if (payload_length)
9296     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9297
9298   if (hop_limit)
9299     ip->hop_limit = hop_limit_val;
9300
9301   *matchp = match;
9302   return 1;
9303 }
9304
9305 uword
9306 unformat_l3_match (unformat_input_t * input, va_list * args)
9307 {
9308   u8 **matchp = va_arg (*args, u8 **);
9309
9310   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9311     {
9312       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9313         return 1;
9314       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9315         return 1;
9316       else
9317         break;
9318     }
9319   return 0;
9320 }
9321
9322 uword
9323 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9324 {
9325   u8 *tagp = va_arg (*args, u8 *);
9326   u32 tag;
9327
9328   if (unformat (input, "%d", &tag))
9329     {
9330       tagp[0] = (tag >> 8) & 0x0F;
9331       tagp[1] = tag & 0xFF;
9332       return 1;
9333     }
9334
9335   return 0;
9336 }
9337
9338 uword
9339 unformat_l2_match (unformat_input_t * input, va_list * args)
9340 {
9341   u8 **matchp = va_arg (*args, u8 **);
9342   u8 *match = 0;
9343   u8 src = 0;
9344   u8 src_val[6];
9345   u8 dst = 0;
9346   u8 dst_val[6];
9347   u8 proto = 0;
9348   u16 proto_val;
9349   u8 tag1 = 0;
9350   u8 tag1_val[2];
9351   u8 tag2 = 0;
9352   u8 tag2_val[2];
9353   int len = 14;
9354   u8 ignore_tag1 = 0;
9355   u8 ignore_tag2 = 0;
9356   u8 cos1 = 0;
9357   u8 cos2 = 0;
9358   u32 cos1_val = 0;
9359   u32 cos2_val = 0;
9360
9361   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9362     {
9363       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9364         src = 1;
9365       else
9366         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9367         dst = 1;
9368       else if (unformat (input, "proto %U",
9369                          unformat_ethernet_type_host_byte_order, &proto_val))
9370         proto = 1;
9371       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9372         tag1 = 1;
9373       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9374         tag2 = 1;
9375       else if (unformat (input, "ignore-tag1"))
9376         ignore_tag1 = 1;
9377       else if (unformat (input, "ignore-tag2"))
9378         ignore_tag2 = 1;
9379       else if (unformat (input, "cos1 %d", &cos1_val))
9380         cos1 = 1;
9381       else if (unformat (input, "cos2 %d", &cos2_val))
9382         cos2 = 1;
9383       else
9384         break;
9385     }
9386   if ((src + dst + proto + tag1 + tag2 +
9387        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9388     return 0;
9389
9390   if (tag1 || ignore_tag1 || cos1)
9391     len = 18;
9392   if (tag2 || ignore_tag2 || cos2)
9393     len = 22;
9394
9395   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9396
9397   if (dst)
9398     clib_memcpy (match, dst_val, 6);
9399
9400   if (src)
9401     clib_memcpy (match + 6, src_val, 6);
9402
9403   if (tag2)
9404     {
9405       /* inner vlan tag */
9406       match[19] = tag2_val[1];
9407       match[18] = tag2_val[0];
9408       if (cos2)
9409         match[18] |= (cos2_val & 0x7) << 5;
9410       if (proto)
9411         {
9412           match[21] = proto_val & 0xff;
9413           match[20] = proto_val >> 8;
9414         }
9415       if (tag1)
9416         {
9417           match[15] = tag1_val[1];
9418           match[14] = tag1_val[0];
9419         }
9420       if (cos1)
9421         match[14] |= (cos1_val & 0x7) << 5;
9422       *matchp = match;
9423       return 1;
9424     }
9425   if (tag1)
9426     {
9427       match[15] = tag1_val[1];
9428       match[14] = tag1_val[0];
9429       if (proto)
9430         {
9431           match[17] = proto_val & 0xff;
9432           match[16] = proto_val >> 8;
9433         }
9434       if (cos1)
9435         match[14] |= (cos1_val & 0x7) << 5;
9436
9437       *matchp = match;
9438       return 1;
9439     }
9440   if (cos2)
9441     match[18] |= (cos2_val & 0x7) << 5;
9442   if (cos1)
9443     match[14] |= (cos1_val & 0x7) << 5;
9444   if (proto)
9445     {
9446       match[13] = proto_val & 0xff;
9447       match[12] = proto_val >> 8;
9448     }
9449
9450   *matchp = match;
9451   return 1;
9452 }
9453 #endif
9454
9455 uword
9456 api_unformat_classify_match (unformat_input_t * input, va_list * args)
9457 {
9458   u8 **matchp = va_arg (*args, u8 **);
9459   u32 skip_n_vectors = va_arg (*args, u32);
9460   u32 match_n_vectors = va_arg (*args, u32);
9461
9462   u8 *match = 0;
9463   u8 *l2 = 0;
9464   u8 *l3 = 0;
9465   u8 *l4 = 0;
9466
9467   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9468     {
9469       if (unformat (input, "hex %U", unformat_hex_string, &match))
9470         ;
9471       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9472         ;
9473       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9474         ;
9475       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9476         ;
9477       else
9478         break;
9479     }
9480
9481   if (l4 && !l3)
9482     {
9483       vec_free (match);
9484       vec_free (l2);
9485       vec_free (l4);
9486       return 0;
9487     }
9488
9489   if (match || l2 || l3 || l4)
9490     {
9491       if (l2 || l3 || l4)
9492         {
9493           /* "Win a free Ethernet header in every packet" */
9494           if (l2 == 0)
9495             vec_validate_aligned (l2, 13, sizeof (u32x4));
9496           match = l2;
9497           if (vec_len (l3))
9498             {
9499               vec_append_aligned (match, l3, sizeof (u32x4));
9500               vec_free (l3);
9501             }
9502           if (vec_len (l4))
9503             {
9504               vec_append_aligned (match, l4, sizeof (u32x4));
9505               vec_free (l4);
9506             }
9507         }
9508
9509       /* Make sure the vector is big enough even if key is all 0's */
9510       vec_validate_aligned
9511         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9512          sizeof (u32x4));
9513
9514       /* Set size, include skipped vectors */
9515       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9516
9517       *matchp = match;
9518
9519       return 1;
9520     }
9521
9522   return 0;
9523 }
9524
9525 static int
9526 api_classify_add_del_session (vat_main_t * vam)
9527 {
9528   unformat_input_t *i = vam->input;
9529   vl_api_classify_add_del_session_t *mp;
9530   int is_add = 1;
9531   u32 table_index = ~0;
9532   u32 hit_next_index = ~0;
9533   u32 opaque_index = ~0;
9534   u8 *match = 0;
9535   i32 advance = 0;
9536   u32 skip_n_vectors = 0;
9537   u32 match_n_vectors = 0;
9538   u32 action = 0;
9539   u32 metadata = 0;
9540   int ret;
9541
9542   /*
9543    * Warning: you have to supply skip_n and match_n
9544    * because the API client cant simply look at the classify
9545    * table object.
9546    */
9547
9548   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9549     {
9550       if (unformat (i, "del"))
9551         is_add = 0;
9552       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
9553                          &hit_next_index))
9554         ;
9555       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9556                          &hit_next_index))
9557         ;
9558       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
9559                          &hit_next_index))
9560         ;
9561       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9562         ;
9563       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9564         ;
9565       else if (unformat (i, "opaque-index %d", &opaque_index))
9566         ;
9567       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9568         ;
9569       else if (unformat (i, "match_n %d", &match_n_vectors))
9570         ;
9571       else if (unformat (i, "match %U", api_unformat_classify_match,
9572                          &match, skip_n_vectors, match_n_vectors))
9573         ;
9574       else if (unformat (i, "advance %d", &advance))
9575         ;
9576       else if (unformat (i, "table-index %d", &table_index))
9577         ;
9578       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9579         action = 1;
9580       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9581         action = 2;
9582       else if (unformat (i, "action %d", &action))
9583         ;
9584       else if (unformat (i, "metadata %d", &metadata))
9585         ;
9586       else
9587         break;
9588     }
9589
9590   if (table_index == ~0)
9591     {
9592       errmsg ("Table index required");
9593       return -99;
9594     }
9595
9596   if (is_add && match == 0)
9597     {
9598       errmsg ("Match value required");
9599       return -99;
9600     }
9601
9602   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
9603
9604   mp->is_add = is_add;
9605   mp->table_index = ntohl (table_index);
9606   mp->hit_next_index = ntohl (hit_next_index);
9607   mp->opaque_index = ntohl (opaque_index);
9608   mp->advance = ntohl (advance);
9609   mp->action = action;
9610   mp->metadata = ntohl (metadata);
9611   clib_memcpy (mp->match, match, vec_len (match));
9612   vec_free (match);
9613
9614   S (mp);
9615   W (ret);
9616   return ret;
9617 }
9618
9619 static int
9620 api_classify_set_interface_ip_table (vat_main_t * vam)
9621 {
9622   unformat_input_t *i = vam->input;
9623   vl_api_classify_set_interface_ip_table_t *mp;
9624   u32 sw_if_index;
9625   int sw_if_index_set;
9626   u32 table_index = ~0;
9627   u8 is_ipv6 = 0;
9628   int ret;
9629
9630   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9631     {
9632       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9633         sw_if_index_set = 1;
9634       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9635         sw_if_index_set = 1;
9636       else if (unformat (i, "table %d", &table_index))
9637         ;
9638       else
9639         {
9640           clib_warning ("parse error '%U'", format_unformat_error, i);
9641           return -99;
9642         }
9643     }
9644
9645   if (sw_if_index_set == 0)
9646     {
9647       errmsg ("missing interface name or sw_if_index");
9648       return -99;
9649     }
9650
9651
9652   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
9653
9654   mp->sw_if_index = ntohl (sw_if_index);
9655   mp->table_index = ntohl (table_index);
9656   mp->is_ipv6 = is_ipv6;
9657
9658   S (mp);
9659   W (ret);
9660   return ret;
9661 }
9662
9663 static int
9664 api_classify_set_interface_l2_tables (vat_main_t * vam)
9665 {
9666   unformat_input_t *i = vam->input;
9667   vl_api_classify_set_interface_l2_tables_t *mp;
9668   u32 sw_if_index;
9669   int sw_if_index_set;
9670   u32 ip4_table_index = ~0;
9671   u32 ip6_table_index = ~0;
9672   u32 other_table_index = ~0;
9673   u32 is_input = 1;
9674   int ret;
9675
9676   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9677     {
9678       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9679         sw_if_index_set = 1;
9680       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9681         sw_if_index_set = 1;
9682       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9683         ;
9684       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9685         ;
9686       else if (unformat (i, "other-table %d", &other_table_index))
9687         ;
9688       else if (unformat (i, "is-input %d", &is_input))
9689         ;
9690       else
9691         {
9692           clib_warning ("parse error '%U'", format_unformat_error, i);
9693           return -99;
9694         }
9695     }
9696
9697   if (sw_if_index_set == 0)
9698     {
9699       errmsg ("missing interface name or sw_if_index");
9700       return -99;
9701     }
9702
9703
9704   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
9705
9706   mp->sw_if_index = ntohl (sw_if_index);
9707   mp->ip4_table_index = ntohl (ip4_table_index);
9708   mp->ip6_table_index = ntohl (ip6_table_index);
9709   mp->other_table_index = ntohl (other_table_index);
9710   mp->is_input = (u8) is_input;
9711
9712   S (mp);
9713   W (ret);
9714   return ret;
9715 }
9716
9717 static int
9718 api_set_ipfix_exporter (vat_main_t * vam)
9719 {
9720   unformat_input_t *i = vam->input;
9721   vl_api_set_ipfix_exporter_t *mp;
9722   ip4_address_t collector_address;
9723   u8 collector_address_set = 0;
9724   u32 collector_port = ~0;
9725   ip4_address_t src_address;
9726   u8 src_address_set = 0;
9727   u32 vrf_id = ~0;
9728   u32 path_mtu = ~0;
9729   u32 template_interval = ~0;
9730   u8 udp_checksum = 0;
9731   int ret;
9732
9733   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9734     {
9735       if (unformat (i, "collector_address %U", unformat_ip4_address,
9736                     &collector_address))
9737         collector_address_set = 1;
9738       else if (unformat (i, "collector_port %d", &collector_port))
9739         ;
9740       else if (unformat (i, "src_address %U", unformat_ip4_address,
9741                          &src_address))
9742         src_address_set = 1;
9743       else if (unformat (i, "vrf_id %d", &vrf_id))
9744         ;
9745       else if (unformat (i, "path_mtu %d", &path_mtu))
9746         ;
9747       else if (unformat (i, "template_interval %d", &template_interval))
9748         ;
9749       else if (unformat (i, "udp_checksum"))
9750         udp_checksum = 1;
9751       else
9752         break;
9753     }
9754
9755   if (collector_address_set == 0)
9756     {
9757       errmsg ("collector_address required");
9758       return -99;
9759     }
9760
9761   if (src_address_set == 0)
9762     {
9763       errmsg ("src_address required");
9764       return -99;
9765     }
9766
9767   M (SET_IPFIX_EXPORTER, mp);
9768
9769   memcpy (mp->collector_address, collector_address.data,
9770           sizeof (collector_address.data));
9771   mp->collector_port = htons ((u16) collector_port);
9772   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9773   mp->vrf_id = htonl (vrf_id);
9774   mp->path_mtu = htonl (path_mtu);
9775   mp->template_interval = htonl (template_interval);
9776   mp->udp_checksum = udp_checksum;
9777
9778   S (mp);
9779   W (ret);
9780   return ret;
9781 }
9782
9783 static int
9784 api_set_ipfix_classify_stream (vat_main_t * vam)
9785 {
9786   unformat_input_t *i = vam->input;
9787   vl_api_set_ipfix_classify_stream_t *mp;
9788   u32 domain_id = 0;
9789   u32 src_port = UDP_DST_PORT_ipfix;
9790   int ret;
9791
9792   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9793     {
9794       if (unformat (i, "domain %d", &domain_id))
9795         ;
9796       else if (unformat (i, "src_port %d", &src_port))
9797         ;
9798       else
9799         {
9800           errmsg ("unknown input `%U'", format_unformat_error, i);
9801           return -99;
9802         }
9803     }
9804
9805   M (SET_IPFIX_CLASSIFY_STREAM, mp);
9806
9807   mp->domain_id = htonl (domain_id);
9808   mp->src_port = htons ((u16) src_port);
9809
9810   S (mp);
9811   W (ret);
9812   return ret;
9813 }
9814
9815 static int
9816 api_ipfix_classify_table_add_del (vat_main_t * vam)
9817 {
9818   unformat_input_t *i = vam->input;
9819   vl_api_ipfix_classify_table_add_del_t *mp;
9820   int is_add = -1;
9821   u32 classify_table_index = ~0;
9822   u8 ip_version = 0;
9823   u8 transport_protocol = 255;
9824   int ret;
9825
9826   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9827     {
9828       if (unformat (i, "add"))
9829         is_add = 1;
9830       else if (unformat (i, "del"))
9831         is_add = 0;
9832       else if (unformat (i, "table %d", &classify_table_index))
9833         ;
9834       else if (unformat (i, "ip4"))
9835         ip_version = 4;
9836       else if (unformat (i, "ip6"))
9837         ip_version = 6;
9838       else if (unformat (i, "tcp"))
9839         transport_protocol = 6;
9840       else if (unformat (i, "udp"))
9841         transport_protocol = 17;
9842       else
9843         {
9844           errmsg ("unknown input `%U'", format_unformat_error, i);
9845           return -99;
9846         }
9847     }
9848
9849   if (is_add == -1)
9850     {
9851       errmsg ("expecting: add|del");
9852       return -99;
9853     }
9854   if (classify_table_index == ~0)
9855     {
9856       errmsg ("classifier table not specified");
9857       return -99;
9858     }
9859   if (ip_version == 0)
9860     {
9861       errmsg ("IP version not specified");
9862       return -99;
9863     }
9864
9865   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
9866
9867   mp->is_add = is_add;
9868   mp->table_id = htonl (classify_table_index);
9869   mp->ip_version = ip_version;
9870   mp->transport_protocol = transport_protocol;
9871
9872   S (mp);
9873   W (ret);
9874   return ret;
9875 }
9876
9877 static int
9878 api_get_node_index (vat_main_t * vam)
9879 {
9880   unformat_input_t *i = vam->input;
9881   vl_api_get_node_index_t *mp;
9882   u8 *name = 0;
9883   int ret;
9884
9885   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9886     {
9887       if (unformat (i, "node %s", &name))
9888         ;
9889       else
9890         break;
9891     }
9892   if (name == 0)
9893     {
9894       errmsg ("node name required");
9895       return -99;
9896     }
9897   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9898     {
9899       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9900       return -99;
9901     }
9902
9903   M (GET_NODE_INDEX, mp);
9904   clib_memcpy (mp->node_name, name, vec_len (name));
9905   vec_free (name);
9906
9907   S (mp);
9908   W (ret);
9909   return ret;
9910 }
9911
9912 static int
9913 api_get_next_index (vat_main_t * vam)
9914 {
9915   unformat_input_t *i = vam->input;
9916   vl_api_get_next_index_t *mp;
9917   u8 *node_name = 0, *next_node_name = 0;
9918   int ret;
9919
9920   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9921     {
9922       if (unformat (i, "node-name %s", &node_name))
9923         ;
9924       else if (unformat (i, "next-node-name %s", &next_node_name))
9925         break;
9926     }
9927
9928   if (node_name == 0)
9929     {
9930       errmsg ("node name required");
9931       return -99;
9932     }
9933   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9934     {
9935       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9936       return -99;
9937     }
9938
9939   if (next_node_name == 0)
9940     {
9941       errmsg ("next node name required");
9942       return -99;
9943     }
9944   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9945     {
9946       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
9947       return -99;
9948     }
9949
9950   M (GET_NEXT_INDEX, mp);
9951   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9952   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9953   vec_free (node_name);
9954   vec_free (next_node_name);
9955
9956   S (mp);
9957   W (ret);
9958   return ret;
9959 }
9960
9961 static int
9962 api_add_node_next (vat_main_t * vam)
9963 {
9964   unformat_input_t *i = vam->input;
9965   vl_api_add_node_next_t *mp;
9966   u8 *name = 0;
9967   u8 *next = 0;
9968   int ret;
9969
9970   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9971     {
9972       if (unformat (i, "node %s", &name))
9973         ;
9974       else if (unformat (i, "next %s", &next))
9975         ;
9976       else
9977         break;
9978     }
9979   if (name == 0)
9980     {
9981       errmsg ("node name required");
9982       return -99;
9983     }
9984   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9985     {
9986       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9987       return -99;
9988     }
9989   if (next == 0)
9990     {
9991       errmsg ("next node required");
9992       return -99;
9993     }
9994   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9995     {
9996       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
9997       return -99;
9998     }
9999
10000   M (ADD_NODE_NEXT, mp);
10001   clib_memcpy (mp->node_name, name, vec_len (name));
10002   clib_memcpy (mp->next_name, next, vec_len (next));
10003   vec_free (name);
10004   vec_free (next);
10005
10006   S (mp);
10007   W (ret);
10008   return ret;
10009 }
10010
10011 static int
10012 api_l2tpv3_create_tunnel (vat_main_t * vam)
10013 {
10014   unformat_input_t *i = vam->input;
10015   ip6_address_t client_address, our_address;
10016   int client_address_set = 0;
10017   int our_address_set = 0;
10018   u32 local_session_id = 0;
10019   u32 remote_session_id = 0;
10020   u64 local_cookie = 0;
10021   u64 remote_cookie = 0;
10022   u8 l2_sublayer_present = 0;
10023   vl_api_l2tpv3_create_tunnel_t *mp;
10024   int ret;
10025
10026   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10027     {
10028       if (unformat (i, "client_address %U", unformat_ip6_address,
10029                     &client_address))
10030         client_address_set = 1;
10031       else if (unformat (i, "our_address %U", unformat_ip6_address,
10032                          &our_address))
10033         our_address_set = 1;
10034       else if (unformat (i, "local_session_id %d", &local_session_id))
10035         ;
10036       else if (unformat (i, "remote_session_id %d", &remote_session_id))
10037         ;
10038       else if (unformat (i, "local_cookie %lld", &local_cookie))
10039         ;
10040       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10041         ;
10042       else if (unformat (i, "l2-sublayer-present"))
10043         l2_sublayer_present = 1;
10044       else
10045         break;
10046     }
10047
10048   if (client_address_set == 0)
10049     {
10050       errmsg ("client_address required");
10051       return -99;
10052     }
10053
10054   if (our_address_set == 0)
10055     {
10056       errmsg ("our_address required");
10057       return -99;
10058     }
10059
10060   M (L2TPV3_CREATE_TUNNEL, mp);
10061
10062   clib_memcpy (mp->client_address, client_address.as_u8,
10063                sizeof (mp->client_address));
10064
10065   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10066
10067   mp->local_session_id = ntohl (local_session_id);
10068   mp->remote_session_id = ntohl (remote_session_id);
10069   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10070   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10071   mp->l2_sublayer_present = l2_sublayer_present;
10072   mp->is_ipv6 = 1;
10073
10074   S (mp);
10075   W (ret);
10076   return ret;
10077 }
10078
10079 static int
10080 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10081 {
10082   unformat_input_t *i = vam->input;
10083   u32 sw_if_index;
10084   u8 sw_if_index_set = 0;
10085   u64 new_local_cookie = 0;
10086   u64 new_remote_cookie = 0;
10087   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10088   int ret;
10089
10090   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10091     {
10092       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10093         sw_if_index_set = 1;
10094       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10095         sw_if_index_set = 1;
10096       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10097         ;
10098       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10099         ;
10100       else
10101         break;
10102     }
10103
10104   if (sw_if_index_set == 0)
10105     {
10106       errmsg ("missing interface name or sw_if_index");
10107       return -99;
10108     }
10109
10110   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
10111
10112   mp->sw_if_index = ntohl (sw_if_index);
10113   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10114   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10115
10116   S (mp);
10117   W (ret);
10118   return ret;
10119 }
10120
10121 static int
10122 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10123 {
10124   unformat_input_t *i = vam->input;
10125   vl_api_l2tpv3_interface_enable_disable_t *mp;
10126   u32 sw_if_index;
10127   u8 sw_if_index_set = 0;
10128   u8 enable_disable = 1;
10129   int ret;
10130
10131   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10132     {
10133       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10134         sw_if_index_set = 1;
10135       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10136         sw_if_index_set = 1;
10137       else if (unformat (i, "enable"))
10138         enable_disable = 1;
10139       else if (unformat (i, "disable"))
10140         enable_disable = 0;
10141       else
10142         break;
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   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
10152
10153   mp->sw_if_index = ntohl (sw_if_index);
10154   mp->enable_disable = enable_disable;
10155
10156   S (mp);
10157   W (ret);
10158   return ret;
10159 }
10160
10161 static int
10162 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10163 {
10164   unformat_input_t *i = vam->input;
10165   vl_api_l2tpv3_set_lookup_key_t *mp;
10166   u8 key = ~0;
10167   int ret;
10168
10169   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10170     {
10171       if (unformat (i, "lookup_v6_src"))
10172         key = L2T_LOOKUP_SRC_ADDRESS;
10173       else if (unformat (i, "lookup_v6_dst"))
10174         key = L2T_LOOKUP_DST_ADDRESS;
10175       else if (unformat (i, "lookup_session_id"))
10176         key = L2T_LOOKUP_SESSION_ID;
10177       else
10178         break;
10179     }
10180
10181   if (key == (u8) ~ 0)
10182     {
10183       errmsg ("l2tp session lookup key unset");
10184       return -99;
10185     }
10186
10187   M (L2TPV3_SET_LOOKUP_KEY, mp);
10188
10189   mp->key = key;
10190
10191   S (mp);
10192   W (ret);
10193   return ret;
10194 }
10195
10196 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10197   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10198 {
10199   vat_main_t *vam = &vat_main;
10200
10201   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10202          format_ip6_address, mp->our_address,
10203          format_ip6_address, mp->client_address,
10204          clib_net_to_host_u32 (mp->sw_if_index));
10205
10206   print (vam->ofp,
10207          "   local cookies %016llx %016llx remote cookie %016llx",
10208          clib_net_to_host_u64 (mp->local_cookie[0]),
10209          clib_net_to_host_u64 (mp->local_cookie[1]),
10210          clib_net_to_host_u64 (mp->remote_cookie));
10211
10212   print (vam->ofp, "   local session-id %d remote session-id %d",
10213          clib_net_to_host_u32 (mp->local_session_id),
10214          clib_net_to_host_u32 (mp->remote_session_id));
10215
10216   print (vam->ofp, "   l2 specific sublayer %s\n",
10217          mp->l2_sublayer_present ? "preset" : "absent");
10218
10219 }
10220
10221 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10222   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10223 {
10224   vat_main_t *vam = &vat_main;
10225   vat_json_node_t *node = NULL;
10226   struct in6_addr addr;
10227
10228   if (VAT_JSON_ARRAY != vam->json_tree.type)
10229     {
10230       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10231       vat_json_init_array (&vam->json_tree);
10232     }
10233   node = vat_json_array_add (&vam->json_tree);
10234
10235   vat_json_init_object (node);
10236
10237   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10238   vat_json_object_add_ip6 (node, "our_address", addr);
10239   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10240   vat_json_object_add_ip6 (node, "client_address", addr);
10241
10242   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10243   vat_json_init_array (lc);
10244   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10245   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10246   vat_json_object_add_uint (node, "remote_cookie",
10247                             clib_net_to_host_u64 (mp->remote_cookie));
10248
10249   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10250   vat_json_object_add_uint (node, "local_session_id",
10251                             clib_net_to_host_u32 (mp->local_session_id));
10252   vat_json_object_add_uint (node, "remote_session_id",
10253                             clib_net_to_host_u32 (mp->remote_session_id));
10254   vat_json_object_add_string_copy (node, "l2_sublayer",
10255                                    mp->l2_sublayer_present ? (u8 *) "present"
10256                                    : (u8 *) "absent");
10257 }
10258
10259 static int
10260 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10261 {
10262   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10263   vl_api_control_ping_t *mp_ping;
10264   int ret;
10265
10266   /* Get list of l2tpv3-tunnel interfaces */
10267   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
10268   S (mp);
10269
10270   /* Use a control ping for synchronization */
10271   M (CONTROL_PING, mp_ping);
10272   S (mp_ping);
10273
10274   W (ret);
10275   return ret;
10276 }
10277
10278
10279 static void vl_api_sw_interface_tap_details_t_handler
10280   (vl_api_sw_interface_tap_details_t * mp)
10281 {
10282   vat_main_t *vam = &vat_main;
10283
10284   print (vam->ofp, "%-16s %d",
10285          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10286 }
10287
10288 static void vl_api_sw_interface_tap_details_t_handler_json
10289   (vl_api_sw_interface_tap_details_t * mp)
10290 {
10291   vat_main_t *vam = &vat_main;
10292   vat_json_node_t *node = NULL;
10293
10294   if (VAT_JSON_ARRAY != vam->json_tree.type)
10295     {
10296       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10297       vat_json_init_array (&vam->json_tree);
10298     }
10299   node = vat_json_array_add (&vam->json_tree);
10300
10301   vat_json_init_object (node);
10302   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10303   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10304 }
10305
10306 static int
10307 api_sw_interface_tap_dump (vat_main_t * vam)
10308 {
10309   vl_api_sw_interface_tap_dump_t *mp;
10310   vl_api_control_ping_t *mp_ping;
10311   int ret;
10312
10313   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10314   /* Get list of tap interfaces */
10315   M (SW_INTERFACE_TAP_DUMP, mp);
10316   S (mp);
10317
10318   /* Use a control ping for synchronization */
10319   M (CONTROL_PING, mp_ping);
10320   S (mp_ping);
10321
10322   W (ret);
10323   return ret;
10324 }
10325
10326 static uword unformat_vxlan_decap_next
10327   (unformat_input_t * input, va_list * args)
10328 {
10329   u32 *result = va_arg (*args, u32 *);
10330   u32 tmp;
10331
10332   if (unformat (input, "l2"))
10333     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10334   else if (unformat (input, "%d", &tmp))
10335     *result = tmp;
10336   else
10337     return 0;
10338   return 1;
10339 }
10340
10341 static int
10342 api_vxlan_add_del_tunnel (vat_main_t * vam)
10343 {
10344   unformat_input_t *line_input = vam->input;
10345   vl_api_vxlan_add_del_tunnel_t *mp;
10346   ip46_address_t src, dst;
10347   u8 is_add = 1;
10348   u8 ipv4_set = 0, ipv6_set = 0;
10349   u8 src_set = 0;
10350   u8 dst_set = 0;
10351   u8 grp_set = 0;
10352   u32 mcast_sw_if_index = ~0;
10353   u32 encap_vrf_id = 0;
10354   u32 decap_next_index = ~0;
10355   u32 vni = 0;
10356   int ret;
10357
10358   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10359   memset (&src, 0, sizeof src);
10360   memset (&dst, 0, sizeof dst);
10361
10362   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10363     {
10364       if (unformat (line_input, "del"))
10365         is_add = 0;
10366       else
10367         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10368         {
10369           ipv4_set = 1;
10370           src_set = 1;
10371         }
10372       else
10373         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10374         {
10375           ipv4_set = 1;
10376           dst_set = 1;
10377         }
10378       else
10379         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10380         {
10381           ipv6_set = 1;
10382           src_set = 1;
10383         }
10384       else
10385         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10386         {
10387           ipv6_set = 1;
10388           dst_set = 1;
10389         }
10390       else if (unformat (line_input, "group %U %U",
10391                          unformat_ip4_address, &dst.ip4,
10392                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10393         {
10394           grp_set = dst_set = 1;
10395           ipv4_set = 1;
10396         }
10397       else if (unformat (line_input, "group %U",
10398                          unformat_ip4_address, &dst.ip4))
10399         {
10400           grp_set = dst_set = 1;
10401           ipv4_set = 1;
10402         }
10403       else if (unformat (line_input, "group %U %U",
10404                          unformat_ip6_address, &dst.ip6,
10405                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10406         {
10407           grp_set = dst_set = 1;
10408           ipv6_set = 1;
10409         }
10410       else if (unformat (line_input, "group %U",
10411                          unformat_ip6_address, &dst.ip6))
10412         {
10413           grp_set = dst_set = 1;
10414           ipv6_set = 1;
10415         }
10416       else
10417         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10418         ;
10419       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10420         ;
10421       else if (unformat (line_input, "decap-next %U",
10422                          unformat_vxlan_decap_next, &decap_next_index))
10423         ;
10424       else if (unformat (line_input, "vni %d", &vni))
10425         ;
10426       else
10427         {
10428           errmsg ("parse error '%U'", format_unformat_error, line_input);
10429           return -99;
10430         }
10431     }
10432
10433   if (src_set == 0)
10434     {
10435       errmsg ("tunnel src address not specified");
10436       return -99;
10437     }
10438   if (dst_set == 0)
10439     {
10440       errmsg ("tunnel dst address not specified");
10441       return -99;
10442     }
10443
10444   if (grp_set && !ip46_address_is_multicast (&dst))
10445     {
10446       errmsg ("tunnel group address not multicast");
10447       return -99;
10448     }
10449   if (grp_set && mcast_sw_if_index == ~0)
10450     {
10451       errmsg ("tunnel nonexistent multicast device");
10452       return -99;
10453     }
10454   if (grp_set == 0 && ip46_address_is_multicast (&dst))
10455     {
10456       errmsg ("tunnel dst address must be unicast");
10457       return -99;
10458     }
10459
10460
10461   if (ipv4_set && ipv6_set)
10462     {
10463       errmsg ("both IPv4 and IPv6 addresses specified");
10464       return -99;
10465     }
10466
10467   if ((vni == 0) || (vni >> 24))
10468     {
10469       errmsg ("vni not specified or out of range");
10470       return -99;
10471     }
10472
10473   M (VXLAN_ADD_DEL_TUNNEL, mp);
10474
10475   if (ipv6_set)
10476     {
10477       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10478       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10479     }
10480   else
10481     {
10482       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10483       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10484     }
10485   mp->encap_vrf_id = ntohl (encap_vrf_id);
10486   mp->decap_next_index = ntohl (decap_next_index);
10487   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10488   mp->vni = ntohl (vni);
10489   mp->is_add = is_add;
10490   mp->is_ipv6 = ipv6_set;
10491
10492   S (mp);
10493   W (ret);
10494   return ret;
10495 }
10496
10497 static void vl_api_vxlan_tunnel_details_t_handler
10498   (vl_api_vxlan_tunnel_details_t * mp)
10499 {
10500   vat_main_t *vam = &vat_main;
10501   ip46_address_t src, dst;
10502
10503   ip46_from_addr_buf (mp->is_ipv6, mp->src_address, &src);
10504   ip46_from_addr_buf (mp->is_ipv6, mp->dst_address, &dst);
10505
10506   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
10507          ntohl (mp->sw_if_index),
10508          format_ip46_address, &src, IP46_TYPE_ANY,
10509          format_ip46_address, &dst, IP46_TYPE_ANY,
10510          ntohl (mp->encap_vrf_id),
10511          ntohl (mp->decap_next_index), ntohl (mp->vni),
10512          ntohl (mp->mcast_sw_if_index));
10513 }
10514
10515 static void vl_api_vxlan_tunnel_details_t_handler_json
10516   (vl_api_vxlan_tunnel_details_t * mp)
10517 {
10518   vat_main_t *vam = &vat_main;
10519   vat_json_node_t *node = NULL;
10520
10521   if (VAT_JSON_ARRAY != vam->json_tree.type)
10522     {
10523       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10524       vat_json_init_array (&vam->json_tree);
10525     }
10526   node = vat_json_array_add (&vam->json_tree);
10527
10528   vat_json_init_object (node);
10529   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10530   if (mp->is_ipv6)
10531     {
10532       struct in6_addr ip6;
10533
10534       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10535       vat_json_object_add_ip6 (node, "src_address", ip6);
10536       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10537       vat_json_object_add_ip6 (node, "dst_address", ip6);
10538     }
10539   else
10540     {
10541       struct in_addr ip4;
10542
10543       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10544       vat_json_object_add_ip4 (node, "src_address", ip4);
10545       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10546       vat_json_object_add_ip4 (node, "dst_address", ip4);
10547     }
10548   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10549   vat_json_object_add_uint (node, "decap_next_index",
10550                             ntohl (mp->decap_next_index));
10551   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10552   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10553   vat_json_object_add_uint (node, "mcast_sw_if_index",
10554                             ntohl (mp->mcast_sw_if_index));
10555 }
10556
10557 static int
10558 api_vxlan_tunnel_dump (vat_main_t * vam)
10559 {
10560   unformat_input_t *i = vam->input;
10561   vl_api_vxlan_tunnel_dump_t *mp;
10562   vl_api_control_ping_t *mp_ping;
10563   u32 sw_if_index;
10564   u8 sw_if_index_set = 0;
10565   int ret;
10566
10567   /* Parse args required to build the message */
10568   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10569     {
10570       if (unformat (i, "sw_if_index %d", &sw_if_index))
10571         sw_if_index_set = 1;
10572       else
10573         break;
10574     }
10575
10576   if (sw_if_index_set == 0)
10577     {
10578       sw_if_index = ~0;
10579     }
10580
10581   if (!vam->json_output)
10582     {
10583       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
10584              "sw_if_index", "src_address", "dst_address",
10585              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
10586     }
10587
10588   /* Get list of vxlan-tunnel interfaces */
10589   M (VXLAN_TUNNEL_DUMP, mp);
10590
10591   mp->sw_if_index = htonl (sw_if_index);
10592
10593   S (mp);
10594
10595   /* Use a control ping for synchronization */
10596   M (CONTROL_PING, mp_ping);
10597   S (mp_ping);
10598
10599   W (ret);
10600   return ret;
10601 }
10602
10603 static int
10604 api_gre_add_del_tunnel (vat_main_t * vam)
10605 {
10606   unformat_input_t *line_input = vam->input;
10607   vl_api_gre_add_del_tunnel_t *mp;
10608   ip4_address_t src4, dst4;
10609   u8 is_add = 1;
10610   u8 teb = 0;
10611   u8 src_set = 0;
10612   u8 dst_set = 0;
10613   u32 outer_fib_id = 0;
10614   int ret;
10615
10616   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10617     {
10618       if (unformat (line_input, "del"))
10619         is_add = 0;
10620       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10621         src_set = 1;
10622       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10623         dst_set = 1;
10624       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10625         ;
10626       else if (unformat (line_input, "teb"))
10627         teb = 1;
10628       else
10629         {
10630           errmsg ("parse error '%U'", format_unformat_error, line_input);
10631           return -99;
10632         }
10633     }
10634
10635   if (src_set == 0)
10636     {
10637       errmsg ("tunnel src address not specified");
10638       return -99;
10639     }
10640   if (dst_set == 0)
10641     {
10642       errmsg ("tunnel dst address not specified");
10643       return -99;
10644     }
10645
10646
10647   M (GRE_ADD_DEL_TUNNEL, mp);
10648
10649   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10650   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10651   mp->outer_fib_id = ntohl (outer_fib_id);
10652   mp->is_add = is_add;
10653   mp->teb = teb;
10654
10655   S (mp);
10656   W (ret);
10657   return ret;
10658 }
10659
10660 static void vl_api_gre_tunnel_details_t_handler
10661   (vl_api_gre_tunnel_details_t * mp)
10662 {
10663   vat_main_t *vam = &vat_main;
10664
10665   print (vam->ofp, "%11d%15U%15U%6d%14d",
10666          ntohl (mp->sw_if_index),
10667          format_ip4_address, &mp->src_address,
10668          format_ip4_address, &mp->dst_address,
10669          mp->teb, ntohl (mp->outer_fib_id));
10670 }
10671
10672 static void vl_api_gre_tunnel_details_t_handler_json
10673   (vl_api_gre_tunnel_details_t * mp)
10674 {
10675   vat_main_t *vam = &vat_main;
10676   vat_json_node_t *node = NULL;
10677   struct in_addr ip4;
10678
10679   if (VAT_JSON_ARRAY != vam->json_tree.type)
10680     {
10681       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10682       vat_json_init_array (&vam->json_tree);
10683     }
10684   node = vat_json_array_add (&vam->json_tree);
10685
10686   vat_json_init_object (node);
10687   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10688   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10689   vat_json_object_add_ip4 (node, "src_address", ip4);
10690   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10691   vat_json_object_add_ip4 (node, "dst_address", ip4);
10692   vat_json_object_add_uint (node, "teb", mp->teb);
10693   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10694 }
10695
10696 static int
10697 api_gre_tunnel_dump (vat_main_t * vam)
10698 {
10699   unformat_input_t *i = vam->input;
10700   vl_api_gre_tunnel_dump_t *mp;
10701   vl_api_control_ping_t *mp_ping;
10702   u32 sw_if_index;
10703   u8 sw_if_index_set = 0;
10704   int ret;
10705
10706   /* Parse args required to build the message */
10707   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10708     {
10709       if (unformat (i, "sw_if_index %d", &sw_if_index))
10710         sw_if_index_set = 1;
10711       else
10712         break;
10713     }
10714
10715   if (sw_if_index_set == 0)
10716     {
10717       sw_if_index = ~0;
10718     }
10719
10720   if (!vam->json_output)
10721     {
10722       print (vam->ofp, "%11s%15s%15s%6s%14s",
10723              "sw_if_index", "src_address", "dst_address", "teb",
10724              "outer_fib_id");
10725     }
10726
10727   /* Get list of gre-tunnel interfaces */
10728   M (GRE_TUNNEL_DUMP, mp);
10729
10730   mp->sw_if_index = htonl (sw_if_index);
10731
10732   S (mp);
10733
10734   /* Use a control ping for synchronization */
10735   M (CONTROL_PING, mp_ping);
10736   S (mp_ping);
10737
10738   W (ret);
10739   return ret;
10740 }
10741
10742 static int
10743 api_l2_fib_clear_table (vat_main_t * vam)
10744 {
10745 //  unformat_input_t * i = vam->input;
10746   vl_api_l2_fib_clear_table_t *mp;
10747   int ret;
10748
10749   M (L2_FIB_CLEAR_TABLE, mp);
10750
10751   S (mp);
10752   W (ret);
10753   return ret;
10754 }
10755
10756 static int
10757 api_l2_interface_efp_filter (vat_main_t * vam)
10758 {
10759   unformat_input_t *i = vam->input;
10760   vl_api_l2_interface_efp_filter_t *mp;
10761   u32 sw_if_index;
10762   u8 enable = 1;
10763   u8 sw_if_index_set = 0;
10764   int ret;
10765
10766   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10767     {
10768       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10769         sw_if_index_set = 1;
10770       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10771         sw_if_index_set = 1;
10772       else if (unformat (i, "enable"))
10773         enable = 1;
10774       else if (unformat (i, "disable"))
10775         enable = 0;
10776       else
10777         {
10778           clib_warning ("parse error '%U'", format_unformat_error, i);
10779           return -99;
10780         }
10781     }
10782
10783   if (sw_if_index_set == 0)
10784     {
10785       errmsg ("missing sw_if_index");
10786       return -99;
10787     }
10788
10789   M (L2_INTERFACE_EFP_FILTER, mp);
10790
10791   mp->sw_if_index = ntohl (sw_if_index);
10792   mp->enable_disable = enable;
10793
10794   S (mp);
10795   W (ret);
10796   return ret;
10797 }
10798
10799 #define foreach_vtr_op                          \
10800 _("disable",  L2_VTR_DISABLED)                  \
10801 _("push-1",  L2_VTR_PUSH_1)                     \
10802 _("push-2",  L2_VTR_PUSH_2)                     \
10803 _("pop-1",  L2_VTR_POP_1)                       \
10804 _("pop-2",  L2_VTR_POP_2)                       \
10805 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10806 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10807 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10808 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10809
10810 static int
10811 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10812 {
10813   unformat_input_t *i = vam->input;
10814   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10815   u32 sw_if_index;
10816   u8 sw_if_index_set = 0;
10817   u8 vtr_op_set = 0;
10818   u32 vtr_op = 0;
10819   u32 push_dot1q = 1;
10820   u32 tag1 = ~0;
10821   u32 tag2 = ~0;
10822   int ret;
10823
10824   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10825     {
10826       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10827         sw_if_index_set = 1;
10828       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10829         sw_if_index_set = 1;
10830       else if (unformat (i, "vtr_op %d", &vtr_op))
10831         vtr_op_set = 1;
10832 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
10833       foreach_vtr_op
10834 #undef _
10835         else if (unformat (i, "push_dot1q %d", &push_dot1q))
10836         ;
10837       else if (unformat (i, "tag1 %d", &tag1))
10838         ;
10839       else if (unformat (i, "tag2 %d", &tag2))
10840         ;
10841       else
10842         {
10843           clib_warning ("parse error '%U'", format_unformat_error, i);
10844           return -99;
10845         }
10846     }
10847
10848   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
10849     {
10850       errmsg ("missing vtr operation or sw_if_index");
10851       return -99;
10852     }
10853
10854   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
10855   mp->sw_if_index = ntohl (sw_if_index);
10856   mp->vtr_op = ntohl (vtr_op);
10857   mp->push_dot1q = ntohl (push_dot1q);
10858   mp->tag1 = ntohl (tag1);
10859   mp->tag2 = ntohl (tag2);
10860
10861   S (mp);
10862   W (ret);
10863   return ret;
10864 }
10865
10866 static int
10867 api_create_vhost_user_if (vat_main_t * vam)
10868 {
10869   unformat_input_t *i = vam->input;
10870   vl_api_create_vhost_user_if_t *mp;
10871   u8 *file_name;
10872   u8 is_server = 0;
10873   u8 file_name_set = 0;
10874   u32 custom_dev_instance = ~0;
10875   u8 hwaddr[6];
10876   u8 use_custom_mac = 0;
10877   u8 *tag = 0;
10878   int ret;
10879
10880   /* Shut up coverity */
10881   memset (hwaddr, 0, sizeof (hwaddr));
10882
10883   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10884     {
10885       if (unformat (i, "socket %s", &file_name))
10886         {
10887           file_name_set = 1;
10888         }
10889       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10890         ;
10891       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10892         use_custom_mac = 1;
10893       else if (unformat (i, "server"))
10894         is_server = 1;
10895       else if (unformat (i, "tag %s", &tag))
10896         ;
10897       else
10898         break;
10899     }
10900
10901   if (file_name_set == 0)
10902     {
10903       errmsg ("missing socket file name");
10904       return -99;
10905     }
10906
10907   if (vec_len (file_name) > 255)
10908     {
10909       errmsg ("socket file name too long");
10910       return -99;
10911     }
10912   vec_add1 (file_name, 0);
10913
10914   M (CREATE_VHOST_USER_IF, mp);
10915
10916   mp->is_server = is_server;
10917   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10918   vec_free (file_name);
10919   if (custom_dev_instance != ~0)
10920     {
10921       mp->renumber = 1;
10922       mp->custom_dev_instance = ntohl (custom_dev_instance);
10923     }
10924   mp->use_custom_mac = use_custom_mac;
10925   clib_memcpy (mp->mac_address, hwaddr, 6);
10926   if (tag)
10927     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
10928   vec_free (tag);
10929
10930   S (mp);
10931   W (ret);
10932   return ret;
10933 }
10934
10935 static int
10936 api_modify_vhost_user_if (vat_main_t * vam)
10937 {
10938   unformat_input_t *i = vam->input;
10939   vl_api_modify_vhost_user_if_t *mp;
10940   u8 *file_name;
10941   u8 is_server = 0;
10942   u8 file_name_set = 0;
10943   u32 custom_dev_instance = ~0;
10944   u8 sw_if_index_set = 0;
10945   u32 sw_if_index = (u32) ~ 0;
10946   int ret;
10947
10948   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10949     {
10950       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10951         sw_if_index_set = 1;
10952       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10953         sw_if_index_set = 1;
10954       else if (unformat (i, "socket %s", &file_name))
10955         {
10956           file_name_set = 1;
10957         }
10958       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10959         ;
10960       else if (unformat (i, "server"))
10961         is_server = 1;
10962       else
10963         break;
10964     }
10965
10966   if (sw_if_index_set == 0)
10967     {
10968       errmsg ("missing sw_if_index or interface name");
10969       return -99;
10970     }
10971
10972   if (file_name_set == 0)
10973     {
10974       errmsg ("missing socket file name");
10975       return -99;
10976     }
10977
10978   if (vec_len (file_name) > 255)
10979     {
10980       errmsg ("socket file name too long");
10981       return -99;
10982     }
10983   vec_add1 (file_name, 0);
10984
10985   M (MODIFY_VHOST_USER_IF, mp);
10986
10987   mp->sw_if_index = ntohl (sw_if_index);
10988   mp->is_server = is_server;
10989   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10990   vec_free (file_name);
10991   if (custom_dev_instance != ~0)
10992     {
10993       mp->renumber = 1;
10994       mp->custom_dev_instance = ntohl (custom_dev_instance);
10995     }
10996
10997   S (mp);
10998   W (ret);
10999   return ret;
11000 }
11001
11002 static int
11003 api_delete_vhost_user_if (vat_main_t * vam)
11004 {
11005   unformat_input_t *i = vam->input;
11006   vl_api_delete_vhost_user_if_t *mp;
11007   u32 sw_if_index = ~0;
11008   u8 sw_if_index_set = 0;
11009   int ret;
11010
11011   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11012     {
11013       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11014         sw_if_index_set = 1;
11015       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11016         sw_if_index_set = 1;
11017       else
11018         break;
11019     }
11020
11021   if (sw_if_index_set == 0)
11022     {
11023       errmsg ("missing sw_if_index or interface name");
11024       return -99;
11025     }
11026
11027
11028   M (DELETE_VHOST_USER_IF, mp);
11029
11030   mp->sw_if_index = ntohl (sw_if_index);
11031
11032   S (mp);
11033   W (ret);
11034   return ret;
11035 }
11036
11037 static void vl_api_sw_interface_vhost_user_details_t_handler
11038   (vl_api_sw_interface_vhost_user_details_t * mp)
11039 {
11040   vat_main_t *vam = &vat_main;
11041
11042   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
11043          (char *) mp->interface_name,
11044          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11045          clib_net_to_host_u64 (mp->features), mp->is_server,
11046          ntohl (mp->num_regions), (char *) mp->sock_filename);
11047   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
11048 }
11049
11050 static void vl_api_sw_interface_vhost_user_details_t_handler_json
11051   (vl_api_sw_interface_vhost_user_details_t * mp)
11052 {
11053   vat_main_t *vam = &vat_main;
11054   vat_json_node_t *node = NULL;
11055
11056   if (VAT_JSON_ARRAY != vam->json_tree.type)
11057     {
11058       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11059       vat_json_init_array (&vam->json_tree);
11060     }
11061   node = vat_json_array_add (&vam->json_tree);
11062
11063   vat_json_init_object (node);
11064   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11065   vat_json_object_add_string_copy (node, "interface_name",
11066                                    mp->interface_name);
11067   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11068                             ntohl (mp->virtio_net_hdr_sz));
11069   vat_json_object_add_uint (node, "features",
11070                             clib_net_to_host_u64 (mp->features));
11071   vat_json_object_add_uint (node, "is_server", mp->is_server);
11072   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11073   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11074   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11075 }
11076
11077 static int
11078 api_sw_interface_vhost_user_dump (vat_main_t * vam)
11079 {
11080   vl_api_sw_interface_vhost_user_dump_t *mp;
11081   vl_api_control_ping_t *mp_ping;
11082   int ret;
11083   print (vam->ofp,
11084          "Interface name           idx hdr_sz features server regions filename");
11085
11086   /* Get list of vhost-user interfaces */
11087   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
11088   S (mp);
11089
11090   /* Use a control ping for synchronization */
11091   M (CONTROL_PING, mp_ping);
11092   S (mp_ping);
11093
11094   W (ret);
11095   return ret;
11096 }
11097
11098 static int
11099 api_show_version (vat_main_t * vam)
11100 {
11101   vl_api_show_version_t *mp;
11102   int ret;
11103
11104   M (SHOW_VERSION, mp);
11105
11106   S (mp);
11107   W (ret);
11108   return ret;
11109 }
11110
11111
11112 static int
11113 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11114 {
11115   unformat_input_t *line_input = vam->input;
11116   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11117   ip4_address_t local4, remote4;
11118   ip6_address_t local6, remote6;
11119   u8 is_add = 1;
11120   u8 ipv4_set = 0, ipv6_set = 0;
11121   u8 local_set = 0;
11122   u8 remote_set = 0;
11123   u32 encap_vrf_id = 0;
11124   u32 decap_vrf_id = 0;
11125   u8 protocol = ~0;
11126   u32 vni;
11127   u8 vni_set = 0;
11128   int ret;
11129
11130   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11131     {
11132       if (unformat (line_input, "del"))
11133         is_add = 0;
11134       else if (unformat (line_input, "local %U",
11135                          unformat_ip4_address, &local4))
11136         {
11137           local_set = 1;
11138           ipv4_set = 1;
11139         }
11140       else if (unformat (line_input, "remote %U",
11141                          unformat_ip4_address, &remote4))
11142         {
11143           remote_set = 1;
11144           ipv4_set = 1;
11145         }
11146       else if (unformat (line_input, "local %U",
11147                          unformat_ip6_address, &local6))
11148         {
11149           local_set = 1;
11150           ipv6_set = 1;
11151         }
11152       else if (unformat (line_input, "remote %U",
11153                          unformat_ip6_address, &remote6))
11154         {
11155           remote_set = 1;
11156           ipv6_set = 1;
11157         }
11158       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11159         ;
11160       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11161         ;
11162       else if (unformat (line_input, "vni %d", &vni))
11163         vni_set = 1;
11164       else if (unformat (line_input, "next-ip4"))
11165         protocol = 1;
11166       else if (unformat (line_input, "next-ip6"))
11167         protocol = 2;
11168       else if (unformat (line_input, "next-ethernet"))
11169         protocol = 3;
11170       else if (unformat (line_input, "next-nsh"))
11171         protocol = 4;
11172       else
11173         {
11174           errmsg ("parse error '%U'", format_unformat_error, line_input);
11175           return -99;
11176         }
11177     }
11178
11179   if (local_set == 0)
11180     {
11181       errmsg ("tunnel local address not specified");
11182       return -99;
11183     }
11184   if (remote_set == 0)
11185     {
11186       errmsg ("tunnel remote address not specified");
11187       return -99;
11188     }
11189   if (ipv4_set && ipv6_set)
11190     {
11191       errmsg ("both IPv4 and IPv6 addresses specified");
11192       return -99;
11193     }
11194
11195   if (vni_set == 0)
11196     {
11197       errmsg ("vni not specified");
11198       return -99;
11199     }
11200
11201   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
11202
11203
11204   if (ipv6_set)
11205     {
11206       clib_memcpy (&mp->local, &local6, sizeof (local6));
11207       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11208     }
11209   else
11210     {
11211       clib_memcpy (&mp->local, &local4, sizeof (local4));
11212       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11213     }
11214
11215   mp->encap_vrf_id = ntohl (encap_vrf_id);
11216   mp->decap_vrf_id = ntohl (decap_vrf_id);
11217   mp->protocol = protocol;
11218   mp->vni = ntohl (vni);
11219   mp->is_add = is_add;
11220   mp->is_ipv6 = ipv6_set;
11221
11222   S (mp);
11223   W (ret);
11224   return ret;
11225 }
11226
11227 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11228   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11229 {
11230   vat_main_t *vam = &vat_main;
11231
11232   print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11233          ntohl (mp->sw_if_index),
11234          format_ip46_address, &(mp->local[0]),
11235          format_ip46_address, &(mp->remote[0]),
11236          ntohl (mp->vni),
11237          ntohl (mp->protocol),
11238          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11239 }
11240
11241 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11242   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11243 {
11244   vat_main_t *vam = &vat_main;
11245   vat_json_node_t *node = NULL;
11246   struct in_addr ip4;
11247   struct in6_addr ip6;
11248
11249   if (VAT_JSON_ARRAY != vam->json_tree.type)
11250     {
11251       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11252       vat_json_init_array (&vam->json_tree);
11253     }
11254   node = vat_json_array_add (&vam->json_tree);
11255
11256   vat_json_init_object (node);
11257   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11258   if (mp->is_ipv6)
11259     {
11260       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11261       vat_json_object_add_ip6 (node, "local", ip6);
11262       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11263       vat_json_object_add_ip6 (node, "remote", ip6);
11264     }
11265   else
11266     {
11267       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11268       vat_json_object_add_ip4 (node, "local", ip4);
11269       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11270       vat_json_object_add_ip4 (node, "remote", ip4);
11271     }
11272   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11273   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11274   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11275   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11276   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11277 }
11278
11279 static int
11280 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11281 {
11282   unformat_input_t *i = vam->input;
11283   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11284   vl_api_control_ping_t *mp_ping;
11285   u32 sw_if_index;
11286   u8 sw_if_index_set = 0;
11287   int ret;
11288
11289   /* Parse args required to build the message */
11290   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11291     {
11292       if (unformat (i, "sw_if_index %d", &sw_if_index))
11293         sw_if_index_set = 1;
11294       else
11295         break;
11296     }
11297
11298   if (sw_if_index_set == 0)
11299     {
11300       sw_if_index = ~0;
11301     }
11302
11303   if (!vam->json_output)
11304     {
11305       print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11306              "sw_if_index", "local", "remote", "vni",
11307              "protocol", "encap_vrf_id", "decap_vrf_id");
11308     }
11309
11310   /* Get list of vxlan-tunnel interfaces */
11311   M (VXLAN_GPE_TUNNEL_DUMP, mp);
11312
11313   mp->sw_if_index = htonl (sw_if_index);
11314
11315   S (mp);
11316
11317   /* Use a control ping for synchronization */
11318   M (CONTROL_PING, mp_ping);
11319   S (mp_ping);
11320
11321   W (ret);
11322   return ret;
11323 }
11324
11325 u8 *
11326 format_l2_fib_mac_address (u8 * s, va_list * args)
11327 {
11328   u8 *a = va_arg (*args, u8 *);
11329
11330   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11331                  a[2], a[3], a[4], a[5], a[6], a[7]);
11332 }
11333
11334 static void vl_api_l2_fib_table_entry_t_handler
11335   (vl_api_l2_fib_table_entry_t * mp)
11336 {
11337   vat_main_t *vam = &vat_main;
11338
11339   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11340          "       %d       %d     %d",
11341          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11342          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11343          mp->bvi_mac);
11344 }
11345
11346 static void vl_api_l2_fib_table_entry_t_handler_json
11347   (vl_api_l2_fib_table_entry_t * mp)
11348 {
11349   vat_main_t *vam = &vat_main;
11350   vat_json_node_t *node = NULL;
11351
11352   if (VAT_JSON_ARRAY != vam->json_tree.type)
11353     {
11354       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11355       vat_json_init_array (&vam->json_tree);
11356     }
11357   node = vat_json_array_add (&vam->json_tree);
11358
11359   vat_json_init_object (node);
11360   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11361   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11362   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11363   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11364   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11365   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11366 }
11367
11368 static int
11369 api_l2_fib_table_dump (vat_main_t * vam)
11370 {
11371   unformat_input_t *i = vam->input;
11372   vl_api_l2_fib_table_dump_t *mp;
11373   vl_api_control_ping_t *mp_ping;
11374   u32 bd_id;
11375   u8 bd_id_set = 0;
11376   int ret;
11377
11378   /* Parse args required to build the message */
11379   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11380     {
11381       if (unformat (i, "bd_id %d", &bd_id))
11382         bd_id_set = 1;
11383       else
11384         break;
11385     }
11386
11387   if (bd_id_set == 0)
11388     {
11389       errmsg ("missing bridge domain");
11390       return -99;
11391     }
11392
11393   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
11394
11395   /* Get list of l2 fib entries */
11396   M (L2_FIB_TABLE_DUMP, mp);
11397
11398   mp->bd_id = ntohl (bd_id);
11399   S (mp);
11400
11401   /* Use a control ping for synchronization */
11402   M (CONTROL_PING, mp_ping);
11403   S (mp_ping);
11404
11405   W (ret);
11406   return ret;
11407 }
11408
11409
11410 static int
11411 api_interface_name_renumber (vat_main_t * vam)
11412 {
11413   unformat_input_t *line_input = vam->input;
11414   vl_api_interface_name_renumber_t *mp;
11415   u32 sw_if_index = ~0;
11416   u32 new_show_dev_instance = ~0;
11417   int ret;
11418
11419   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11420     {
11421       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
11422                     &sw_if_index))
11423         ;
11424       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11425         ;
11426       else if (unformat (line_input, "new_show_dev_instance %d",
11427                          &new_show_dev_instance))
11428         ;
11429       else
11430         break;
11431     }
11432
11433   if (sw_if_index == ~0)
11434     {
11435       errmsg ("missing interface name or sw_if_index");
11436       return -99;
11437     }
11438
11439   if (new_show_dev_instance == ~0)
11440     {
11441       errmsg ("missing new_show_dev_instance");
11442       return -99;
11443     }
11444
11445   M (INTERFACE_NAME_RENUMBER, mp);
11446
11447   mp->sw_if_index = ntohl (sw_if_index);
11448   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11449
11450   S (mp);
11451   W (ret);
11452   return ret;
11453 }
11454
11455 static int
11456 api_want_ip4_arp_events (vat_main_t * vam)
11457 {
11458   unformat_input_t *line_input = vam->input;
11459   vl_api_want_ip4_arp_events_t *mp;
11460   ip4_address_t address;
11461   int address_set = 0;
11462   u32 enable_disable = 1;
11463   int ret;
11464
11465   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11466     {
11467       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11468         address_set = 1;
11469       else if (unformat (line_input, "del"))
11470         enable_disable = 0;
11471       else
11472         break;
11473     }
11474
11475   if (address_set == 0)
11476     {
11477       errmsg ("missing addresses");
11478       return -99;
11479     }
11480
11481   M (WANT_IP4_ARP_EVENTS, mp);
11482   mp->enable_disable = enable_disable;
11483   mp->pid = getpid ();
11484   mp->address = address.as_u32;
11485
11486   S (mp);
11487   W (ret);
11488   return ret;
11489 }
11490
11491 static int
11492 api_want_ip6_nd_events (vat_main_t * vam)
11493 {
11494   unformat_input_t *line_input = vam->input;
11495   vl_api_want_ip6_nd_events_t *mp;
11496   ip6_address_t address;
11497   int address_set = 0;
11498   u32 enable_disable = 1;
11499   int ret;
11500
11501   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11502     {
11503       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11504         address_set = 1;
11505       else if (unformat (line_input, "del"))
11506         enable_disable = 0;
11507       else
11508         break;
11509     }
11510
11511   if (address_set == 0)
11512     {
11513       errmsg ("missing addresses");
11514       return -99;
11515     }
11516
11517   M (WANT_IP6_ND_EVENTS, mp);
11518   mp->enable_disable = enable_disable;
11519   mp->pid = getpid ();
11520   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11521
11522   S (mp);
11523   W (ret);
11524   return ret;
11525 }
11526
11527 static int
11528 api_input_acl_set_interface (vat_main_t * vam)
11529 {
11530   unformat_input_t *i = vam->input;
11531   vl_api_input_acl_set_interface_t *mp;
11532   u32 sw_if_index;
11533   int sw_if_index_set;
11534   u32 ip4_table_index = ~0;
11535   u32 ip6_table_index = ~0;
11536   u32 l2_table_index = ~0;
11537   u8 is_add = 1;
11538   int ret;
11539
11540   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11541     {
11542       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11543         sw_if_index_set = 1;
11544       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11545         sw_if_index_set = 1;
11546       else if (unformat (i, "del"))
11547         is_add = 0;
11548       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11549         ;
11550       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11551         ;
11552       else if (unformat (i, "l2-table %d", &l2_table_index))
11553         ;
11554       else
11555         {
11556           clib_warning ("parse error '%U'", format_unformat_error, i);
11557           return -99;
11558         }
11559     }
11560
11561   if (sw_if_index_set == 0)
11562     {
11563       errmsg ("missing interface name or sw_if_index");
11564       return -99;
11565     }
11566
11567   M (INPUT_ACL_SET_INTERFACE, mp);
11568
11569   mp->sw_if_index = ntohl (sw_if_index);
11570   mp->ip4_table_index = ntohl (ip4_table_index);
11571   mp->ip6_table_index = ntohl (ip6_table_index);
11572   mp->l2_table_index = ntohl (l2_table_index);
11573   mp->is_add = is_add;
11574
11575   S (mp);
11576   W (ret);
11577   return ret;
11578 }
11579
11580 static int
11581 api_ip_address_dump (vat_main_t * vam)
11582 {
11583   unformat_input_t *i = vam->input;
11584   vl_api_ip_address_dump_t *mp;
11585   vl_api_control_ping_t *mp_ping;
11586   u32 sw_if_index = ~0;
11587   u8 sw_if_index_set = 0;
11588   u8 ipv4_set = 0;
11589   u8 ipv6_set = 0;
11590   int ret;
11591
11592   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11593     {
11594       if (unformat (i, "sw_if_index %d", &sw_if_index))
11595         sw_if_index_set = 1;
11596       else
11597         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11598         sw_if_index_set = 1;
11599       else if (unformat (i, "ipv4"))
11600         ipv4_set = 1;
11601       else if (unformat (i, "ipv6"))
11602         ipv6_set = 1;
11603       else
11604         break;
11605     }
11606
11607   if (ipv4_set && ipv6_set)
11608     {
11609       errmsg ("ipv4 and ipv6 flags cannot be both set");
11610       return -99;
11611     }
11612
11613   if ((!ipv4_set) && (!ipv6_set))
11614     {
11615       errmsg ("no ipv4 nor ipv6 flag set");
11616       return -99;
11617     }
11618
11619   if (sw_if_index_set == 0)
11620     {
11621       errmsg ("missing interface name or sw_if_index");
11622       return -99;
11623     }
11624
11625   vam->current_sw_if_index = sw_if_index;
11626   vam->is_ipv6 = ipv6_set;
11627
11628   M (IP_ADDRESS_DUMP, mp);
11629   mp->sw_if_index = ntohl (sw_if_index);
11630   mp->is_ipv6 = ipv6_set;
11631   S (mp);
11632
11633   /* Use a control ping for synchronization */
11634   M (CONTROL_PING, mp_ping);
11635   S (mp_ping);
11636
11637   W (ret);
11638   return ret;
11639 }
11640
11641 static int
11642 api_ip_dump (vat_main_t * vam)
11643 {
11644   vl_api_ip_dump_t *mp;
11645   vl_api_control_ping_t *mp_ping;
11646   unformat_input_t *in = vam->input;
11647   int ipv4_set = 0;
11648   int ipv6_set = 0;
11649   int is_ipv6;
11650   int i;
11651   int ret;
11652
11653   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11654     {
11655       if (unformat (in, "ipv4"))
11656         ipv4_set = 1;
11657       else if (unformat (in, "ipv6"))
11658         ipv6_set = 1;
11659       else
11660         break;
11661     }
11662
11663   if (ipv4_set && ipv6_set)
11664     {
11665       errmsg ("ipv4 and ipv6 flags cannot be both set");
11666       return -99;
11667     }
11668
11669   if ((!ipv4_set) && (!ipv6_set))
11670     {
11671       errmsg ("no ipv4 nor ipv6 flag set");
11672       return -99;
11673     }
11674
11675   is_ipv6 = ipv6_set;
11676   vam->is_ipv6 = is_ipv6;
11677
11678   /* free old data */
11679   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11680     {
11681       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11682     }
11683   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11684
11685   M (IP_DUMP, mp);
11686   mp->is_ipv6 = ipv6_set;
11687   S (mp);
11688
11689   /* Use a control ping for synchronization */
11690   M (CONTROL_PING, mp_ping);
11691   S (mp_ping);
11692
11693   W (ret);
11694   return ret;
11695 }
11696
11697 static int
11698 api_ipsec_spd_add_del (vat_main_t * vam)
11699 {
11700   unformat_input_t *i = vam->input;
11701   vl_api_ipsec_spd_add_del_t *mp;
11702   u32 spd_id = ~0;
11703   u8 is_add = 1;
11704   int ret;
11705
11706   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11707     {
11708       if (unformat (i, "spd_id %d", &spd_id))
11709         ;
11710       else if (unformat (i, "del"))
11711         is_add = 0;
11712       else
11713         {
11714           clib_warning ("parse error '%U'", format_unformat_error, i);
11715           return -99;
11716         }
11717     }
11718   if (spd_id == ~0)
11719     {
11720       errmsg ("spd_id must be set");
11721       return -99;
11722     }
11723
11724   M (IPSEC_SPD_ADD_DEL, mp);
11725
11726   mp->spd_id = ntohl (spd_id);
11727   mp->is_add = is_add;
11728
11729   S (mp);
11730   W (ret);
11731   return ret;
11732 }
11733
11734 static int
11735 api_ipsec_interface_add_del_spd (vat_main_t * vam)
11736 {
11737   unformat_input_t *i = vam->input;
11738   vl_api_ipsec_interface_add_del_spd_t *mp;
11739   u32 sw_if_index;
11740   u8 sw_if_index_set = 0;
11741   u32 spd_id = (u32) ~ 0;
11742   u8 is_add = 1;
11743   int ret;
11744
11745   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11746     {
11747       if (unformat (i, "del"))
11748         is_add = 0;
11749       else if (unformat (i, "spd_id %d", &spd_id))
11750         ;
11751       else
11752         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11753         sw_if_index_set = 1;
11754       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11755         sw_if_index_set = 1;
11756       else
11757         {
11758           clib_warning ("parse error '%U'", format_unformat_error, i);
11759           return -99;
11760         }
11761
11762     }
11763
11764   if (spd_id == (u32) ~ 0)
11765     {
11766       errmsg ("spd_id must be set");
11767       return -99;
11768     }
11769
11770   if (sw_if_index_set == 0)
11771     {
11772       errmsg ("missing interface name or sw_if_index");
11773       return -99;
11774     }
11775
11776   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
11777
11778   mp->spd_id = ntohl (spd_id);
11779   mp->sw_if_index = ntohl (sw_if_index);
11780   mp->is_add = is_add;
11781
11782   S (mp);
11783   W (ret);
11784   return ret;
11785 }
11786
11787 static int
11788 api_ipsec_spd_add_del_entry (vat_main_t * vam)
11789 {
11790   unformat_input_t *i = vam->input;
11791   vl_api_ipsec_spd_add_del_entry_t *mp;
11792   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11793   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11794   i32 priority = 0;
11795   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11796   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11797   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11798   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11799   int ret;
11800
11801   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11802   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11803   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11804   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11805   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11806   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11807
11808   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11809     {
11810       if (unformat (i, "del"))
11811         is_add = 0;
11812       if (unformat (i, "outbound"))
11813         is_outbound = 1;
11814       if (unformat (i, "inbound"))
11815         is_outbound = 0;
11816       else if (unformat (i, "spd_id %d", &spd_id))
11817         ;
11818       else if (unformat (i, "sa_id %d", &sa_id))
11819         ;
11820       else if (unformat (i, "priority %d", &priority))
11821         ;
11822       else if (unformat (i, "protocol %d", &protocol))
11823         ;
11824       else if (unformat (i, "lport_start %d", &lport_start))
11825         ;
11826       else if (unformat (i, "lport_stop %d", &lport_stop))
11827         ;
11828       else if (unformat (i, "rport_start %d", &rport_start))
11829         ;
11830       else if (unformat (i, "rport_stop %d", &rport_stop))
11831         ;
11832       else
11833         if (unformat
11834             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
11835         {
11836           is_ipv6 = 0;
11837           is_ip_any = 0;
11838         }
11839       else
11840         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
11841         {
11842           is_ipv6 = 0;
11843           is_ip_any = 0;
11844         }
11845       else
11846         if (unformat
11847             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
11848         {
11849           is_ipv6 = 0;
11850           is_ip_any = 0;
11851         }
11852       else
11853         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11854         {
11855           is_ipv6 = 0;
11856           is_ip_any = 0;
11857         }
11858       else
11859         if (unformat
11860             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11861         {
11862           is_ipv6 = 1;
11863           is_ip_any = 0;
11864         }
11865       else
11866         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11867         {
11868           is_ipv6 = 1;
11869           is_ip_any = 0;
11870         }
11871       else
11872         if (unformat
11873             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11874         {
11875           is_ipv6 = 1;
11876           is_ip_any = 0;
11877         }
11878       else
11879         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11880         {
11881           is_ipv6 = 1;
11882           is_ip_any = 0;
11883         }
11884       else
11885         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11886         {
11887           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11888             {
11889               clib_warning ("unsupported action: 'resolve'");
11890               return -99;
11891             }
11892         }
11893       else
11894         {
11895           clib_warning ("parse error '%U'", format_unformat_error, i);
11896           return -99;
11897         }
11898
11899     }
11900
11901   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
11902
11903   mp->spd_id = ntohl (spd_id);
11904   mp->priority = ntohl (priority);
11905   mp->is_outbound = is_outbound;
11906
11907   mp->is_ipv6 = is_ipv6;
11908   if (is_ipv6 || is_ip_any)
11909     {
11910       clib_memcpy (mp->remote_address_start, &raddr6_start,
11911                    sizeof (ip6_address_t));
11912       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
11913                    sizeof (ip6_address_t));
11914       clib_memcpy (mp->local_address_start, &laddr6_start,
11915                    sizeof (ip6_address_t));
11916       clib_memcpy (mp->local_address_stop, &laddr6_stop,
11917                    sizeof (ip6_address_t));
11918     }
11919   else
11920     {
11921       clib_memcpy (mp->remote_address_start, &raddr4_start,
11922                    sizeof (ip4_address_t));
11923       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
11924                    sizeof (ip4_address_t));
11925       clib_memcpy (mp->local_address_start, &laddr4_start,
11926                    sizeof (ip4_address_t));
11927       clib_memcpy (mp->local_address_stop, &laddr4_stop,
11928                    sizeof (ip4_address_t));
11929     }
11930   mp->protocol = (u8) protocol;
11931   mp->local_port_start = ntohs ((u16) lport_start);
11932   mp->local_port_stop = ntohs ((u16) lport_stop);
11933   mp->remote_port_start = ntohs ((u16) rport_start);
11934   mp->remote_port_stop = ntohs ((u16) rport_stop);
11935   mp->policy = (u8) policy;
11936   mp->sa_id = ntohl (sa_id);
11937   mp->is_add = is_add;
11938   mp->is_ip_any = is_ip_any;
11939   S (mp);
11940   W (ret);
11941   return ret;
11942 }
11943
11944 static int
11945 api_ipsec_sad_add_del_entry (vat_main_t * vam)
11946 {
11947   unformat_input_t *i = vam->input;
11948   vl_api_ipsec_sad_add_del_entry_t *mp;
11949   u32 sad_id = 0, spi = 0;
11950   u8 *ck = 0, *ik = 0;
11951   u8 is_add = 1;
11952
11953   u8 protocol = IPSEC_PROTOCOL_AH;
11954   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
11955   u32 crypto_alg = 0, integ_alg = 0;
11956   ip4_address_t tun_src4;
11957   ip4_address_t tun_dst4;
11958   ip6_address_t tun_src6;
11959   ip6_address_t tun_dst6;
11960   int ret;
11961
11962   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11963     {
11964       if (unformat (i, "del"))
11965         is_add = 0;
11966       else if (unformat (i, "sad_id %d", &sad_id))
11967         ;
11968       else if (unformat (i, "spi %d", &spi))
11969         ;
11970       else if (unformat (i, "esp"))
11971         protocol = IPSEC_PROTOCOL_ESP;
11972       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
11973         {
11974           is_tunnel = 1;
11975           is_tunnel_ipv6 = 0;
11976         }
11977       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
11978         {
11979           is_tunnel = 1;
11980           is_tunnel_ipv6 = 0;
11981         }
11982       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
11983         {
11984           is_tunnel = 1;
11985           is_tunnel_ipv6 = 1;
11986         }
11987       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
11988         {
11989           is_tunnel = 1;
11990           is_tunnel_ipv6 = 1;
11991         }
11992       else
11993         if (unformat
11994             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
11995         {
11996           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
11997               crypto_alg >= IPSEC_CRYPTO_N_ALG)
11998             {
11999               clib_warning ("unsupported crypto-alg: '%U'",
12000                             format_ipsec_crypto_alg, crypto_alg);
12001               return -99;
12002             }
12003         }
12004       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12005         ;
12006       else
12007         if (unformat
12008             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12009         {
12010           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12011               integ_alg >= IPSEC_INTEG_N_ALG)
12012             {
12013               clib_warning ("unsupported integ-alg: '%U'",
12014                             format_ipsec_integ_alg, integ_alg);
12015               return -99;
12016             }
12017         }
12018       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12019         ;
12020       else
12021         {
12022           clib_warning ("parse error '%U'", format_unformat_error, i);
12023           return -99;
12024         }
12025
12026     }
12027
12028   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
12029
12030   mp->sad_id = ntohl (sad_id);
12031   mp->is_add = is_add;
12032   mp->protocol = protocol;
12033   mp->spi = ntohl (spi);
12034   mp->is_tunnel = is_tunnel;
12035   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12036   mp->crypto_algorithm = crypto_alg;
12037   mp->integrity_algorithm = integ_alg;
12038   mp->crypto_key_length = vec_len (ck);
12039   mp->integrity_key_length = vec_len (ik);
12040
12041   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12042     mp->crypto_key_length = sizeof (mp->crypto_key);
12043
12044   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12045     mp->integrity_key_length = sizeof (mp->integrity_key);
12046
12047   if (ck)
12048     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12049   if (ik)
12050     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12051
12052   if (is_tunnel)
12053     {
12054       if (is_tunnel_ipv6)
12055         {
12056           clib_memcpy (mp->tunnel_src_address, &tun_src6,
12057                        sizeof (ip6_address_t));
12058           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12059                        sizeof (ip6_address_t));
12060         }
12061       else
12062         {
12063           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12064                        sizeof (ip4_address_t));
12065           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12066                        sizeof (ip4_address_t));
12067         }
12068     }
12069
12070   S (mp);
12071   W (ret);
12072   return ret;
12073 }
12074
12075 static int
12076 api_ipsec_sa_set_key (vat_main_t * vam)
12077 {
12078   unformat_input_t *i = vam->input;
12079   vl_api_ipsec_sa_set_key_t *mp;
12080   u32 sa_id;
12081   u8 *ck = 0, *ik = 0;
12082   int ret;
12083
12084   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12085     {
12086       if (unformat (i, "sa_id %d", &sa_id))
12087         ;
12088       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12089         ;
12090       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12091         ;
12092       else
12093         {
12094           clib_warning ("parse error '%U'", format_unformat_error, i);
12095           return -99;
12096         }
12097     }
12098
12099   M (IPSEC_SA_SET_KEY, mp);
12100
12101   mp->sa_id = ntohl (sa_id);
12102   mp->crypto_key_length = vec_len (ck);
12103   mp->integrity_key_length = vec_len (ik);
12104
12105   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12106     mp->crypto_key_length = sizeof (mp->crypto_key);
12107
12108   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12109     mp->integrity_key_length = sizeof (mp->integrity_key);
12110
12111   if (ck)
12112     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12113   if (ik)
12114     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12115
12116   S (mp);
12117   W (ret);
12118   return ret;
12119 }
12120
12121 static int
12122 api_ikev2_profile_add_del (vat_main_t * vam)
12123 {
12124   unformat_input_t *i = vam->input;
12125   vl_api_ikev2_profile_add_del_t *mp;
12126   u8 is_add = 1;
12127   u8 *name = 0;
12128   int ret;
12129
12130   const char *valid_chars = "a-zA-Z0-9_";
12131
12132   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12133     {
12134       if (unformat (i, "del"))
12135         is_add = 0;
12136       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12137         vec_add1 (name, 0);
12138       else
12139         {
12140           errmsg ("parse error '%U'", format_unformat_error, i);
12141           return -99;
12142         }
12143     }
12144
12145   if (!vec_len (name))
12146     {
12147       errmsg ("profile name must be specified");
12148       return -99;
12149     }
12150
12151   if (vec_len (name) > 64)
12152     {
12153       errmsg ("profile name too long");
12154       return -99;
12155     }
12156
12157   M (IKEV2_PROFILE_ADD_DEL, mp);
12158
12159   clib_memcpy (mp->name, name, vec_len (name));
12160   mp->is_add = is_add;
12161   vec_free (name);
12162
12163   S (mp);
12164   W (ret);
12165   return ret;
12166 }
12167
12168 static int
12169 api_ikev2_profile_set_auth (vat_main_t * vam)
12170 {
12171   unformat_input_t *i = vam->input;
12172   vl_api_ikev2_profile_set_auth_t *mp;
12173   u8 *name = 0;
12174   u8 *data = 0;
12175   u32 auth_method = 0;
12176   u8 is_hex = 0;
12177   int ret;
12178
12179   const char *valid_chars = "a-zA-Z0-9_";
12180
12181   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12182     {
12183       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12184         vec_add1 (name, 0);
12185       else if (unformat (i, "auth_method %U",
12186                          unformat_ikev2_auth_method, &auth_method))
12187         ;
12188       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12189         is_hex = 1;
12190       else if (unformat (i, "auth_data %v", &data))
12191         ;
12192       else
12193         {
12194           errmsg ("parse error '%U'", format_unformat_error, i);
12195           return -99;
12196         }
12197     }
12198
12199   if (!vec_len (name))
12200     {
12201       errmsg ("profile name must be specified");
12202       return -99;
12203     }
12204
12205   if (vec_len (name) > 64)
12206     {
12207       errmsg ("profile name too long");
12208       return -99;
12209     }
12210
12211   if (!vec_len (data))
12212     {
12213       errmsg ("auth_data must be specified");
12214       return -99;
12215     }
12216
12217   if (!auth_method)
12218     {
12219       errmsg ("auth_method must be specified");
12220       return -99;
12221     }
12222
12223   M (IKEV2_PROFILE_SET_AUTH, mp);
12224
12225   mp->is_hex = is_hex;
12226   mp->auth_method = (u8) auth_method;
12227   mp->data_len = vec_len (data);
12228   clib_memcpy (mp->name, name, vec_len (name));
12229   clib_memcpy (mp->data, data, vec_len (data));
12230   vec_free (name);
12231   vec_free (data);
12232
12233   S (mp);
12234   W (ret);
12235   return ret;
12236 }
12237
12238 static int
12239 api_ikev2_profile_set_id (vat_main_t * vam)
12240 {
12241   unformat_input_t *i = vam->input;
12242   vl_api_ikev2_profile_set_id_t *mp;
12243   u8 *name = 0;
12244   u8 *data = 0;
12245   u8 is_local = 0;
12246   u32 id_type = 0;
12247   ip4_address_t ip4;
12248   int ret;
12249
12250   const char *valid_chars = "a-zA-Z0-9_";
12251
12252   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12253     {
12254       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12255         vec_add1 (name, 0);
12256       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12257         ;
12258       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12259         {
12260           data = vec_new (u8, 4);
12261           clib_memcpy (data, ip4.as_u8, 4);
12262         }
12263       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12264         ;
12265       else if (unformat (i, "id_data %v", &data))
12266         ;
12267       else if (unformat (i, "local"))
12268         is_local = 1;
12269       else if (unformat (i, "remote"))
12270         is_local = 0;
12271       else
12272         {
12273           errmsg ("parse error '%U'", format_unformat_error, i);
12274           return -99;
12275         }
12276     }
12277
12278   if (!vec_len (name))
12279     {
12280       errmsg ("profile name must be specified");
12281       return -99;
12282     }
12283
12284   if (vec_len (name) > 64)
12285     {
12286       errmsg ("profile name too long");
12287       return -99;
12288     }
12289
12290   if (!vec_len (data))
12291     {
12292       errmsg ("id_data must be specified");
12293       return -99;
12294     }
12295
12296   if (!id_type)
12297     {
12298       errmsg ("id_type must be specified");
12299       return -99;
12300     }
12301
12302   M (IKEV2_PROFILE_SET_ID, mp);
12303
12304   mp->is_local = is_local;
12305   mp->id_type = (u8) id_type;
12306   mp->data_len = vec_len (data);
12307   clib_memcpy (mp->name, name, vec_len (name));
12308   clib_memcpy (mp->data, data, vec_len (data));
12309   vec_free (name);
12310   vec_free (data);
12311
12312   S (mp);
12313   W (ret);
12314   return ret;
12315 }
12316
12317 static int
12318 api_ikev2_profile_set_ts (vat_main_t * vam)
12319 {
12320   unformat_input_t *i = vam->input;
12321   vl_api_ikev2_profile_set_ts_t *mp;
12322   u8 *name = 0;
12323   u8 is_local = 0;
12324   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12325   ip4_address_t start_addr, end_addr;
12326
12327   const char *valid_chars = "a-zA-Z0-9_";
12328   int ret;
12329
12330   start_addr.as_u32 = 0;
12331   end_addr.as_u32 = (u32) ~ 0;
12332
12333   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12334     {
12335       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12336         vec_add1 (name, 0);
12337       else if (unformat (i, "protocol %d", &proto))
12338         ;
12339       else if (unformat (i, "start_port %d", &start_port))
12340         ;
12341       else if (unformat (i, "end_port %d", &end_port))
12342         ;
12343       else
12344         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12345         ;
12346       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12347         ;
12348       else if (unformat (i, "local"))
12349         is_local = 1;
12350       else if (unformat (i, "remote"))
12351         is_local = 0;
12352       else
12353         {
12354           errmsg ("parse error '%U'", format_unformat_error, i);
12355           return -99;
12356         }
12357     }
12358
12359   if (!vec_len (name))
12360     {
12361       errmsg ("profile name must be specified");
12362       return -99;
12363     }
12364
12365   if (vec_len (name) > 64)
12366     {
12367       errmsg ("profile name too long");
12368       return -99;
12369     }
12370
12371   M (IKEV2_PROFILE_SET_TS, mp);
12372
12373   mp->is_local = is_local;
12374   mp->proto = (u8) proto;
12375   mp->start_port = (u16) start_port;
12376   mp->end_port = (u16) end_port;
12377   mp->start_addr = start_addr.as_u32;
12378   mp->end_addr = end_addr.as_u32;
12379   clib_memcpy (mp->name, name, vec_len (name));
12380   vec_free (name);
12381
12382   S (mp);
12383   W (ret);
12384   return ret;
12385 }
12386
12387 static int
12388 api_ikev2_set_local_key (vat_main_t * vam)
12389 {
12390   unformat_input_t *i = vam->input;
12391   vl_api_ikev2_set_local_key_t *mp;
12392   u8 *file = 0;
12393   int ret;
12394
12395   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12396     {
12397       if (unformat (i, "file %v", &file))
12398         vec_add1 (file, 0);
12399       else
12400         {
12401           errmsg ("parse error '%U'", format_unformat_error, i);
12402           return -99;
12403         }
12404     }
12405
12406   if (!vec_len (file))
12407     {
12408       errmsg ("RSA key file must be specified");
12409       return -99;
12410     }
12411
12412   if (vec_len (file) > 256)
12413     {
12414       errmsg ("file name too long");
12415       return -99;
12416     }
12417
12418   M (IKEV2_SET_LOCAL_KEY, mp);
12419
12420   clib_memcpy (mp->key_file, file, vec_len (file));
12421   vec_free (file);
12422
12423   S (mp);
12424   W (ret);
12425   return ret;
12426 }
12427
12428 static int
12429 api_ikev2_set_responder (vat_main_t * vam)
12430 {
12431   unformat_input_t *i = vam->input;
12432   vl_api_ikev2_set_responder_t *mp;
12433   int ret;
12434   u8 *name = 0;
12435   u32 sw_if_index = ~0;
12436   ip4_address_t address;
12437
12438   const char *valid_chars = "a-zA-Z0-9_";
12439
12440   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12441     {
12442       if (unformat
12443           (i, "%U interface %d address %U", unformat_token, valid_chars,
12444            &name, &sw_if_index, unformat_ip4_address, &address))
12445         vec_add1 (name, 0);
12446       else
12447         {
12448           errmsg ("parse error '%U'", format_unformat_error, i);
12449           return -99;
12450         }
12451     }
12452
12453   if (!vec_len (name))
12454     {
12455       errmsg ("profile name must be specified");
12456       return -99;
12457     }
12458
12459   if (vec_len (name) > 64)
12460     {
12461       errmsg ("profile name too long");
12462       return -99;
12463     }
12464
12465   M (IKEV2_SET_RESPONDER, mp);
12466
12467   clib_memcpy (mp->name, name, vec_len (name));
12468   vec_free (name);
12469
12470   mp->sw_if_index = sw_if_index;
12471   clib_memcpy (mp->address, &address, sizeof (address));
12472
12473   S (mp);
12474   W (ret);
12475   return ret;
12476 }
12477
12478 static int
12479 api_ikev2_set_ike_transforms (vat_main_t * vam)
12480 {
12481   unformat_input_t *i = vam->input;
12482   vl_api_ikev2_set_ike_transforms_t *mp;
12483   int ret;
12484   u8 *name = 0;
12485   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
12486
12487   const char *valid_chars = "a-zA-Z0-9_";
12488
12489   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12490     {
12491       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
12492                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
12493         vec_add1 (name, 0);
12494       else
12495         {
12496           errmsg ("parse error '%U'", format_unformat_error, i);
12497           return -99;
12498         }
12499     }
12500
12501   if (!vec_len (name))
12502     {
12503       errmsg ("profile name must be specified");
12504       return -99;
12505     }
12506
12507   if (vec_len (name) > 64)
12508     {
12509       errmsg ("profile name too long");
12510       return -99;
12511     }
12512
12513   M (IKEV2_SET_IKE_TRANSFORMS, mp);
12514
12515   clib_memcpy (mp->name, name, vec_len (name));
12516   vec_free (name);
12517   mp->crypto_alg = crypto_alg;
12518   mp->crypto_key_size = crypto_key_size;
12519   mp->integ_alg = integ_alg;
12520   mp->dh_group = dh_group;
12521
12522   S (mp);
12523   W (ret);
12524   return ret;
12525 }
12526
12527
12528 static int
12529 api_ikev2_set_esp_transforms (vat_main_t * vam)
12530 {
12531   unformat_input_t *i = vam->input;
12532   vl_api_ikev2_set_esp_transforms_t *mp;
12533   int ret;
12534   u8 *name = 0;
12535   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
12536
12537   const char *valid_chars = "a-zA-Z0-9_";
12538
12539   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12540     {
12541       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
12542                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
12543         vec_add1 (name, 0);
12544       else
12545         {
12546           errmsg ("parse error '%U'", format_unformat_error, i);
12547           return -99;
12548         }
12549     }
12550
12551   if (!vec_len (name))
12552     {
12553       errmsg ("profile name must be specified");
12554       return -99;
12555     }
12556
12557   if (vec_len (name) > 64)
12558     {
12559       errmsg ("profile name too long");
12560       return -99;
12561     }
12562
12563   M (IKEV2_SET_ESP_TRANSFORMS, mp);
12564
12565   clib_memcpy (mp->name, name, vec_len (name));
12566   vec_free (name);
12567   mp->crypto_alg = crypto_alg;
12568   mp->crypto_key_size = crypto_key_size;
12569   mp->integ_alg = integ_alg;
12570   mp->dh_group = dh_group;
12571
12572   S (mp);
12573   W (ret);
12574   return ret;
12575 }
12576
12577 static int
12578 api_ikev2_set_sa_lifetime (vat_main_t * vam)
12579 {
12580   unformat_input_t *i = vam->input;
12581   vl_api_ikev2_set_sa_lifetime_t *mp;
12582   int ret;
12583   u8 *name = 0;
12584   u64 lifetime, lifetime_maxdata;
12585   u32 lifetime_jitter, handover;
12586
12587   const char *valid_chars = "a-zA-Z0-9_";
12588
12589   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12590     {
12591       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
12592                     &lifetime, &lifetime_jitter, &handover,
12593                     &lifetime_maxdata))
12594         vec_add1 (name, 0);
12595       else
12596         {
12597           errmsg ("parse error '%U'", format_unformat_error, i);
12598           return -99;
12599         }
12600     }
12601
12602   if (!vec_len (name))
12603     {
12604       errmsg ("profile name must be specified");
12605       return -99;
12606     }
12607
12608   if (vec_len (name) > 64)
12609     {
12610       errmsg ("profile name too long");
12611       return -99;
12612     }
12613
12614   M (IKEV2_SET_SA_LIFETIME, mp);
12615
12616   clib_memcpy (mp->name, name, vec_len (name));
12617   vec_free (name);
12618   mp->lifetime = lifetime;
12619   mp->lifetime_jitter = lifetime_jitter;
12620   mp->handover = handover;
12621   mp->lifetime_maxdata = lifetime_maxdata;
12622
12623   S (mp);
12624   W (ret);
12625   return ret;
12626 }
12627
12628 static int
12629 api_ikev2_initiate_sa_init (vat_main_t * vam)
12630 {
12631   unformat_input_t *i = vam->input;
12632   vl_api_ikev2_initiate_sa_init_t *mp;
12633   int ret;
12634   u8 *name = 0;
12635
12636   const char *valid_chars = "a-zA-Z0-9_";
12637
12638   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12639     {
12640       if (unformat (i, "%U", unformat_token, valid_chars, &name))
12641         vec_add1 (name, 0);
12642       else
12643         {
12644           errmsg ("parse error '%U'", format_unformat_error, i);
12645           return -99;
12646         }
12647     }
12648
12649   if (!vec_len (name))
12650     {
12651       errmsg ("profile name must be specified");
12652       return -99;
12653     }
12654
12655   if (vec_len (name) > 64)
12656     {
12657       errmsg ("profile name too long");
12658       return -99;
12659     }
12660
12661   M (IKEV2_INITIATE_SA_INIT, mp);
12662
12663   clib_memcpy (mp->name, name, vec_len (name));
12664   vec_free (name);
12665
12666   S (mp);
12667   W (ret);
12668   return ret;
12669 }
12670
12671 static int
12672 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
12673 {
12674   unformat_input_t *i = vam->input;
12675   vl_api_ikev2_initiate_del_ike_sa_t *mp;
12676   int ret;
12677   u64 ispi;
12678
12679
12680   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12681     {
12682       if (unformat (i, "%lx", &ispi))
12683         ;
12684       else
12685         {
12686           errmsg ("parse error '%U'", format_unformat_error, i);
12687           return -99;
12688         }
12689     }
12690
12691   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
12692
12693   mp->ispi = ispi;
12694
12695   S (mp);
12696   W (ret);
12697   return ret;
12698 }
12699
12700 static int
12701 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
12702 {
12703   unformat_input_t *i = vam->input;
12704   vl_api_ikev2_initiate_del_child_sa_t *mp;
12705   int ret;
12706   u32 ispi;
12707
12708
12709   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12710     {
12711       if (unformat (i, "%x", &ispi))
12712         ;
12713       else
12714         {
12715           errmsg ("parse error '%U'", format_unformat_error, i);
12716           return -99;
12717         }
12718     }
12719
12720   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
12721
12722   mp->ispi = ispi;
12723
12724   S (mp);
12725   W (ret);
12726   return ret;
12727 }
12728
12729 static int
12730 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
12731 {
12732   unformat_input_t *i = vam->input;
12733   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
12734   int ret;
12735   u32 ispi;
12736
12737
12738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12739     {
12740       if (unformat (i, "%x", &ispi))
12741         ;
12742       else
12743         {
12744           errmsg ("parse error '%U'", format_unformat_error, i);
12745           return -99;
12746         }
12747     }
12748
12749   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
12750
12751   mp->ispi = ispi;
12752
12753   S (mp);
12754   W (ret);
12755   return ret;
12756 }
12757
12758 /*
12759  * MAP
12760  */
12761 static int
12762 api_map_add_domain (vat_main_t * vam)
12763 {
12764   unformat_input_t *i = vam->input;
12765   vl_api_map_add_domain_t *mp;
12766
12767   ip4_address_t ip4_prefix;
12768   ip6_address_t ip6_prefix;
12769   ip6_address_t ip6_src;
12770   u32 num_m_args = 0;
12771   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12772     0, psid_length = 0;
12773   u8 is_translation = 0;
12774   u32 mtu = 0;
12775   u32 ip6_src_len = 128;
12776   int ret;
12777
12778   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12779     {
12780       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12781                     &ip4_prefix, &ip4_prefix_len))
12782         num_m_args++;
12783       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12784                          &ip6_prefix, &ip6_prefix_len))
12785         num_m_args++;
12786       else
12787         if (unformat
12788             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12789              &ip6_src_len))
12790         num_m_args++;
12791       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12792         num_m_args++;
12793       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12794         num_m_args++;
12795       else if (unformat (i, "psid-offset %d", &psid_offset))
12796         num_m_args++;
12797       else if (unformat (i, "psid-len %d", &psid_length))
12798         num_m_args++;
12799       else if (unformat (i, "mtu %d", &mtu))
12800         num_m_args++;
12801       else if (unformat (i, "map-t"))
12802         is_translation = 1;
12803       else
12804         {
12805           clib_warning ("parse error '%U'", format_unformat_error, i);
12806           return -99;
12807         }
12808     }
12809
12810   if (num_m_args < 3)
12811     {
12812       errmsg ("mandatory argument(s) missing");
12813       return -99;
12814     }
12815
12816   /* Construct the API message */
12817   M (MAP_ADD_DOMAIN, mp);
12818
12819   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12820   mp->ip4_prefix_len = ip4_prefix_len;
12821
12822   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12823   mp->ip6_prefix_len = ip6_prefix_len;
12824
12825   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12826   mp->ip6_src_prefix_len = ip6_src_len;
12827
12828   mp->ea_bits_len = ea_bits_len;
12829   mp->psid_offset = psid_offset;
12830   mp->psid_length = psid_length;
12831   mp->is_translation = is_translation;
12832   mp->mtu = htons (mtu);
12833
12834   /* send it... */
12835   S (mp);
12836
12837   /* Wait for a reply, return good/bad news  */
12838   W (ret);
12839   return ret;
12840 }
12841
12842 static int
12843 api_map_del_domain (vat_main_t * vam)
12844 {
12845   unformat_input_t *i = vam->input;
12846   vl_api_map_del_domain_t *mp;
12847
12848   u32 num_m_args = 0;
12849   u32 index;
12850   int ret;
12851
12852   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12853     {
12854       if (unformat (i, "index %d", &index))
12855         num_m_args++;
12856       else
12857         {
12858           clib_warning ("parse error '%U'", format_unformat_error, i);
12859           return -99;
12860         }
12861     }
12862
12863   if (num_m_args != 1)
12864     {
12865       errmsg ("mandatory argument(s) missing");
12866       return -99;
12867     }
12868
12869   /* Construct the API message */
12870   M (MAP_DEL_DOMAIN, mp);
12871
12872   mp->index = ntohl (index);
12873
12874   /* send it... */
12875   S (mp);
12876
12877   /* Wait for a reply, return good/bad news  */
12878   W (ret);
12879   return ret;
12880 }
12881
12882 static int
12883 api_map_add_del_rule (vat_main_t * vam)
12884 {
12885   unformat_input_t *i = vam->input;
12886   vl_api_map_add_del_rule_t *mp;
12887   u8 is_add = 1;
12888   ip6_address_t ip6_dst;
12889   u32 num_m_args = 0, index, psid = 0;
12890   int ret;
12891
12892   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12893     {
12894       if (unformat (i, "index %d", &index))
12895         num_m_args++;
12896       else if (unformat (i, "psid %d", &psid))
12897         num_m_args++;
12898       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12899         num_m_args++;
12900       else if (unformat (i, "del"))
12901         {
12902           is_add = 0;
12903         }
12904       else
12905         {
12906           clib_warning ("parse error '%U'", format_unformat_error, i);
12907           return -99;
12908         }
12909     }
12910
12911   /* Construct the API message */
12912   M (MAP_ADD_DEL_RULE, mp);
12913
12914   mp->index = ntohl (index);
12915   mp->is_add = is_add;
12916   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12917   mp->psid = ntohs (psid);
12918
12919   /* send it... */
12920   S (mp);
12921
12922   /* Wait for a reply, return good/bad news  */
12923   W (ret);
12924   return ret;
12925 }
12926
12927 static int
12928 api_map_domain_dump (vat_main_t * vam)
12929 {
12930   vl_api_map_domain_dump_t *mp;
12931   vl_api_control_ping_t *mp_ping;
12932   int ret;
12933
12934   /* Construct the API message */
12935   M (MAP_DOMAIN_DUMP, mp);
12936
12937   /* send it... */
12938   S (mp);
12939
12940   /* Use a control ping for synchronization */
12941   M (CONTROL_PING, mp_ping);
12942   S (mp_ping);
12943
12944   W (ret);
12945   return ret;
12946 }
12947
12948 static int
12949 api_map_rule_dump (vat_main_t * vam)
12950 {
12951   unformat_input_t *i = vam->input;
12952   vl_api_map_rule_dump_t *mp;
12953   vl_api_control_ping_t *mp_ping;
12954   u32 domain_index = ~0;
12955   int ret;
12956
12957   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12958     {
12959       if (unformat (i, "index %u", &domain_index))
12960         ;
12961       else
12962         break;
12963     }
12964
12965   if (domain_index == ~0)
12966     {
12967       clib_warning ("parse error: domain index expected");
12968       return -99;
12969     }
12970
12971   /* Construct the API message */
12972   M (MAP_RULE_DUMP, mp);
12973
12974   mp->domain_index = htonl (domain_index);
12975
12976   /* send it... */
12977   S (mp);
12978
12979   /* Use a control ping for synchronization */
12980   M (CONTROL_PING, mp_ping);
12981   S (mp_ping);
12982
12983   W (ret);
12984   return ret;
12985 }
12986
12987 static void vl_api_map_add_domain_reply_t_handler
12988   (vl_api_map_add_domain_reply_t * mp)
12989 {
12990   vat_main_t *vam = &vat_main;
12991   i32 retval = ntohl (mp->retval);
12992
12993   if (vam->async_mode)
12994     {
12995       vam->async_errors += (retval < 0);
12996     }
12997   else
12998     {
12999       vam->retval = retval;
13000       vam->result_ready = 1;
13001     }
13002 }
13003
13004 static void vl_api_map_add_domain_reply_t_handler_json
13005   (vl_api_map_add_domain_reply_t * mp)
13006 {
13007   vat_main_t *vam = &vat_main;
13008   vat_json_node_t node;
13009
13010   vat_json_init_object (&node);
13011   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
13012   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
13013
13014   vat_json_print (vam->ofp, &node);
13015   vat_json_free (&node);
13016
13017   vam->retval = ntohl (mp->retval);
13018   vam->result_ready = 1;
13019 }
13020
13021 static int
13022 api_get_first_msg_id (vat_main_t * vam)
13023 {
13024   vl_api_get_first_msg_id_t *mp;
13025   unformat_input_t *i = vam->input;
13026   u8 *name;
13027   u8 name_set = 0;
13028   int ret;
13029
13030   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13031     {
13032       if (unformat (i, "client %s", &name))
13033         name_set = 1;
13034       else
13035         break;
13036     }
13037
13038   if (name_set == 0)
13039     {
13040       errmsg ("missing client name");
13041       return -99;
13042     }
13043   vec_add1 (name, 0);
13044
13045   if (vec_len (name) > 63)
13046     {
13047       errmsg ("client name too long");
13048       return -99;
13049     }
13050
13051   M (GET_FIRST_MSG_ID, mp);
13052   clib_memcpy (mp->name, name, vec_len (name));
13053   S (mp);
13054   W (ret);
13055   return ret;
13056 }
13057
13058 static int
13059 api_cop_interface_enable_disable (vat_main_t * vam)
13060 {
13061   unformat_input_t *line_input = vam->input;
13062   vl_api_cop_interface_enable_disable_t *mp;
13063   u32 sw_if_index = ~0;
13064   u8 enable_disable = 1;
13065   int ret;
13066
13067   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13068     {
13069       if (unformat (line_input, "disable"))
13070         enable_disable = 0;
13071       if (unformat (line_input, "enable"))
13072         enable_disable = 1;
13073       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13074                          vam, &sw_if_index))
13075         ;
13076       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13077         ;
13078       else
13079         break;
13080     }
13081
13082   if (sw_if_index == ~0)
13083     {
13084       errmsg ("missing interface name or sw_if_index");
13085       return -99;
13086     }
13087
13088   /* Construct the API message */
13089   M (COP_INTERFACE_ENABLE_DISABLE, mp);
13090   mp->sw_if_index = ntohl (sw_if_index);
13091   mp->enable_disable = enable_disable;
13092
13093   /* send it... */
13094   S (mp);
13095   /* Wait for the reply */
13096   W (ret);
13097   return ret;
13098 }
13099
13100 static int
13101 api_cop_whitelist_enable_disable (vat_main_t * vam)
13102 {
13103   unformat_input_t *line_input = vam->input;
13104   vl_api_cop_whitelist_enable_disable_t *mp;
13105   u32 sw_if_index = ~0;
13106   u8 ip4 = 0, ip6 = 0, default_cop = 0;
13107   u32 fib_id = 0;
13108   int ret;
13109
13110   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13111     {
13112       if (unformat (line_input, "ip4"))
13113         ip4 = 1;
13114       else if (unformat (line_input, "ip6"))
13115         ip6 = 1;
13116       else if (unformat (line_input, "default"))
13117         default_cop = 1;
13118       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13119                          vam, &sw_if_index))
13120         ;
13121       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13122         ;
13123       else if (unformat (line_input, "fib-id %d", &fib_id))
13124         ;
13125       else
13126         break;
13127     }
13128
13129   if (sw_if_index == ~0)
13130     {
13131       errmsg ("missing interface name or sw_if_index");
13132       return -99;
13133     }
13134
13135   /* Construct the API message */
13136   M (COP_WHITELIST_ENABLE_DISABLE, mp);
13137   mp->sw_if_index = ntohl (sw_if_index);
13138   mp->fib_id = ntohl (fib_id);
13139   mp->ip4 = ip4;
13140   mp->ip6 = ip6;
13141   mp->default_cop = default_cop;
13142
13143   /* send it... */
13144   S (mp);
13145   /* Wait for the reply */
13146   W (ret);
13147   return ret;
13148 }
13149
13150 static int
13151 api_get_node_graph (vat_main_t * vam)
13152 {
13153   vl_api_get_node_graph_t *mp;
13154   int ret;
13155
13156   M (GET_NODE_GRAPH, mp);
13157
13158   /* send it... */
13159   S (mp);
13160   /* Wait for the reply */
13161   W (ret);
13162   return ret;
13163 }
13164
13165 /* *INDENT-OFF* */
13166 /** Used for parsing LISP eids */
13167 typedef CLIB_PACKED(struct{
13168   u8 addr[16];   /**< eid address */
13169   u32 len;       /**< prefix length if IP */
13170   u8 type;      /**< type of eid */
13171 }) lisp_eid_vat_t;
13172 /* *INDENT-ON* */
13173
13174 static uword
13175 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
13176 {
13177   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
13178
13179   memset (a, 0, sizeof (a[0]));
13180
13181   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
13182     {
13183       a->type = 0;              /* ipv4 type */
13184     }
13185   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
13186     {
13187       a->type = 1;              /* ipv6 type */
13188     }
13189   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
13190     {
13191       a->type = 2;              /* mac type */
13192     }
13193   else
13194     {
13195       return 0;
13196     }
13197
13198   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
13199     {
13200       return 0;
13201     }
13202
13203   return 1;
13204 }
13205
13206 static int
13207 lisp_eid_size_vat (u8 type)
13208 {
13209   switch (type)
13210     {
13211     case 0:
13212       return 4;
13213     case 1:
13214       return 16;
13215     case 2:
13216       return 6;
13217     }
13218   return 0;
13219 }
13220
13221 static void
13222 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
13223 {
13224   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
13225 }
13226
13227 static int
13228 api_one_add_del_locator_set (vat_main_t * vam)
13229 {
13230   unformat_input_t *input = vam->input;
13231   vl_api_one_add_del_locator_set_t *mp;
13232   u8 is_add = 1;
13233   u8 *locator_set_name = NULL;
13234   u8 locator_set_name_set = 0;
13235   vl_api_local_locator_t locator, *locators = 0;
13236   u32 sw_if_index, priority, weight;
13237   u32 data_len = 0;
13238
13239   int ret;
13240   /* Parse args required to build the message */
13241   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13242     {
13243       if (unformat (input, "del"))
13244         {
13245           is_add = 0;
13246         }
13247       else if (unformat (input, "locator-set %s", &locator_set_name))
13248         {
13249           locator_set_name_set = 1;
13250         }
13251       else if (unformat (input, "sw_if_index %u p %u w %u",
13252                          &sw_if_index, &priority, &weight))
13253         {
13254           locator.sw_if_index = htonl (sw_if_index);
13255           locator.priority = priority;
13256           locator.weight = weight;
13257           vec_add1 (locators, locator);
13258         }
13259       else
13260         if (unformat
13261             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
13262              &sw_if_index, &priority, &weight))
13263         {
13264           locator.sw_if_index = htonl (sw_if_index);
13265           locator.priority = priority;
13266           locator.weight = weight;
13267           vec_add1 (locators, locator);
13268         }
13269       else
13270         break;
13271     }
13272
13273   if (locator_set_name_set == 0)
13274     {
13275       errmsg ("missing locator-set name");
13276       vec_free (locators);
13277       return -99;
13278     }
13279
13280   if (vec_len (locator_set_name) > 64)
13281     {
13282       errmsg ("locator-set name too long");
13283       vec_free (locator_set_name);
13284       vec_free (locators);
13285       return -99;
13286     }
13287   vec_add1 (locator_set_name, 0);
13288
13289   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
13290
13291   /* Construct the API message */
13292   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
13293
13294   mp->is_add = is_add;
13295   clib_memcpy (mp->locator_set_name, locator_set_name,
13296                vec_len (locator_set_name));
13297   vec_free (locator_set_name);
13298
13299   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
13300   if (locators)
13301     clib_memcpy (mp->locators, locators, data_len);
13302   vec_free (locators);
13303
13304   /* send it... */
13305   S (mp);
13306
13307   /* Wait for a reply... */
13308   W (ret);
13309   return ret;
13310 }
13311
13312 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
13313
13314 static int
13315 api_one_add_del_locator (vat_main_t * vam)
13316 {
13317   unformat_input_t *input = vam->input;
13318   vl_api_one_add_del_locator_t *mp;
13319   u32 tmp_if_index = ~0;
13320   u32 sw_if_index = ~0;
13321   u8 sw_if_index_set = 0;
13322   u8 sw_if_index_if_name_set = 0;
13323   u32 priority = ~0;
13324   u8 priority_set = 0;
13325   u32 weight = ~0;
13326   u8 weight_set = 0;
13327   u8 is_add = 1;
13328   u8 *locator_set_name = NULL;
13329   u8 locator_set_name_set = 0;
13330   int ret;
13331
13332   /* Parse args required to build the message */
13333   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13334     {
13335       if (unformat (input, "del"))
13336         {
13337           is_add = 0;
13338         }
13339       else if (unformat (input, "locator-set %s", &locator_set_name))
13340         {
13341           locator_set_name_set = 1;
13342         }
13343       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
13344                          &tmp_if_index))
13345         {
13346           sw_if_index_if_name_set = 1;
13347           sw_if_index = tmp_if_index;
13348         }
13349       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
13350         {
13351           sw_if_index_set = 1;
13352           sw_if_index = tmp_if_index;
13353         }
13354       else if (unformat (input, "p %d", &priority))
13355         {
13356           priority_set = 1;
13357         }
13358       else if (unformat (input, "w %d", &weight))
13359         {
13360           weight_set = 1;
13361         }
13362       else
13363         break;
13364     }
13365
13366   if (locator_set_name_set == 0)
13367     {
13368       errmsg ("missing locator-set name");
13369       return -99;
13370     }
13371
13372   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
13373     {
13374       errmsg ("missing sw_if_index");
13375       vec_free (locator_set_name);
13376       return -99;
13377     }
13378
13379   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
13380     {
13381       errmsg ("cannot use both params interface name and sw_if_index");
13382       vec_free (locator_set_name);
13383       return -99;
13384     }
13385
13386   if (priority_set == 0)
13387     {
13388       errmsg ("missing locator-set priority");
13389       vec_free (locator_set_name);
13390       return -99;
13391     }
13392
13393   if (weight_set == 0)
13394     {
13395       errmsg ("missing locator-set weight");
13396       vec_free (locator_set_name);
13397       return -99;
13398     }
13399
13400   if (vec_len (locator_set_name) > 64)
13401     {
13402       errmsg ("locator-set name too long");
13403       vec_free (locator_set_name);
13404       return -99;
13405     }
13406   vec_add1 (locator_set_name, 0);
13407
13408   /* Construct the API message */
13409   M (ONE_ADD_DEL_LOCATOR, mp);
13410
13411   mp->is_add = is_add;
13412   mp->sw_if_index = ntohl (sw_if_index);
13413   mp->priority = priority;
13414   mp->weight = weight;
13415   clib_memcpy (mp->locator_set_name, locator_set_name,
13416                vec_len (locator_set_name));
13417   vec_free (locator_set_name);
13418
13419   /* send it... */
13420   S (mp);
13421
13422   /* Wait for a reply... */
13423   W (ret);
13424   return ret;
13425 }
13426
13427 #define api_lisp_add_del_locator api_one_add_del_locator
13428
13429 uword
13430 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
13431 {
13432   u32 *key_id = va_arg (*args, u32 *);
13433   u8 *s = 0;
13434
13435   if (unformat (input, "%s", &s))
13436     {
13437       if (!strcmp ((char *) s, "sha1"))
13438         key_id[0] = HMAC_SHA_1_96;
13439       else if (!strcmp ((char *) s, "sha256"))
13440         key_id[0] = HMAC_SHA_256_128;
13441       else
13442         {
13443           clib_warning ("invalid key_id: '%s'", s);
13444           key_id[0] = HMAC_NO_KEY;
13445         }
13446     }
13447   else
13448     return 0;
13449
13450   vec_free (s);
13451   return 1;
13452 }
13453
13454 static int
13455 api_one_add_del_local_eid (vat_main_t * vam)
13456 {
13457   unformat_input_t *input = vam->input;
13458   vl_api_one_add_del_local_eid_t *mp;
13459   u8 is_add = 1;
13460   u8 eid_set = 0;
13461   lisp_eid_vat_t _eid, *eid = &_eid;
13462   u8 *locator_set_name = 0;
13463   u8 locator_set_name_set = 0;
13464   u32 vni = 0;
13465   u16 key_id = 0;
13466   u8 *key = 0;
13467   int ret;
13468
13469   /* Parse args required to build the message */
13470   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13471     {
13472       if (unformat (input, "del"))
13473         {
13474           is_add = 0;
13475         }
13476       else if (unformat (input, "vni %d", &vni))
13477         {
13478           ;
13479         }
13480       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13481         {
13482           eid_set = 1;
13483         }
13484       else if (unformat (input, "locator-set %s", &locator_set_name))
13485         {
13486           locator_set_name_set = 1;
13487         }
13488       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
13489         ;
13490       else if (unformat (input, "secret-key %_%v%_", &key))
13491         ;
13492       else
13493         break;
13494     }
13495
13496   if (locator_set_name_set == 0)
13497     {
13498       errmsg ("missing locator-set name");
13499       return -99;
13500     }
13501
13502   if (0 == eid_set)
13503     {
13504       errmsg ("EID address not set!");
13505       vec_free (locator_set_name);
13506       return -99;
13507     }
13508
13509   if (key && (0 == key_id))
13510     {
13511       errmsg ("invalid key_id!");
13512       return -99;
13513     }
13514
13515   if (vec_len (key) > 64)
13516     {
13517       errmsg ("key too long");
13518       vec_free (key);
13519       return -99;
13520     }
13521
13522   if (vec_len (locator_set_name) > 64)
13523     {
13524       errmsg ("locator-set name too long");
13525       vec_free (locator_set_name);
13526       return -99;
13527     }
13528   vec_add1 (locator_set_name, 0);
13529
13530   /* Construct the API message */
13531   M (ONE_ADD_DEL_LOCAL_EID, mp);
13532
13533   mp->is_add = is_add;
13534   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13535   mp->eid_type = eid->type;
13536   mp->prefix_len = eid->len;
13537   mp->vni = clib_host_to_net_u32 (vni);
13538   mp->key_id = clib_host_to_net_u16 (key_id);
13539   clib_memcpy (mp->locator_set_name, locator_set_name,
13540                vec_len (locator_set_name));
13541   clib_memcpy (mp->key, key, vec_len (key));
13542
13543   vec_free (locator_set_name);
13544   vec_free (key);
13545
13546   /* send it... */
13547   S (mp);
13548
13549   /* Wait for a reply... */
13550   W (ret);
13551   return ret;
13552 }
13553
13554 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
13555
13556 static int
13557 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
13558 {
13559   u32 dp_table = 0, vni = 0;;
13560   unformat_input_t *input = vam->input;
13561   vl_api_gpe_add_del_fwd_entry_t *mp;
13562   u8 is_add = 1;
13563   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
13564   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
13565   u8 rmt_eid_set = 0, lcl_eid_set = 0;
13566   u32 action = ~0, w;
13567   ip4_address_t rmt_rloc4, lcl_rloc4;
13568   ip6_address_t rmt_rloc6, lcl_rloc6;
13569   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
13570   int ret;
13571
13572   memset (&rloc, 0, sizeof (rloc));
13573
13574   /* Parse args required to build the message */
13575   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13576     {
13577       if (unformat (input, "del"))
13578         is_add = 0;
13579       else if (unformat (input, "add"))
13580         is_add = 1;
13581       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
13582         {
13583           rmt_eid_set = 1;
13584         }
13585       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
13586         {
13587           lcl_eid_set = 1;
13588         }
13589       else if (unformat (input, "vrf %d", &dp_table))
13590         ;
13591       else if (unformat (input, "bd %d", &dp_table))
13592         ;
13593       else if (unformat (input, "vni %d", &vni))
13594         ;
13595       else if (unformat (input, "w %d", &w))
13596         {
13597           if (!curr_rloc)
13598             {
13599               errmsg ("No RLOC configured for setting priority/weight!");
13600               return -99;
13601             }
13602           curr_rloc->weight = w;
13603         }
13604       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
13605                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
13606         {
13607           rloc.is_ip4 = 1;
13608
13609           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
13610           rloc.weight = 0;
13611           vec_add1 (lcl_locs, rloc);
13612
13613           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
13614           vec_add1 (rmt_locs, rloc);
13615           /* weight saved in rmt loc */
13616           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13617         }
13618       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
13619                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
13620         {
13621           rloc.is_ip4 = 0;
13622           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
13623           rloc.weight = 0;
13624           vec_add1 (lcl_locs, rloc);
13625
13626           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13627           vec_add1 (rmt_locs, rloc);
13628           /* weight saved in rmt loc */
13629           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13630         }
13631       else if (unformat (input, "action %d", &action))
13632         {
13633           ;
13634         }
13635       else
13636         {
13637           clib_warning ("parse error '%U'", format_unformat_error, input);
13638           return -99;
13639         }
13640     }
13641
13642   if (!rmt_eid_set)
13643     {
13644       errmsg ("remote eid addresses not set");
13645       return -99;
13646     }
13647
13648   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13649     {
13650       errmsg ("eid types don't match");
13651       return -99;
13652     }
13653
13654   if (0 == rmt_locs && (u32) ~ 0 == action)
13655     {
13656       errmsg ("action not set for negative mapping");
13657       return -99;
13658     }
13659
13660   /* Construct the API message */
13661   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
13662       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
13663
13664   mp->is_add = is_add;
13665   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13666   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13667   mp->eid_type = rmt_eid->type;
13668   mp->dp_table = clib_host_to_net_u32 (dp_table);
13669   mp->vni = clib_host_to_net_u32 (vni);
13670   mp->rmt_len = rmt_eid->len;
13671   mp->lcl_len = lcl_eid->len;
13672   mp->action = action;
13673
13674   if (0 != rmt_locs && 0 != lcl_locs)
13675     {
13676       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
13677       clib_memcpy (mp->locs, lcl_locs,
13678                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
13679
13680       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
13681       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
13682                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
13683     }
13684   vec_free (lcl_locs);
13685   vec_free (rmt_locs);
13686
13687   /* send it... */
13688   S (mp);
13689
13690   /* Wait for a reply... */
13691   W (ret);
13692   return ret;
13693 }
13694
13695 static int
13696 api_one_add_del_map_server (vat_main_t * vam)
13697 {
13698   unformat_input_t *input = vam->input;
13699   vl_api_one_add_del_map_server_t *mp;
13700   u8 is_add = 1;
13701   u8 ipv4_set = 0;
13702   u8 ipv6_set = 0;
13703   ip4_address_t ipv4;
13704   ip6_address_t ipv6;
13705   int ret;
13706
13707   /* Parse args required to build the message */
13708   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13709     {
13710       if (unformat (input, "del"))
13711         {
13712           is_add = 0;
13713         }
13714       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13715         {
13716           ipv4_set = 1;
13717         }
13718       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13719         {
13720           ipv6_set = 1;
13721         }
13722       else
13723         break;
13724     }
13725
13726   if (ipv4_set && ipv6_set)
13727     {
13728       errmsg ("both eid v4 and v6 addresses set");
13729       return -99;
13730     }
13731
13732   if (!ipv4_set && !ipv6_set)
13733     {
13734       errmsg ("eid addresses not set");
13735       return -99;
13736     }
13737
13738   /* Construct the API message */
13739   M (ONE_ADD_DEL_MAP_SERVER, mp);
13740
13741   mp->is_add = is_add;
13742   if (ipv6_set)
13743     {
13744       mp->is_ipv6 = 1;
13745       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13746     }
13747   else
13748     {
13749       mp->is_ipv6 = 0;
13750       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13751     }
13752
13753   /* send it... */
13754   S (mp);
13755
13756   /* Wait for a reply... */
13757   W (ret);
13758   return ret;
13759 }
13760
13761 #define api_lisp_add_del_map_server api_one_add_del_map_server
13762
13763 static int
13764 api_one_add_del_map_resolver (vat_main_t * vam)
13765 {
13766   unformat_input_t *input = vam->input;
13767   vl_api_one_add_del_map_resolver_t *mp;
13768   u8 is_add = 1;
13769   u8 ipv4_set = 0;
13770   u8 ipv6_set = 0;
13771   ip4_address_t ipv4;
13772   ip6_address_t ipv6;
13773   int ret;
13774
13775   /* Parse args required to build the message */
13776   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13777     {
13778       if (unformat (input, "del"))
13779         {
13780           is_add = 0;
13781         }
13782       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13783         {
13784           ipv4_set = 1;
13785         }
13786       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13787         {
13788           ipv6_set = 1;
13789         }
13790       else
13791         break;
13792     }
13793
13794   if (ipv4_set && ipv6_set)
13795     {
13796       errmsg ("both eid v4 and v6 addresses set");
13797       return -99;
13798     }
13799
13800   if (!ipv4_set && !ipv6_set)
13801     {
13802       errmsg ("eid addresses not set");
13803       return -99;
13804     }
13805
13806   /* Construct the API message */
13807   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
13808
13809   mp->is_add = is_add;
13810   if (ipv6_set)
13811     {
13812       mp->is_ipv6 = 1;
13813       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13814     }
13815   else
13816     {
13817       mp->is_ipv6 = 0;
13818       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13819     }
13820
13821   /* send it... */
13822   S (mp);
13823
13824   /* Wait for a reply... */
13825   W (ret);
13826   return ret;
13827 }
13828
13829 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
13830
13831 static int
13832 api_lisp_gpe_enable_disable (vat_main_t * vam)
13833 {
13834   unformat_input_t *input = vam->input;
13835   vl_api_gpe_enable_disable_t *mp;
13836   u8 is_set = 0;
13837   u8 is_en = 1;
13838   int ret;
13839
13840   /* Parse args required to build the message */
13841   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13842     {
13843       if (unformat (input, "enable"))
13844         {
13845           is_set = 1;
13846           is_en = 1;
13847         }
13848       else if (unformat (input, "disable"))
13849         {
13850           is_set = 1;
13851           is_en = 0;
13852         }
13853       else
13854         break;
13855     }
13856
13857   if (is_set == 0)
13858     {
13859       errmsg ("Value not set");
13860       return -99;
13861     }
13862
13863   /* Construct the API message */
13864   M (GPE_ENABLE_DISABLE, mp);
13865
13866   mp->is_en = is_en;
13867
13868   /* send it... */
13869   S (mp);
13870
13871   /* Wait for a reply... */
13872   W (ret);
13873   return ret;
13874 }
13875
13876 static int
13877 api_one_rloc_probe_enable_disable (vat_main_t * vam)
13878 {
13879   unformat_input_t *input = vam->input;
13880   vl_api_one_rloc_probe_enable_disable_t *mp;
13881   u8 is_set = 0;
13882   u8 is_en = 0;
13883   int ret;
13884
13885   /* Parse args required to build the message */
13886   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13887     {
13888       if (unformat (input, "enable"))
13889         {
13890           is_set = 1;
13891           is_en = 1;
13892         }
13893       else if (unformat (input, "disable"))
13894         is_set = 1;
13895       else
13896         break;
13897     }
13898
13899   if (!is_set)
13900     {
13901       errmsg ("Value not set");
13902       return -99;
13903     }
13904
13905   /* Construct the API message */
13906   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
13907
13908   mp->is_enabled = is_en;
13909
13910   /* send it... */
13911   S (mp);
13912
13913   /* Wait for a reply... */
13914   W (ret);
13915   return ret;
13916 }
13917
13918 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
13919
13920 static int
13921 api_one_map_register_enable_disable (vat_main_t * vam)
13922 {
13923   unformat_input_t *input = vam->input;
13924   vl_api_one_map_register_enable_disable_t *mp;
13925   u8 is_set = 0;
13926   u8 is_en = 0;
13927   int ret;
13928
13929   /* Parse args required to build the message */
13930   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13931     {
13932       if (unformat (input, "enable"))
13933         {
13934           is_set = 1;
13935           is_en = 1;
13936         }
13937       else if (unformat (input, "disable"))
13938         is_set = 1;
13939       else
13940         break;
13941     }
13942
13943   if (!is_set)
13944     {
13945       errmsg ("Value not set");
13946       return -99;
13947     }
13948
13949   /* Construct the API message */
13950   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
13951
13952   mp->is_enabled = is_en;
13953
13954   /* send it... */
13955   S (mp);
13956
13957   /* Wait for a reply... */
13958   W (ret);
13959   return ret;
13960 }
13961
13962 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
13963
13964 static int
13965 api_one_enable_disable (vat_main_t * vam)
13966 {
13967   unformat_input_t *input = vam->input;
13968   vl_api_one_enable_disable_t *mp;
13969   u8 is_set = 0;
13970   u8 is_en = 0;
13971   int ret;
13972
13973   /* Parse args required to build the message */
13974   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13975     {
13976       if (unformat (input, "enable"))
13977         {
13978           is_set = 1;
13979           is_en = 1;
13980         }
13981       else if (unformat (input, "disable"))
13982         {
13983           is_set = 1;
13984         }
13985       else
13986         break;
13987     }
13988
13989   if (!is_set)
13990     {
13991       errmsg ("Value not set");
13992       return -99;
13993     }
13994
13995   /* Construct the API message */
13996   M (ONE_ENABLE_DISABLE, mp);
13997
13998   mp->is_en = is_en;
13999
14000   /* send it... */
14001   S (mp);
14002
14003   /* Wait for a reply... */
14004   W (ret);
14005   return ret;
14006 }
14007
14008 #define api_lisp_enable_disable api_one_enable_disable
14009
14010 static int
14011 api_show_one_map_register_state (vat_main_t * vam)
14012 {
14013   vl_api_show_one_map_register_state_t *mp;
14014   int ret;
14015
14016   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
14017
14018   /* send */
14019   S (mp);
14020
14021   /* wait for reply */
14022   W (ret);
14023   return ret;
14024 }
14025
14026 #define api_show_lisp_map_register_state api_show_one_map_register_state
14027
14028 static int
14029 api_show_one_rloc_probe_state (vat_main_t * vam)
14030 {
14031   vl_api_show_one_rloc_probe_state_t *mp;
14032   int ret;
14033
14034   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
14035
14036   /* send */
14037   S (mp);
14038
14039   /* wait for reply */
14040   W (ret);
14041   return ret;
14042 }
14043
14044 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
14045
14046 static int
14047 api_show_one_map_request_mode (vat_main_t * vam)
14048 {
14049   vl_api_show_one_map_request_mode_t *mp;
14050   int ret;
14051
14052   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
14053
14054   /* send */
14055   S (mp);
14056
14057   /* wait for reply */
14058   W (ret);
14059   return ret;
14060 }
14061
14062 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
14063
14064 static int
14065 api_one_map_request_mode (vat_main_t * vam)
14066 {
14067   unformat_input_t *input = vam->input;
14068   vl_api_one_map_request_mode_t *mp;
14069   u8 mode = 0;
14070   int ret;
14071
14072   /* Parse args required to build the message */
14073   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14074     {
14075       if (unformat (input, "dst-only"))
14076         mode = 0;
14077       else if (unformat (input, "src-dst"))
14078         mode = 1;
14079       else
14080         {
14081           errmsg ("parse error '%U'", format_unformat_error, input);
14082           return -99;
14083         }
14084     }
14085
14086   M (ONE_MAP_REQUEST_MODE, mp);
14087
14088   mp->mode = mode;
14089
14090   /* send */
14091   S (mp);
14092
14093   /* wait for reply */
14094   W (ret);
14095   return ret;
14096 }
14097
14098 #define api_lisp_map_request_mode api_one_map_request_mode
14099
14100 /**
14101  * Enable/disable ONE proxy ITR.
14102  *
14103  * @param vam vpp API test context
14104  * @return return code
14105  */
14106 static int
14107 api_one_pitr_set_locator_set (vat_main_t * vam)
14108 {
14109   u8 ls_name_set = 0;
14110   unformat_input_t *input = vam->input;
14111   vl_api_one_pitr_set_locator_set_t *mp;
14112   u8 is_add = 1;
14113   u8 *ls_name = 0;
14114   int ret;
14115
14116   /* Parse args required to build the message */
14117   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14118     {
14119       if (unformat (input, "del"))
14120         is_add = 0;
14121       else if (unformat (input, "locator-set %s", &ls_name))
14122         ls_name_set = 1;
14123       else
14124         {
14125           errmsg ("parse error '%U'", format_unformat_error, input);
14126           return -99;
14127         }
14128     }
14129
14130   if (!ls_name_set)
14131     {
14132       errmsg ("locator-set name not set!");
14133       return -99;
14134     }
14135
14136   M (ONE_PITR_SET_LOCATOR_SET, mp);
14137
14138   mp->is_add = is_add;
14139   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
14140   vec_free (ls_name);
14141
14142   /* send */
14143   S (mp);
14144
14145   /* wait for reply */
14146   W (ret);
14147   return ret;
14148 }
14149
14150 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
14151
14152 static int
14153 api_show_one_pitr (vat_main_t * vam)
14154 {
14155   vl_api_show_one_pitr_t *mp;
14156   int ret;
14157
14158   if (!vam->json_output)
14159     {
14160       print (vam->ofp, "%=20s", "lisp status:");
14161     }
14162
14163   M (SHOW_ONE_PITR, mp);
14164   /* send it... */
14165   S (mp);
14166
14167   /* Wait for a reply... */
14168   W (ret);
14169   return ret;
14170 }
14171
14172 #define api_show_lisp_pitr api_show_one_pitr
14173
14174 /**
14175  * Add/delete mapping between vni and vrf
14176  */
14177 static int
14178 api_one_eid_table_add_del_map (vat_main_t * vam)
14179 {
14180   unformat_input_t *input = vam->input;
14181   vl_api_one_eid_table_add_del_map_t *mp;
14182   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
14183   u32 vni, vrf, bd_index;
14184   int ret;
14185
14186   /* Parse args required to build the message */
14187   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14188     {
14189       if (unformat (input, "del"))
14190         is_add = 0;
14191       else if (unformat (input, "vrf %d", &vrf))
14192         vrf_set = 1;
14193       else if (unformat (input, "bd_index %d", &bd_index))
14194         bd_index_set = 1;
14195       else if (unformat (input, "vni %d", &vni))
14196         vni_set = 1;
14197       else
14198         break;
14199     }
14200
14201   if (!vni_set || (!vrf_set && !bd_index_set))
14202     {
14203       errmsg ("missing arguments!");
14204       return -99;
14205     }
14206
14207   if (vrf_set && bd_index_set)
14208     {
14209       errmsg ("error: both vrf and bd entered!");
14210       return -99;
14211     }
14212
14213   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
14214
14215   mp->is_add = is_add;
14216   mp->vni = htonl (vni);
14217   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
14218   mp->is_l2 = bd_index_set;
14219
14220   /* send */
14221   S (mp);
14222
14223   /* wait for reply */
14224   W (ret);
14225   return ret;
14226 }
14227
14228 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
14229
14230 uword
14231 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
14232 {
14233   u32 *action = va_arg (*args, u32 *);
14234   u8 *s = 0;
14235
14236   if (unformat (input, "%s", &s))
14237     {
14238       if (!strcmp ((char *) s, "no-action"))
14239         action[0] = 0;
14240       else if (!strcmp ((char *) s, "natively-forward"))
14241         action[0] = 1;
14242       else if (!strcmp ((char *) s, "send-map-request"))
14243         action[0] = 2;
14244       else if (!strcmp ((char *) s, "drop"))
14245         action[0] = 3;
14246       else
14247         {
14248           clib_warning ("invalid action: '%s'", s);
14249           action[0] = 3;
14250         }
14251     }
14252   else
14253     return 0;
14254
14255   vec_free (s);
14256   return 1;
14257 }
14258
14259 /**
14260  * Add/del remote mapping to/from ONE control plane
14261  *
14262  * @param vam vpp API test context
14263  * @return return code
14264  */
14265 static int
14266 api_one_add_del_remote_mapping (vat_main_t * vam)
14267 {
14268   unformat_input_t *input = vam->input;
14269   vl_api_one_add_del_remote_mapping_t *mp;
14270   u32 vni = 0;
14271   lisp_eid_vat_t _eid, *eid = &_eid;
14272   lisp_eid_vat_t _seid, *seid = &_seid;
14273   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
14274   u32 action = ~0, p, w, data_len;
14275   ip4_address_t rloc4;
14276   ip6_address_t rloc6;
14277   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
14278   int ret;
14279
14280   memset (&rloc, 0, sizeof (rloc));
14281
14282   /* Parse args required to build the message */
14283   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14284     {
14285       if (unformat (input, "del-all"))
14286         {
14287           del_all = 1;
14288         }
14289       else if (unformat (input, "del"))
14290         {
14291           is_add = 0;
14292         }
14293       else if (unformat (input, "add"))
14294         {
14295           is_add = 1;
14296         }
14297       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14298         {
14299           eid_set = 1;
14300         }
14301       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
14302         {
14303           seid_set = 1;
14304         }
14305       else if (unformat (input, "vni %d", &vni))
14306         {
14307           ;
14308         }
14309       else if (unformat (input, "p %d w %d", &p, &w))
14310         {
14311           if (!curr_rloc)
14312             {
14313               errmsg ("No RLOC configured for setting priority/weight!");
14314               return -99;
14315             }
14316           curr_rloc->priority = p;
14317           curr_rloc->weight = w;
14318         }
14319       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
14320         {
14321           rloc.is_ip4 = 1;
14322           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
14323           vec_add1 (rlocs, rloc);
14324           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14325         }
14326       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
14327         {
14328           rloc.is_ip4 = 0;
14329           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
14330           vec_add1 (rlocs, rloc);
14331           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14332         }
14333       else if (unformat (input, "action %U",
14334                          unformat_negative_mapping_action, &action))
14335         {
14336           ;
14337         }
14338       else
14339         {
14340           clib_warning ("parse error '%U'", format_unformat_error, input);
14341           return -99;
14342         }
14343     }
14344
14345   if (0 == eid_set)
14346     {
14347       errmsg ("missing params!");
14348       return -99;
14349     }
14350
14351   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
14352     {
14353       errmsg ("no action set for negative map-reply!");
14354       return -99;
14355     }
14356
14357   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
14358
14359   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
14360   mp->is_add = is_add;
14361   mp->vni = htonl (vni);
14362   mp->action = (u8) action;
14363   mp->is_src_dst = seid_set;
14364   mp->eid_len = eid->len;
14365   mp->seid_len = seid->len;
14366   mp->del_all = del_all;
14367   mp->eid_type = eid->type;
14368   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14369   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
14370
14371   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
14372   clib_memcpy (mp->rlocs, rlocs, data_len);
14373   vec_free (rlocs);
14374
14375   /* send it... */
14376   S (mp);
14377
14378   /* Wait for a reply... */
14379   W (ret);
14380   return ret;
14381 }
14382
14383 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
14384
14385 /**
14386  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
14387  * forwarding entries in data-plane accordingly.
14388  *
14389  * @param vam vpp API test context
14390  * @return return code
14391  */
14392 static int
14393 api_one_add_del_adjacency (vat_main_t * vam)
14394 {
14395   unformat_input_t *input = vam->input;
14396   vl_api_one_add_del_adjacency_t *mp;
14397   u32 vni = 0;
14398   ip4_address_t leid4, reid4;
14399   ip6_address_t leid6, reid6;
14400   u8 reid_mac[6] = { 0 };
14401   u8 leid_mac[6] = { 0 };
14402   u8 reid_type, leid_type;
14403   u32 leid_len = 0, reid_len = 0, len;
14404   u8 is_add = 1;
14405   int ret;
14406
14407   leid_type = reid_type = (u8) ~ 0;
14408
14409   /* Parse args required to build the message */
14410   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14411     {
14412       if (unformat (input, "del"))
14413         {
14414           is_add = 0;
14415         }
14416       else if (unformat (input, "add"))
14417         {
14418           is_add = 1;
14419         }
14420       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
14421                          &reid4, &len))
14422         {
14423           reid_type = 0;        /* ipv4 */
14424           reid_len = len;
14425         }
14426       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
14427                          &reid6, &len))
14428         {
14429           reid_type = 1;        /* ipv6 */
14430           reid_len = len;
14431         }
14432       else if (unformat (input, "reid %U", unformat_ethernet_address,
14433                          reid_mac))
14434         {
14435           reid_type = 2;        /* mac */
14436         }
14437       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
14438                          &leid4, &len))
14439         {
14440           leid_type = 0;        /* ipv4 */
14441           leid_len = len;
14442         }
14443       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
14444                          &leid6, &len))
14445         {
14446           leid_type = 1;        /* ipv6 */
14447           leid_len = len;
14448         }
14449       else if (unformat (input, "leid %U", unformat_ethernet_address,
14450                          leid_mac))
14451         {
14452           leid_type = 2;        /* mac */
14453         }
14454       else if (unformat (input, "vni %d", &vni))
14455         {
14456           ;
14457         }
14458       else
14459         {
14460           errmsg ("parse error '%U'", format_unformat_error, input);
14461           return -99;
14462         }
14463     }
14464
14465   if ((u8) ~ 0 == reid_type)
14466     {
14467       errmsg ("missing params!");
14468       return -99;
14469     }
14470
14471   if (leid_type != reid_type)
14472     {
14473       errmsg ("remote and local EIDs are of different types!");
14474       return -99;
14475     }
14476
14477   M (ONE_ADD_DEL_ADJACENCY, mp);
14478   mp->is_add = is_add;
14479   mp->vni = htonl (vni);
14480   mp->leid_len = leid_len;
14481   mp->reid_len = reid_len;
14482   mp->eid_type = reid_type;
14483
14484   switch (mp->eid_type)
14485     {
14486     case 0:
14487       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
14488       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
14489       break;
14490     case 1:
14491       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
14492       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
14493       break;
14494     case 2:
14495       clib_memcpy (mp->leid, leid_mac, 6);
14496       clib_memcpy (mp->reid, reid_mac, 6);
14497       break;
14498     default:
14499       errmsg ("unknown EID type %d!", mp->eid_type);
14500       return 0;
14501     }
14502
14503   /* send it... */
14504   S (mp);
14505
14506   /* Wait for a reply... */
14507   W (ret);
14508   return ret;
14509 }
14510
14511 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
14512
14513 uword
14514 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
14515 {
14516   u32 *mode = va_arg (*args, u32 *);
14517
14518   if (unformat (input, "lisp"))
14519     *mode = 0;
14520   else if (unformat (input, "vxlan"))
14521     *mode = 1;
14522   else
14523     return 0;
14524
14525   return 1;
14526 }
14527
14528 static int
14529 api_gpe_get_encap_mode (vat_main_t * vam)
14530 {
14531   vl_api_gpe_get_encap_mode_t *mp;
14532   int ret;
14533
14534   /* Construct the API message */
14535   M (GPE_GET_ENCAP_MODE, mp);
14536
14537   /* send it... */
14538   S (mp);
14539
14540   /* Wait for a reply... */
14541   W (ret);
14542   return ret;
14543 }
14544
14545 static int
14546 api_gpe_set_encap_mode (vat_main_t * vam)
14547 {
14548   unformat_input_t *input = vam->input;
14549   vl_api_gpe_set_encap_mode_t *mp;
14550   int ret;
14551   u32 mode = 0;
14552
14553   /* Parse args required to build the message */
14554   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14555     {
14556       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
14557         ;
14558       else
14559         break;
14560     }
14561
14562   /* Construct the API message */
14563   M (GPE_SET_ENCAP_MODE, mp);
14564
14565   mp->mode = mode;
14566
14567   /* send it... */
14568   S (mp);
14569
14570   /* Wait for a reply... */
14571   W (ret);
14572   return ret;
14573 }
14574
14575 static int
14576 api_lisp_gpe_add_del_iface (vat_main_t * vam)
14577 {
14578   unformat_input_t *input = vam->input;
14579   vl_api_gpe_add_del_iface_t *mp;
14580   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
14581   u32 dp_table = 0, vni = 0;
14582   int ret;
14583
14584   /* Parse args required to build the message */
14585   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14586     {
14587       if (unformat (input, "up"))
14588         {
14589           action_set = 1;
14590           is_add = 1;
14591         }
14592       else if (unformat (input, "down"))
14593         {
14594           action_set = 1;
14595           is_add = 0;
14596         }
14597       else if (unformat (input, "table_id %d", &dp_table))
14598         {
14599           dp_table_set = 1;
14600         }
14601       else if (unformat (input, "bd_id %d", &dp_table))
14602         {
14603           dp_table_set = 1;
14604           is_l2 = 1;
14605         }
14606       else if (unformat (input, "vni %d", &vni))
14607         {
14608           vni_set = 1;
14609         }
14610       else
14611         break;
14612     }
14613
14614   if (action_set == 0)
14615     {
14616       errmsg ("Action not set");
14617       return -99;
14618     }
14619   if (dp_table_set == 0 || vni_set == 0)
14620     {
14621       errmsg ("vni and dp_table must be set");
14622       return -99;
14623     }
14624
14625   /* Construct the API message */
14626   M (GPE_ADD_DEL_IFACE, mp);
14627
14628   mp->is_add = is_add;
14629   mp->dp_table = dp_table;
14630   mp->is_l2 = is_l2;
14631   mp->vni = vni;
14632
14633   /* send it... */
14634   S (mp);
14635
14636   /* Wait for a reply... */
14637   W (ret);
14638   return ret;
14639 }
14640
14641 /**
14642  * Add/del map request itr rlocs from ONE control plane and updates
14643  *
14644  * @param vam vpp API test context
14645  * @return return code
14646  */
14647 static int
14648 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
14649 {
14650   unformat_input_t *input = vam->input;
14651   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
14652   u8 *locator_set_name = 0;
14653   u8 locator_set_name_set = 0;
14654   u8 is_add = 1;
14655   int ret;
14656
14657   /* Parse args required to build the message */
14658   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14659     {
14660       if (unformat (input, "del"))
14661         {
14662           is_add = 0;
14663         }
14664       else if (unformat (input, "%_%v%_", &locator_set_name))
14665         {
14666           locator_set_name_set = 1;
14667         }
14668       else
14669         {
14670           clib_warning ("parse error '%U'", format_unformat_error, input);
14671           return -99;
14672         }
14673     }
14674
14675   if (is_add && !locator_set_name_set)
14676     {
14677       errmsg ("itr-rloc is not set!");
14678       return -99;
14679     }
14680
14681   if (is_add && vec_len (locator_set_name) > 64)
14682     {
14683       errmsg ("itr-rloc locator-set name too long");
14684       vec_free (locator_set_name);
14685       return -99;
14686     }
14687
14688   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
14689   mp->is_add = is_add;
14690   if (is_add)
14691     {
14692       clib_memcpy (mp->locator_set_name, locator_set_name,
14693                    vec_len (locator_set_name));
14694     }
14695   else
14696     {
14697       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
14698     }
14699   vec_free (locator_set_name);
14700
14701   /* send it... */
14702   S (mp);
14703
14704   /* Wait for a reply... */
14705   W (ret);
14706   return ret;
14707 }
14708
14709 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
14710
14711 static int
14712 api_one_locator_dump (vat_main_t * vam)
14713 {
14714   unformat_input_t *input = vam->input;
14715   vl_api_one_locator_dump_t *mp;
14716   vl_api_control_ping_t *mp_ping;
14717   u8 is_index_set = 0, is_name_set = 0;
14718   u8 *ls_name = 0;
14719   u32 ls_index = ~0;
14720   int ret;
14721
14722   /* Parse args required to build the message */
14723   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14724     {
14725       if (unformat (input, "ls_name %_%v%_", &ls_name))
14726         {
14727           is_name_set = 1;
14728         }
14729       else if (unformat (input, "ls_index %d", &ls_index))
14730         {
14731           is_index_set = 1;
14732         }
14733       else
14734         {
14735           errmsg ("parse error '%U'", format_unformat_error, input);
14736           return -99;
14737         }
14738     }
14739
14740   if (!is_index_set && !is_name_set)
14741     {
14742       errmsg ("error: expected one of index or name!");
14743       return -99;
14744     }
14745
14746   if (is_index_set && is_name_set)
14747     {
14748       errmsg ("error: only one param expected!");
14749       return -99;
14750     }
14751
14752   if (vec_len (ls_name) > 62)
14753     {
14754       errmsg ("error: locator set name too long!");
14755       return -99;
14756     }
14757
14758   if (!vam->json_output)
14759     {
14760       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
14761     }
14762
14763   M (ONE_LOCATOR_DUMP, mp);
14764   mp->is_index_set = is_index_set;
14765
14766   if (is_index_set)
14767     mp->ls_index = clib_host_to_net_u32 (ls_index);
14768   else
14769     {
14770       vec_add1 (ls_name, 0);
14771       strncpy ((char *) mp->ls_name, (char *) ls_name,
14772                sizeof (mp->ls_name) - 1);
14773     }
14774
14775   /* send it... */
14776   S (mp);
14777
14778   /* Use a control ping for synchronization */
14779   M (CONTROL_PING, mp_ping);
14780   S (mp_ping);
14781
14782   /* Wait for a reply... */
14783   W (ret);
14784   return ret;
14785 }
14786
14787 #define api_lisp_locator_dump api_one_locator_dump
14788
14789 static int
14790 api_one_locator_set_dump (vat_main_t * vam)
14791 {
14792   vl_api_one_locator_set_dump_t *mp;
14793   vl_api_control_ping_t *mp_ping;
14794   unformat_input_t *input = vam->input;
14795   u8 filter = 0;
14796   int ret;
14797
14798   /* Parse args required to build the message */
14799   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14800     {
14801       if (unformat (input, "local"))
14802         {
14803           filter = 1;
14804         }
14805       else if (unformat (input, "remote"))
14806         {
14807           filter = 2;
14808         }
14809       else
14810         {
14811           errmsg ("parse error '%U'", format_unformat_error, input);
14812           return -99;
14813         }
14814     }
14815
14816   if (!vam->json_output)
14817     {
14818       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
14819     }
14820
14821   M (ONE_LOCATOR_SET_DUMP, mp);
14822
14823   mp->filter = filter;
14824
14825   /* send it... */
14826   S (mp);
14827
14828   /* Use a control ping for synchronization */
14829   M (CONTROL_PING, mp_ping);
14830   S (mp_ping);
14831
14832   /* Wait for a reply... */
14833   W (ret);
14834   return ret;
14835 }
14836
14837 #define api_lisp_locator_set_dump api_one_locator_set_dump
14838
14839 static int
14840 api_one_eid_table_map_dump (vat_main_t * vam)
14841 {
14842   u8 is_l2 = 0;
14843   u8 mode_set = 0;
14844   unformat_input_t *input = vam->input;
14845   vl_api_one_eid_table_map_dump_t *mp;
14846   vl_api_control_ping_t *mp_ping;
14847   int ret;
14848
14849   /* Parse args required to build the message */
14850   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14851     {
14852       if (unformat (input, "l2"))
14853         {
14854           is_l2 = 1;
14855           mode_set = 1;
14856         }
14857       else if (unformat (input, "l3"))
14858         {
14859           is_l2 = 0;
14860           mode_set = 1;
14861         }
14862       else
14863         {
14864           errmsg ("parse error '%U'", format_unformat_error, input);
14865           return -99;
14866         }
14867     }
14868
14869   if (!mode_set)
14870     {
14871       errmsg ("expected one of 'l2' or 'l3' parameter!");
14872       return -99;
14873     }
14874
14875   if (!vam->json_output)
14876     {
14877       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
14878     }
14879
14880   M (ONE_EID_TABLE_MAP_DUMP, mp);
14881   mp->is_l2 = is_l2;
14882
14883   /* send it... */
14884   S (mp);
14885
14886   /* Use a control ping for synchronization */
14887   M (CONTROL_PING, mp_ping);
14888   S (mp_ping);
14889
14890   /* Wait for a reply... */
14891   W (ret);
14892   return ret;
14893 }
14894
14895 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
14896
14897 static int
14898 api_one_eid_table_vni_dump (vat_main_t * vam)
14899 {
14900   vl_api_one_eid_table_vni_dump_t *mp;
14901   vl_api_control_ping_t *mp_ping;
14902   int ret;
14903
14904   if (!vam->json_output)
14905     {
14906       print (vam->ofp, "VNI");
14907     }
14908
14909   M (ONE_EID_TABLE_VNI_DUMP, mp);
14910
14911   /* send it... */
14912   S (mp);
14913
14914   /* Use a control ping for synchronization */
14915   M (CONTROL_PING, mp_ping);
14916   S (mp_ping);
14917
14918   /* Wait for a reply... */
14919   W (ret);
14920   return ret;
14921 }
14922
14923 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
14924
14925 static int
14926 api_one_eid_table_dump (vat_main_t * vam)
14927 {
14928   unformat_input_t *i = vam->input;
14929   vl_api_one_eid_table_dump_t *mp;
14930   vl_api_control_ping_t *mp_ping;
14931   struct in_addr ip4;
14932   struct in6_addr ip6;
14933   u8 mac[6];
14934   u8 eid_type = ~0, eid_set = 0;
14935   u32 prefix_length = ~0, t, vni = 0;
14936   u8 filter = 0;
14937   int ret;
14938
14939   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14940     {
14941       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
14942         {
14943           eid_set = 1;
14944           eid_type = 0;
14945           prefix_length = t;
14946         }
14947       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
14948         {
14949           eid_set = 1;
14950           eid_type = 1;
14951           prefix_length = t;
14952         }
14953       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
14954         {
14955           eid_set = 1;
14956           eid_type = 2;
14957         }
14958       else if (unformat (i, "vni %d", &t))
14959         {
14960           vni = t;
14961         }
14962       else if (unformat (i, "local"))
14963         {
14964           filter = 1;
14965         }
14966       else if (unformat (i, "remote"))
14967         {
14968           filter = 2;
14969         }
14970       else
14971         {
14972           errmsg ("parse error '%U'", format_unformat_error, i);
14973           return -99;
14974         }
14975     }
14976
14977   if (!vam->json_output)
14978     {
14979       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
14980              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
14981     }
14982
14983   M (ONE_EID_TABLE_DUMP, mp);
14984
14985   mp->filter = filter;
14986   if (eid_set)
14987     {
14988       mp->eid_set = 1;
14989       mp->vni = htonl (vni);
14990       mp->eid_type = eid_type;
14991       switch (eid_type)
14992         {
14993         case 0:
14994           mp->prefix_length = prefix_length;
14995           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
14996           break;
14997         case 1:
14998           mp->prefix_length = prefix_length;
14999           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
15000           break;
15001         case 2:
15002           clib_memcpy (mp->eid, mac, sizeof (mac));
15003           break;
15004         default:
15005           errmsg ("unknown EID type %d!", eid_type);
15006           return -99;
15007         }
15008     }
15009
15010   /* send it... */
15011   S (mp);
15012
15013   /* Use a control ping for synchronization */
15014   M (CONTROL_PING, mp_ping);
15015   S (mp_ping);
15016
15017   /* Wait for a reply... */
15018   W (ret);
15019   return ret;
15020 }
15021
15022 #define api_lisp_eid_table_dump api_one_eid_table_dump
15023
15024 static int
15025 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
15026 {
15027   unformat_input_t *i = vam->input;
15028   vl_api_gpe_fwd_entries_get_t *mp;
15029   u8 vni_set = 0;
15030   u32 vni = ~0;
15031   int ret;
15032
15033   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15034     {
15035       if (unformat (i, "vni %d", &vni))
15036         {
15037           vni_set = 1;
15038         }
15039       else
15040         {
15041           errmsg ("parse error '%U'", format_unformat_error, i);
15042           return -99;
15043         }
15044     }
15045
15046   if (!vni_set)
15047     {
15048       errmsg ("vni not set!");
15049       return -99;
15050     }
15051
15052   if (!vam->json_output)
15053     {
15054       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
15055              "leid", "reid");
15056     }
15057
15058   M (GPE_FWD_ENTRIES_GET, mp);
15059   mp->vni = clib_host_to_net_u32 (vni);
15060
15061   /* send it... */
15062   S (mp);
15063
15064   /* Wait for a reply... */
15065   W (ret);
15066   return ret;
15067 }
15068
15069 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
15070 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
15071 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
15072 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
15073
15074 static int
15075 api_one_adjacencies_get (vat_main_t * vam)
15076 {
15077   unformat_input_t *i = vam->input;
15078   vl_api_one_adjacencies_get_t *mp;
15079   u8 vni_set = 0;
15080   u32 vni = ~0;
15081   int ret;
15082
15083   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15084     {
15085       if (unformat (i, "vni %d", &vni))
15086         {
15087           vni_set = 1;
15088         }
15089       else
15090         {
15091           errmsg ("parse error '%U'", format_unformat_error, i);
15092           return -99;
15093         }
15094     }
15095
15096   if (!vni_set)
15097     {
15098       errmsg ("vni not set!");
15099       return -99;
15100     }
15101
15102   if (!vam->json_output)
15103     {
15104       print (vam->ofp, "%s %40s", "leid", "reid");
15105     }
15106
15107   M (ONE_ADJACENCIES_GET, mp);
15108   mp->vni = clib_host_to_net_u32 (vni);
15109
15110   /* send it... */
15111   S (mp);
15112
15113   /* Wait for a reply... */
15114   W (ret);
15115   return ret;
15116 }
15117
15118 #define api_lisp_adjacencies_get api_one_adjacencies_get
15119
15120 static int
15121 api_one_map_server_dump (vat_main_t * vam)
15122 {
15123   vl_api_one_map_server_dump_t *mp;
15124   vl_api_control_ping_t *mp_ping;
15125   int ret;
15126
15127   if (!vam->json_output)
15128     {
15129       print (vam->ofp, "%=20s", "Map server");
15130     }
15131
15132   M (ONE_MAP_SERVER_DUMP, mp);
15133   /* send it... */
15134   S (mp);
15135
15136   /* Use a control ping for synchronization */
15137   M (CONTROL_PING, mp_ping);
15138   S (mp_ping);
15139
15140   /* Wait for a reply... */
15141   W (ret);
15142   return ret;
15143 }
15144
15145 #define api_lisp_map_server_dump api_one_map_server_dump
15146
15147 static int
15148 api_one_map_resolver_dump (vat_main_t * vam)
15149 {
15150   vl_api_one_map_resolver_dump_t *mp;
15151   vl_api_control_ping_t *mp_ping;
15152   int ret;
15153
15154   if (!vam->json_output)
15155     {
15156       print (vam->ofp, "%=20s", "Map resolver");
15157     }
15158
15159   M (ONE_MAP_RESOLVER_DUMP, mp);
15160   /* send it... */
15161   S (mp);
15162
15163   /* Use a control ping for synchronization */
15164   M (CONTROL_PING, mp_ping);
15165   S (mp_ping);
15166
15167   /* Wait for a reply... */
15168   W (ret);
15169   return ret;
15170 }
15171
15172 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
15173
15174 static int
15175 api_show_one_status (vat_main_t * vam)
15176 {
15177   vl_api_show_one_status_t *mp;
15178   int ret;
15179
15180   if (!vam->json_output)
15181     {
15182       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
15183     }
15184
15185   M (SHOW_ONE_STATUS, mp);
15186   /* send it... */
15187   S (mp);
15188   /* Wait for a reply... */
15189   W (ret);
15190   return ret;
15191 }
15192
15193 #define api_show_lisp_status api_show_one_status
15194
15195 static int
15196 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
15197 {
15198   vl_api_gpe_fwd_entry_path_dump_t *mp;
15199   vl_api_control_ping_t *mp_ping;
15200   unformat_input_t *i = vam->input;
15201   u32 fwd_entry_index = ~0;
15202   int ret;
15203
15204   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15205     {
15206       if (unformat (i, "index %d", &fwd_entry_index))
15207         ;
15208       else
15209         break;
15210     }
15211
15212   if (~0 == fwd_entry_index)
15213     {
15214       errmsg ("no index specified!");
15215       return -99;
15216     }
15217
15218   if (!vam->json_output)
15219     {
15220       print (vam->ofp, "first line");
15221     }
15222
15223   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
15224
15225   /* send it... */
15226   S (mp);
15227   /* Use a control ping for synchronization */
15228   M (CONTROL_PING, mp_ping);
15229   S (mp_ping);
15230
15231   /* Wait for a reply... */
15232   W (ret);
15233   return ret;
15234 }
15235
15236 static int
15237 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
15238 {
15239   vl_api_one_get_map_request_itr_rlocs_t *mp;
15240   int ret;
15241
15242   if (!vam->json_output)
15243     {
15244       print (vam->ofp, "%=20s", "itr-rlocs:");
15245     }
15246
15247   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
15248   /* send it... */
15249   S (mp);
15250   /* Wait for a reply... */
15251   W (ret);
15252   return ret;
15253 }
15254
15255 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
15256
15257 static int
15258 api_af_packet_create (vat_main_t * vam)
15259 {
15260   unformat_input_t *i = vam->input;
15261   vl_api_af_packet_create_t *mp;
15262   u8 *host_if_name = 0;
15263   u8 hw_addr[6];
15264   u8 random_hw_addr = 1;
15265   int ret;
15266
15267   memset (hw_addr, 0, sizeof (hw_addr));
15268
15269   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15270     {
15271       if (unformat (i, "name %s", &host_if_name))
15272         vec_add1 (host_if_name, 0);
15273       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15274         random_hw_addr = 0;
15275       else
15276         break;
15277     }
15278
15279   if (!vec_len (host_if_name))
15280     {
15281       errmsg ("host-interface name must be specified");
15282       return -99;
15283     }
15284
15285   if (vec_len (host_if_name) > 64)
15286     {
15287       errmsg ("host-interface name too long");
15288       return -99;
15289     }
15290
15291   M (AF_PACKET_CREATE, mp);
15292
15293   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15294   clib_memcpy (mp->hw_addr, hw_addr, 6);
15295   mp->use_random_hw_addr = random_hw_addr;
15296   vec_free (host_if_name);
15297
15298   S (mp);
15299
15300   /* *INDENT-OFF* */
15301   W2 (ret,
15302       ({
15303         if (ret == 0)
15304           fprintf (vam->ofp ? vam->ofp : stderr,
15305                    " new sw_if_index = %d\n", vam->sw_if_index);
15306       }));
15307   /* *INDENT-ON* */
15308   return ret;
15309 }
15310
15311 static int
15312 api_af_packet_delete (vat_main_t * vam)
15313 {
15314   unformat_input_t *i = vam->input;
15315   vl_api_af_packet_delete_t *mp;
15316   u8 *host_if_name = 0;
15317   int ret;
15318
15319   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15320     {
15321       if (unformat (i, "name %s", &host_if_name))
15322         vec_add1 (host_if_name, 0);
15323       else
15324         break;
15325     }
15326
15327   if (!vec_len (host_if_name))
15328     {
15329       errmsg ("host-interface name must be specified");
15330       return -99;
15331     }
15332
15333   if (vec_len (host_if_name) > 64)
15334     {
15335       errmsg ("host-interface name too long");
15336       return -99;
15337     }
15338
15339   M (AF_PACKET_DELETE, mp);
15340
15341   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15342   vec_free (host_if_name);
15343
15344   S (mp);
15345   W (ret);
15346   return ret;
15347 }
15348
15349 static int
15350 api_policer_add_del (vat_main_t * vam)
15351 {
15352   unformat_input_t *i = vam->input;
15353   vl_api_policer_add_del_t *mp;
15354   u8 is_add = 1;
15355   u8 *name = 0;
15356   u32 cir = 0;
15357   u32 eir = 0;
15358   u64 cb = 0;
15359   u64 eb = 0;
15360   u8 rate_type = 0;
15361   u8 round_type = 0;
15362   u8 type = 0;
15363   u8 color_aware = 0;
15364   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
15365   int ret;
15366
15367   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
15368   conform_action.dscp = 0;
15369   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
15370   exceed_action.dscp = 0;
15371   violate_action.action_type = SSE2_QOS_ACTION_DROP;
15372   violate_action.dscp = 0;
15373
15374   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15375     {
15376       if (unformat (i, "del"))
15377         is_add = 0;
15378       else if (unformat (i, "name %s", &name))
15379         vec_add1 (name, 0);
15380       else if (unformat (i, "cir %u", &cir))
15381         ;
15382       else if (unformat (i, "eir %u", &eir))
15383         ;
15384       else if (unformat (i, "cb %u", &cb))
15385         ;
15386       else if (unformat (i, "eb %u", &eb))
15387         ;
15388       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
15389                          &rate_type))
15390         ;
15391       else if (unformat (i, "round_type %U", unformat_policer_round_type,
15392                          &round_type))
15393         ;
15394       else if (unformat (i, "type %U", unformat_policer_type, &type))
15395         ;
15396       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
15397                          &conform_action))
15398         ;
15399       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
15400                          &exceed_action))
15401         ;
15402       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
15403                          &violate_action))
15404         ;
15405       else if (unformat (i, "color-aware"))
15406         color_aware = 1;
15407       else
15408         break;
15409     }
15410
15411   if (!vec_len (name))
15412     {
15413       errmsg ("policer name must be specified");
15414       return -99;
15415     }
15416
15417   if (vec_len (name) > 64)
15418     {
15419       errmsg ("policer name too long");
15420       return -99;
15421     }
15422
15423   M (POLICER_ADD_DEL, mp);
15424
15425   clib_memcpy (mp->name, name, vec_len (name));
15426   vec_free (name);
15427   mp->is_add = is_add;
15428   mp->cir = cir;
15429   mp->eir = eir;
15430   mp->cb = cb;
15431   mp->eb = eb;
15432   mp->rate_type = rate_type;
15433   mp->round_type = round_type;
15434   mp->type = type;
15435   mp->conform_action_type = conform_action.action_type;
15436   mp->conform_dscp = conform_action.dscp;
15437   mp->exceed_action_type = exceed_action.action_type;
15438   mp->exceed_dscp = exceed_action.dscp;
15439   mp->violate_action_type = violate_action.action_type;
15440   mp->violate_dscp = violate_action.dscp;
15441   mp->color_aware = color_aware;
15442
15443   S (mp);
15444   W (ret);
15445   return ret;
15446 }
15447
15448 static int
15449 api_policer_dump (vat_main_t * vam)
15450 {
15451   unformat_input_t *i = vam->input;
15452   vl_api_policer_dump_t *mp;
15453   vl_api_control_ping_t *mp_ping;
15454   u8 *match_name = 0;
15455   u8 match_name_valid = 0;
15456   int ret;
15457
15458   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15459     {
15460       if (unformat (i, "name %s", &match_name))
15461         {
15462           vec_add1 (match_name, 0);
15463           match_name_valid = 1;
15464         }
15465       else
15466         break;
15467     }
15468
15469   M (POLICER_DUMP, mp);
15470   mp->match_name_valid = match_name_valid;
15471   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
15472   vec_free (match_name);
15473   /* send it... */
15474   S (mp);
15475
15476   /* Use a control ping for synchronization */
15477   M (CONTROL_PING, mp_ping);
15478   S (mp_ping);
15479
15480   /* Wait for a reply... */
15481   W (ret);
15482   return ret;
15483 }
15484
15485 static int
15486 api_policer_classify_set_interface (vat_main_t * vam)
15487 {
15488   unformat_input_t *i = vam->input;
15489   vl_api_policer_classify_set_interface_t *mp;
15490   u32 sw_if_index;
15491   int sw_if_index_set;
15492   u32 ip4_table_index = ~0;
15493   u32 ip6_table_index = ~0;
15494   u32 l2_table_index = ~0;
15495   u8 is_add = 1;
15496   int ret;
15497
15498   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15499     {
15500       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15501         sw_if_index_set = 1;
15502       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15503         sw_if_index_set = 1;
15504       else if (unformat (i, "del"))
15505         is_add = 0;
15506       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15507         ;
15508       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15509         ;
15510       else if (unformat (i, "l2-table %d", &l2_table_index))
15511         ;
15512       else
15513         {
15514           clib_warning ("parse error '%U'", format_unformat_error, i);
15515           return -99;
15516         }
15517     }
15518
15519   if (sw_if_index_set == 0)
15520     {
15521       errmsg ("missing interface name or sw_if_index");
15522       return -99;
15523     }
15524
15525   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
15526
15527   mp->sw_if_index = ntohl (sw_if_index);
15528   mp->ip4_table_index = ntohl (ip4_table_index);
15529   mp->ip6_table_index = ntohl (ip6_table_index);
15530   mp->l2_table_index = ntohl (l2_table_index);
15531   mp->is_add = is_add;
15532
15533   S (mp);
15534   W (ret);
15535   return ret;
15536 }
15537
15538 static int
15539 api_policer_classify_dump (vat_main_t * vam)
15540 {
15541   unformat_input_t *i = vam->input;
15542   vl_api_policer_classify_dump_t *mp;
15543   vl_api_control_ping_t *mp_ping;
15544   u8 type = POLICER_CLASSIFY_N_TABLES;
15545   int ret;
15546
15547   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
15548     ;
15549   else
15550     {
15551       errmsg ("classify table type must be specified");
15552       return -99;
15553     }
15554
15555   if (!vam->json_output)
15556     {
15557       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
15558     }
15559
15560   M (POLICER_CLASSIFY_DUMP, mp);
15561   mp->type = type;
15562   /* send it... */
15563   S (mp);
15564
15565   /* Use a control ping for synchronization */
15566   M (CONTROL_PING, mp_ping);
15567   S (mp_ping);
15568
15569   /* Wait for a reply... */
15570   W (ret);
15571   return ret;
15572 }
15573
15574 static int
15575 api_netmap_create (vat_main_t * vam)
15576 {
15577   unformat_input_t *i = vam->input;
15578   vl_api_netmap_create_t *mp;
15579   u8 *if_name = 0;
15580   u8 hw_addr[6];
15581   u8 random_hw_addr = 1;
15582   u8 is_pipe = 0;
15583   u8 is_master = 0;
15584   int ret;
15585
15586   memset (hw_addr, 0, sizeof (hw_addr));
15587
15588   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15589     {
15590       if (unformat (i, "name %s", &if_name))
15591         vec_add1 (if_name, 0);
15592       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15593         random_hw_addr = 0;
15594       else if (unformat (i, "pipe"))
15595         is_pipe = 1;
15596       else if (unformat (i, "master"))
15597         is_master = 1;
15598       else if (unformat (i, "slave"))
15599         is_master = 0;
15600       else
15601         break;
15602     }
15603
15604   if (!vec_len (if_name))
15605     {
15606       errmsg ("interface name must be specified");
15607       return -99;
15608     }
15609
15610   if (vec_len (if_name) > 64)
15611     {
15612       errmsg ("interface name too long");
15613       return -99;
15614     }
15615
15616   M (NETMAP_CREATE, mp);
15617
15618   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15619   clib_memcpy (mp->hw_addr, hw_addr, 6);
15620   mp->use_random_hw_addr = random_hw_addr;
15621   mp->is_pipe = is_pipe;
15622   mp->is_master = is_master;
15623   vec_free (if_name);
15624
15625   S (mp);
15626   W (ret);
15627   return ret;
15628 }
15629
15630 static int
15631 api_netmap_delete (vat_main_t * vam)
15632 {
15633   unformat_input_t *i = vam->input;
15634   vl_api_netmap_delete_t *mp;
15635   u8 *if_name = 0;
15636   int ret;
15637
15638   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15639     {
15640       if (unformat (i, "name %s", &if_name))
15641         vec_add1 (if_name, 0);
15642       else
15643         break;
15644     }
15645
15646   if (!vec_len (if_name))
15647     {
15648       errmsg ("interface name must be specified");
15649       return -99;
15650     }
15651
15652   if (vec_len (if_name) > 64)
15653     {
15654       errmsg ("interface name too long");
15655       return -99;
15656     }
15657
15658   M (NETMAP_DELETE, mp);
15659
15660   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15661   vec_free (if_name);
15662
15663   S (mp);
15664   W (ret);
15665   return ret;
15666 }
15667
15668 static void vl_api_mpls_tunnel_details_t_handler
15669   (vl_api_mpls_tunnel_details_t * mp)
15670 {
15671   vat_main_t *vam = &vat_main;
15672   i32 len = mp->mt_next_hop_n_labels;
15673   i32 i;
15674
15675   print (vam->ofp, "[%d]: via %U %d labels ",
15676          mp->tunnel_index,
15677          format_ip4_address, mp->mt_next_hop,
15678          ntohl (mp->mt_next_hop_sw_if_index));
15679   for (i = 0; i < len; i++)
15680     {
15681       print (vam->ofp, "%u ", ntohl (mp->mt_next_hop_out_labels[i]));
15682     }
15683   print (vam->ofp, "");
15684 }
15685
15686 static void vl_api_mpls_tunnel_details_t_handler_json
15687   (vl_api_mpls_tunnel_details_t * mp)
15688 {
15689   vat_main_t *vam = &vat_main;
15690   vat_json_node_t *node = NULL;
15691   struct in_addr ip4;
15692   i32 i;
15693   i32 len = mp->mt_next_hop_n_labels;
15694
15695   if (VAT_JSON_ARRAY != vam->json_tree.type)
15696     {
15697       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15698       vat_json_init_array (&vam->json_tree);
15699     }
15700   node = vat_json_array_add (&vam->json_tree);
15701
15702   vat_json_init_object (node);
15703   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
15704   clib_memcpy (&ip4, &(mp->mt_next_hop), sizeof (ip4));
15705   vat_json_object_add_ip4 (node, "next_hop", ip4);
15706   vat_json_object_add_uint (node, "next_hop_sw_if_index",
15707                             ntohl (mp->mt_next_hop_sw_if_index));
15708   vat_json_object_add_uint (node, "l2_only", ntohl (mp->mt_l2_only));
15709   vat_json_object_add_uint (node, "label_count", len);
15710   for (i = 0; i < len; i++)
15711     {
15712       vat_json_object_add_uint (node, "label",
15713                                 ntohl (mp->mt_next_hop_out_labels[i]));
15714     }
15715 }
15716
15717 static int
15718 api_mpls_tunnel_dump (vat_main_t * vam)
15719 {
15720   vl_api_mpls_tunnel_dump_t *mp;
15721   vl_api_control_ping_t *mp_ping;
15722   i32 index = -1;
15723   int ret;
15724
15725   /* Parse args required to build the message */
15726   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
15727     {
15728       if (!unformat (vam->input, "tunnel_index %d", &index))
15729         {
15730           index = -1;
15731           break;
15732         }
15733     }
15734
15735   print (vam->ofp, "  tunnel_index %d", index);
15736
15737   M (MPLS_TUNNEL_DUMP, mp);
15738   mp->tunnel_index = htonl (index);
15739   S (mp);
15740
15741   /* Use a control ping for synchronization */
15742   M (CONTROL_PING, mp_ping);
15743   S (mp_ping);
15744
15745   W (ret);
15746   return ret;
15747 }
15748
15749 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
15750 #define vl_api_mpls_fib_details_t_print vl_noop_handler
15751
15752 static void
15753 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
15754 {
15755   vat_main_t *vam = &vat_main;
15756   int count = ntohl (mp->count);
15757   vl_api_fib_path2_t *fp;
15758   int i;
15759
15760   print (vam->ofp,
15761          "table-id %d, label %u, ess_bit %u",
15762          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
15763   fp = mp->path;
15764   for (i = 0; i < count; i++)
15765     {
15766       if (fp->afi == IP46_TYPE_IP6)
15767         print (vam->ofp,
15768                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15769                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15770                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15771                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15772                format_ip6_address, fp->next_hop);
15773       else if (fp->afi == IP46_TYPE_IP4)
15774         print (vam->ofp,
15775                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15776                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15777                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15778                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15779                format_ip4_address, fp->next_hop);
15780       fp++;
15781     }
15782 }
15783
15784 static void vl_api_mpls_fib_details_t_handler_json
15785   (vl_api_mpls_fib_details_t * mp)
15786 {
15787   vat_main_t *vam = &vat_main;
15788   int count = ntohl (mp->count);
15789   vat_json_node_t *node = NULL;
15790   struct in_addr ip4;
15791   struct in6_addr ip6;
15792   vl_api_fib_path2_t *fp;
15793   int i;
15794
15795   if (VAT_JSON_ARRAY != vam->json_tree.type)
15796     {
15797       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15798       vat_json_init_array (&vam->json_tree);
15799     }
15800   node = vat_json_array_add (&vam->json_tree);
15801
15802   vat_json_init_object (node);
15803   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15804   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
15805   vat_json_object_add_uint (node, "label", ntohl (mp->label));
15806   vat_json_object_add_uint (node, "path_count", count);
15807   fp = mp->path;
15808   for (i = 0; i < count; i++)
15809     {
15810       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15811       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15812       vat_json_object_add_uint (node, "is_local", fp->is_local);
15813       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15814       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15815       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15816       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15817       if (fp->afi == IP46_TYPE_IP4)
15818         {
15819           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15820           vat_json_object_add_ip4 (node, "next_hop", ip4);
15821         }
15822       else if (fp->afi == IP46_TYPE_IP6)
15823         {
15824           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15825           vat_json_object_add_ip6 (node, "next_hop", ip6);
15826         }
15827     }
15828 }
15829
15830 static int
15831 api_mpls_fib_dump (vat_main_t * vam)
15832 {
15833   vl_api_mpls_fib_dump_t *mp;
15834   vl_api_control_ping_t *mp_ping;
15835   int ret;
15836
15837   M (MPLS_FIB_DUMP, mp);
15838   S (mp);
15839
15840   /* Use a control ping for synchronization */
15841   M (CONTROL_PING, mp_ping);
15842   S (mp_ping);
15843
15844   W (ret);
15845   return ret;
15846 }
15847
15848 #define vl_api_ip_fib_details_t_endian vl_noop_handler
15849 #define vl_api_ip_fib_details_t_print vl_noop_handler
15850
15851 static void
15852 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
15853 {
15854   vat_main_t *vam = &vat_main;
15855   int count = ntohl (mp->count);
15856   vl_api_fib_path_t *fp;
15857   int i;
15858
15859   print (vam->ofp,
15860          "table-id %d, prefix %U/%d",
15861          ntohl (mp->table_id), format_ip4_address, mp->address,
15862          mp->address_length);
15863   fp = mp->path;
15864   for (i = 0; i < count; i++)
15865     {
15866       if (fp->afi == IP46_TYPE_IP6)
15867         print (vam->ofp,
15868                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15869                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15870                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15871                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15872                format_ip6_address, fp->next_hop);
15873       else if (fp->afi == IP46_TYPE_IP4)
15874         print (vam->ofp,
15875                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15876                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15877                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15878                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15879                format_ip4_address, fp->next_hop);
15880       fp++;
15881     }
15882 }
15883
15884 static void vl_api_ip_fib_details_t_handler_json
15885   (vl_api_ip_fib_details_t * mp)
15886 {
15887   vat_main_t *vam = &vat_main;
15888   int count = ntohl (mp->count);
15889   vat_json_node_t *node = NULL;
15890   struct in_addr ip4;
15891   struct in6_addr ip6;
15892   vl_api_fib_path_t *fp;
15893   int i;
15894
15895   if (VAT_JSON_ARRAY != vam->json_tree.type)
15896     {
15897       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15898       vat_json_init_array (&vam->json_tree);
15899     }
15900   node = vat_json_array_add (&vam->json_tree);
15901
15902   vat_json_init_object (node);
15903   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15904   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
15905   vat_json_object_add_ip4 (node, "prefix", ip4);
15906   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15907   vat_json_object_add_uint (node, "path_count", count);
15908   fp = mp->path;
15909   for (i = 0; i < count; i++)
15910     {
15911       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15912       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15913       vat_json_object_add_uint (node, "is_local", fp->is_local);
15914       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15915       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15916       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15917       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15918       if (fp->afi == IP46_TYPE_IP4)
15919         {
15920           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15921           vat_json_object_add_ip4 (node, "next_hop", ip4);
15922         }
15923       else if (fp->afi == IP46_TYPE_IP6)
15924         {
15925           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15926           vat_json_object_add_ip6 (node, "next_hop", ip6);
15927         }
15928     }
15929 }
15930
15931 static int
15932 api_ip_fib_dump (vat_main_t * vam)
15933 {
15934   vl_api_ip_fib_dump_t *mp;
15935   vl_api_control_ping_t *mp_ping;
15936   int ret;
15937
15938   M (IP_FIB_DUMP, mp);
15939   S (mp);
15940
15941   /* Use a control ping for synchronization */
15942   M (CONTROL_PING, mp_ping);
15943   S (mp_ping);
15944
15945   W (ret);
15946   return ret;
15947 }
15948
15949 static int
15950 api_ip_mfib_dump (vat_main_t * vam)
15951 {
15952   vl_api_ip_mfib_dump_t *mp;
15953   vl_api_control_ping_t *mp_ping;
15954   int ret;
15955
15956   M (IP_MFIB_DUMP, mp);
15957   S (mp);
15958
15959   /* Use a control ping for synchronization */
15960   M (CONTROL_PING, mp_ping);
15961   S (mp_ping);
15962
15963   W (ret);
15964   return ret;
15965 }
15966
15967 static void vl_api_ip_neighbor_details_t_handler
15968   (vl_api_ip_neighbor_details_t * mp)
15969 {
15970   vat_main_t *vam = &vat_main;
15971
15972   print (vam->ofp, "%c %U %U",
15973          (mp->is_static) ? 'S' : 'D',
15974          format_ethernet_address, &mp->mac_address,
15975          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
15976          &mp->ip_address);
15977 }
15978
15979 static void vl_api_ip_neighbor_details_t_handler_json
15980   (vl_api_ip_neighbor_details_t * mp)
15981 {
15982
15983   vat_main_t *vam = &vat_main;
15984   vat_json_node_t *node;
15985   struct in_addr ip4;
15986   struct in6_addr ip6;
15987
15988   if (VAT_JSON_ARRAY != vam->json_tree.type)
15989     {
15990       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15991       vat_json_init_array (&vam->json_tree);
15992     }
15993   node = vat_json_array_add (&vam->json_tree);
15994
15995   vat_json_init_object (node);
15996   vat_json_object_add_string_copy (node, "flag",
15997                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
15998                                    "dynamic");
15999
16000   vat_json_object_add_string_copy (node, "link_layer",
16001                                    format (0, "%U", format_ethernet_address,
16002                                            &mp->mac_address));
16003
16004   if (mp->is_ipv6)
16005     {
16006       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
16007       vat_json_object_add_ip6 (node, "ip_address", ip6);
16008     }
16009   else
16010     {
16011       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
16012       vat_json_object_add_ip4 (node, "ip_address", ip4);
16013     }
16014 }
16015
16016 static int
16017 api_ip_neighbor_dump (vat_main_t * vam)
16018 {
16019   unformat_input_t *i = vam->input;
16020   vl_api_ip_neighbor_dump_t *mp;
16021   vl_api_control_ping_t *mp_ping;
16022   u8 is_ipv6 = 0;
16023   u32 sw_if_index = ~0;
16024   int ret;
16025
16026   /* Parse args required to build the message */
16027   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16028     {
16029       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16030         ;
16031       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16032         ;
16033       else if (unformat (i, "ip6"))
16034         is_ipv6 = 1;
16035       else
16036         break;
16037     }
16038
16039   if (sw_if_index == ~0)
16040     {
16041       errmsg ("missing interface name or sw_if_index");
16042       return -99;
16043     }
16044
16045   M (IP_NEIGHBOR_DUMP, mp);
16046   mp->is_ipv6 = (u8) is_ipv6;
16047   mp->sw_if_index = ntohl (sw_if_index);
16048   S (mp);
16049
16050   /* Use a control ping for synchronization */
16051   M (CONTROL_PING, mp_ping);
16052   S (mp_ping);
16053
16054   W (ret);
16055   return ret;
16056 }
16057
16058 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
16059 #define vl_api_ip6_fib_details_t_print vl_noop_handler
16060
16061 static void
16062 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
16063 {
16064   vat_main_t *vam = &vat_main;
16065   int count = ntohl (mp->count);
16066   vl_api_fib_path_t *fp;
16067   int i;
16068
16069   print (vam->ofp,
16070          "table-id %d, prefix %U/%d",
16071          ntohl (mp->table_id), format_ip6_address, mp->address,
16072          mp->address_length);
16073   fp = mp->path;
16074   for (i = 0; i < count; i++)
16075     {
16076       if (fp->afi == IP46_TYPE_IP6)
16077         print (vam->ofp,
16078                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16079                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16080                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16081                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16082                format_ip6_address, fp->next_hop);
16083       else if (fp->afi == IP46_TYPE_IP4)
16084         print (vam->ofp,
16085                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16086                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16087                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16088                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16089                format_ip4_address, fp->next_hop);
16090       fp++;
16091     }
16092 }
16093
16094 static void vl_api_ip6_fib_details_t_handler_json
16095   (vl_api_ip6_fib_details_t * mp)
16096 {
16097   vat_main_t *vam = &vat_main;
16098   int count = ntohl (mp->count);
16099   vat_json_node_t *node = NULL;
16100   struct in_addr ip4;
16101   struct in6_addr ip6;
16102   vl_api_fib_path_t *fp;
16103   int i;
16104
16105   if (VAT_JSON_ARRAY != vam->json_tree.type)
16106     {
16107       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16108       vat_json_init_array (&vam->json_tree);
16109     }
16110   node = vat_json_array_add (&vam->json_tree);
16111
16112   vat_json_init_object (node);
16113   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16114   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
16115   vat_json_object_add_ip6 (node, "prefix", ip6);
16116   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16117   vat_json_object_add_uint (node, "path_count", count);
16118   fp = mp->path;
16119   for (i = 0; i < count; i++)
16120     {
16121       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16122       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16123       vat_json_object_add_uint (node, "is_local", fp->is_local);
16124       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16125       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16126       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16127       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16128       if (fp->afi == IP46_TYPE_IP4)
16129         {
16130           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16131           vat_json_object_add_ip4 (node, "next_hop", ip4);
16132         }
16133       else if (fp->afi == IP46_TYPE_IP6)
16134         {
16135           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16136           vat_json_object_add_ip6 (node, "next_hop", ip6);
16137         }
16138     }
16139 }
16140
16141 static int
16142 api_ip6_fib_dump (vat_main_t * vam)
16143 {
16144   vl_api_ip6_fib_dump_t *mp;
16145   vl_api_control_ping_t *mp_ping;
16146   int ret;
16147
16148   M (IP6_FIB_DUMP, mp);
16149   S (mp);
16150
16151   /* Use a control ping for synchronization */
16152   M (CONTROL_PING, mp_ping);
16153   S (mp_ping);
16154
16155   W (ret);
16156   return ret;
16157 }
16158
16159 static int
16160 api_ip6_mfib_dump (vat_main_t * vam)
16161 {
16162   vl_api_ip6_mfib_dump_t *mp;
16163   vl_api_control_ping_t *mp_ping;
16164   int ret;
16165
16166   M (IP6_MFIB_DUMP, mp);
16167   S (mp);
16168
16169   /* Use a control ping for synchronization */
16170   M (CONTROL_PING, mp_ping);
16171   S (mp_ping);
16172
16173   W (ret);
16174   return ret;
16175 }
16176
16177 int
16178 api_classify_table_ids (vat_main_t * vam)
16179 {
16180   vl_api_classify_table_ids_t *mp;
16181   int ret;
16182
16183   /* Construct the API message */
16184   M (CLASSIFY_TABLE_IDS, mp);
16185   mp->context = 0;
16186
16187   S (mp);
16188   W (ret);
16189   return ret;
16190 }
16191
16192 int
16193 api_classify_table_by_interface (vat_main_t * vam)
16194 {
16195   unformat_input_t *input = vam->input;
16196   vl_api_classify_table_by_interface_t *mp;
16197
16198   u32 sw_if_index = ~0;
16199   int ret;
16200   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16201     {
16202       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16203         ;
16204       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16205         ;
16206       else
16207         break;
16208     }
16209   if (sw_if_index == ~0)
16210     {
16211       errmsg ("missing interface name or sw_if_index");
16212       return -99;
16213     }
16214
16215   /* Construct the API message */
16216   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
16217   mp->context = 0;
16218   mp->sw_if_index = ntohl (sw_if_index);
16219
16220   S (mp);
16221   W (ret);
16222   return ret;
16223 }
16224
16225 int
16226 api_classify_table_info (vat_main_t * vam)
16227 {
16228   unformat_input_t *input = vam->input;
16229   vl_api_classify_table_info_t *mp;
16230
16231   u32 table_id = ~0;
16232   int ret;
16233   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16234     {
16235       if (unformat (input, "table_id %d", &table_id))
16236         ;
16237       else
16238         break;
16239     }
16240   if (table_id == ~0)
16241     {
16242       errmsg ("missing table id");
16243       return -99;
16244     }
16245
16246   /* Construct the API message */
16247   M (CLASSIFY_TABLE_INFO, mp);
16248   mp->context = 0;
16249   mp->table_id = ntohl (table_id);
16250
16251   S (mp);
16252   W (ret);
16253   return ret;
16254 }
16255
16256 int
16257 api_classify_session_dump (vat_main_t * vam)
16258 {
16259   unformat_input_t *input = vam->input;
16260   vl_api_classify_session_dump_t *mp;
16261   vl_api_control_ping_t *mp_ping;
16262
16263   u32 table_id = ~0;
16264   int ret;
16265   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16266     {
16267       if (unformat (input, "table_id %d", &table_id))
16268         ;
16269       else
16270         break;
16271     }
16272   if (table_id == ~0)
16273     {
16274       errmsg ("missing table id");
16275       return -99;
16276     }
16277
16278   /* Construct the API message */
16279   M (CLASSIFY_SESSION_DUMP, mp);
16280   mp->context = 0;
16281   mp->table_id = ntohl (table_id);
16282   S (mp);
16283
16284   /* Use a control ping for synchronization */
16285   M (CONTROL_PING, mp_ping);
16286   S (mp_ping);
16287
16288   W (ret);
16289   return ret;
16290 }
16291
16292 static void
16293 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
16294 {
16295   vat_main_t *vam = &vat_main;
16296
16297   print (vam->ofp, "collector_address %U, collector_port %d, "
16298          "src_address %U, vrf_id %d, path_mtu %u, "
16299          "template_interval %u, udp_checksum %d",
16300          format_ip4_address, mp->collector_address,
16301          ntohs (mp->collector_port),
16302          format_ip4_address, mp->src_address,
16303          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
16304          ntohl (mp->template_interval), mp->udp_checksum);
16305
16306   vam->retval = 0;
16307   vam->result_ready = 1;
16308 }
16309
16310 static void
16311   vl_api_ipfix_exporter_details_t_handler_json
16312   (vl_api_ipfix_exporter_details_t * mp)
16313 {
16314   vat_main_t *vam = &vat_main;
16315   vat_json_node_t node;
16316   struct in_addr collector_address;
16317   struct in_addr src_address;
16318
16319   vat_json_init_object (&node);
16320   clib_memcpy (&collector_address, &mp->collector_address,
16321                sizeof (collector_address));
16322   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
16323   vat_json_object_add_uint (&node, "collector_port",
16324                             ntohs (mp->collector_port));
16325   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
16326   vat_json_object_add_ip4 (&node, "src_address", src_address);
16327   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
16328   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
16329   vat_json_object_add_uint (&node, "template_interval",
16330                             ntohl (mp->template_interval));
16331   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
16332
16333   vat_json_print (vam->ofp, &node);
16334   vat_json_free (&node);
16335   vam->retval = 0;
16336   vam->result_ready = 1;
16337 }
16338
16339 int
16340 api_ipfix_exporter_dump (vat_main_t * vam)
16341 {
16342   vl_api_ipfix_exporter_dump_t *mp;
16343   int ret;
16344
16345   /* Construct the API message */
16346   M (IPFIX_EXPORTER_DUMP, mp);
16347   mp->context = 0;
16348
16349   S (mp);
16350   W (ret);
16351   return ret;
16352 }
16353
16354 static int
16355 api_ipfix_classify_stream_dump (vat_main_t * vam)
16356 {
16357   vl_api_ipfix_classify_stream_dump_t *mp;
16358   int ret;
16359
16360   /* Construct the API message */
16361   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
16362   mp->context = 0;
16363
16364   S (mp);
16365   W (ret);
16366   return ret;
16367   /* NOTREACHED */
16368   return 0;
16369 }
16370
16371 static void
16372   vl_api_ipfix_classify_stream_details_t_handler
16373   (vl_api_ipfix_classify_stream_details_t * mp)
16374 {
16375   vat_main_t *vam = &vat_main;
16376   print (vam->ofp, "domain_id %d, src_port %d",
16377          ntohl (mp->domain_id), ntohs (mp->src_port));
16378   vam->retval = 0;
16379   vam->result_ready = 1;
16380 }
16381
16382 static void
16383   vl_api_ipfix_classify_stream_details_t_handler_json
16384   (vl_api_ipfix_classify_stream_details_t * mp)
16385 {
16386   vat_main_t *vam = &vat_main;
16387   vat_json_node_t node;
16388
16389   vat_json_init_object (&node);
16390   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
16391   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
16392
16393   vat_json_print (vam->ofp, &node);
16394   vat_json_free (&node);
16395   vam->retval = 0;
16396   vam->result_ready = 1;
16397 }
16398
16399 static int
16400 api_ipfix_classify_table_dump (vat_main_t * vam)
16401 {
16402   vl_api_ipfix_classify_table_dump_t *mp;
16403   vl_api_control_ping_t *mp_ping;
16404   int ret;
16405
16406   if (!vam->json_output)
16407     {
16408       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
16409              "transport_protocol");
16410     }
16411
16412   /* Construct the API message */
16413   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
16414
16415   /* send it... */
16416   S (mp);
16417
16418   /* Use a control ping for synchronization */
16419   M (CONTROL_PING, mp_ping);
16420   S (mp_ping);
16421
16422   W (ret);
16423   return ret;
16424 }
16425
16426 static void
16427   vl_api_ipfix_classify_table_details_t_handler
16428   (vl_api_ipfix_classify_table_details_t * mp)
16429 {
16430   vat_main_t *vam = &vat_main;
16431   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
16432          mp->transport_protocol);
16433 }
16434
16435 static void
16436   vl_api_ipfix_classify_table_details_t_handler_json
16437   (vl_api_ipfix_classify_table_details_t * mp)
16438 {
16439   vat_json_node_t *node = NULL;
16440   vat_main_t *vam = &vat_main;
16441
16442   if (VAT_JSON_ARRAY != vam->json_tree.type)
16443     {
16444       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16445       vat_json_init_array (&vam->json_tree);
16446     }
16447
16448   node = vat_json_array_add (&vam->json_tree);
16449   vat_json_init_object (node);
16450
16451   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
16452   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
16453   vat_json_object_add_uint (node, "transport_protocol",
16454                             mp->transport_protocol);
16455 }
16456
16457 static int
16458 api_sw_interface_span_enable_disable (vat_main_t * vam)
16459 {
16460   unformat_input_t *i = vam->input;
16461   vl_api_sw_interface_span_enable_disable_t *mp;
16462   u32 src_sw_if_index = ~0;
16463   u32 dst_sw_if_index = ~0;
16464   u8 state = 3;
16465   int ret;
16466
16467   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16468     {
16469       if (unformat
16470           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
16471         ;
16472       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
16473         ;
16474       else
16475         if (unformat
16476             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
16477         ;
16478       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
16479         ;
16480       else if (unformat (i, "disable"))
16481         state = 0;
16482       else if (unformat (i, "rx"))
16483         state = 1;
16484       else if (unformat (i, "tx"))
16485         state = 2;
16486       else if (unformat (i, "both"))
16487         state = 3;
16488       else
16489         break;
16490     }
16491
16492   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
16493
16494   mp->sw_if_index_from = htonl (src_sw_if_index);
16495   mp->sw_if_index_to = htonl (dst_sw_if_index);
16496   mp->state = state;
16497
16498   S (mp);
16499   W (ret);
16500   return ret;
16501 }
16502
16503 static void
16504 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
16505                                             * mp)
16506 {
16507   vat_main_t *vam = &vat_main;
16508   u8 *sw_if_from_name = 0;
16509   u8 *sw_if_to_name = 0;
16510   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16511   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16512   char *states[] = { "none", "rx", "tx", "both" };
16513   hash_pair_t *p;
16514
16515   /* *INDENT-OFF* */
16516   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16517   ({
16518     if ((u32) p->value[0] == sw_if_index_from)
16519       {
16520         sw_if_from_name = (u8 *)(p->key);
16521         if (sw_if_to_name)
16522           break;
16523       }
16524     if ((u32) p->value[0] == sw_if_index_to)
16525       {
16526         sw_if_to_name = (u8 *)(p->key);
16527         if (sw_if_from_name)
16528           break;
16529       }
16530   }));
16531   /* *INDENT-ON* */
16532   print (vam->ofp, "%20s => %20s (%s)",
16533          sw_if_from_name, sw_if_to_name, states[mp->state]);
16534 }
16535
16536 static void
16537   vl_api_sw_interface_span_details_t_handler_json
16538   (vl_api_sw_interface_span_details_t * mp)
16539 {
16540   vat_main_t *vam = &vat_main;
16541   vat_json_node_t *node = NULL;
16542   u8 *sw_if_from_name = 0;
16543   u8 *sw_if_to_name = 0;
16544   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16545   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16546   hash_pair_t *p;
16547
16548   /* *INDENT-OFF* */
16549   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16550   ({
16551     if ((u32) p->value[0] == sw_if_index_from)
16552       {
16553         sw_if_from_name = (u8 *)(p->key);
16554         if (sw_if_to_name)
16555           break;
16556       }
16557     if ((u32) p->value[0] == sw_if_index_to)
16558       {
16559         sw_if_to_name = (u8 *)(p->key);
16560         if (sw_if_from_name)
16561           break;
16562       }
16563   }));
16564   /* *INDENT-ON* */
16565
16566   if (VAT_JSON_ARRAY != vam->json_tree.type)
16567     {
16568       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16569       vat_json_init_array (&vam->json_tree);
16570     }
16571   node = vat_json_array_add (&vam->json_tree);
16572
16573   vat_json_init_object (node);
16574   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
16575   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
16576   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
16577   if (0 != sw_if_to_name)
16578     {
16579       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
16580     }
16581   vat_json_object_add_uint (node, "state", mp->state);
16582 }
16583
16584 static int
16585 api_sw_interface_span_dump (vat_main_t * vam)
16586 {
16587   vl_api_sw_interface_span_dump_t *mp;
16588   vl_api_control_ping_t *mp_ping;
16589   int ret;
16590
16591   M (SW_INTERFACE_SPAN_DUMP, mp);
16592   S (mp);
16593
16594   /* Use a control ping for synchronization */
16595   M (CONTROL_PING, mp_ping);
16596   S (mp_ping);
16597
16598   W (ret);
16599   return ret;
16600 }
16601
16602 int
16603 api_pg_create_interface (vat_main_t * vam)
16604 {
16605   unformat_input_t *input = vam->input;
16606   vl_api_pg_create_interface_t *mp;
16607
16608   u32 if_id = ~0;
16609   int ret;
16610   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16611     {
16612       if (unformat (input, "if_id %d", &if_id))
16613         ;
16614       else
16615         break;
16616     }
16617   if (if_id == ~0)
16618     {
16619       errmsg ("missing pg interface index");
16620       return -99;
16621     }
16622
16623   /* Construct the API message */
16624   M (PG_CREATE_INTERFACE, mp);
16625   mp->context = 0;
16626   mp->interface_id = ntohl (if_id);
16627
16628   S (mp);
16629   W (ret);
16630   return ret;
16631 }
16632
16633 int
16634 api_pg_capture (vat_main_t * vam)
16635 {
16636   unformat_input_t *input = vam->input;
16637   vl_api_pg_capture_t *mp;
16638
16639   u32 if_id = ~0;
16640   u8 enable = 1;
16641   u32 count = 1;
16642   u8 pcap_file_set = 0;
16643   u8 *pcap_file = 0;
16644   int ret;
16645   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16646     {
16647       if (unformat (input, "if_id %d", &if_id))
16648         ;
16649       else if (unformat (input, "pcap %s", &pcap_file))
16650         pcap_file_set = 1;
16651       else if (unformat (input, "count %d", &count))
16652         ;
16653       else if (unformat (input, "disable"))
16654         enable = 0;
16655       else
16656         break;
16657     }
16658   if (if_id == ~0)
16659     {
16660       errmsg ("missing pg interface index");
16661       return -99;
16662     }
16663   if (pcap_file_set > 0)
16664     {
16665       if (vec_len (pcap_file) > 255)
16666         {
16667           errmsg ("pcap file name is too long");
16668           return -99;
16669         }
16670     }
16671
16672   u32 name_len = vec_len (pcap_file);
16673   /* Construct the API message */
16674   M (PG_CAPTURE, mp);
16675   mp->context = 0;
16676   mp->interface_id = ntohl (if_id);
16677   mp->is_enabled = enable;
16678   mp->count = ntohl (count);
16679   mp->pcap_name_length = ntohl (name_len);
16680   if (pcap_file_set != 0)
16681     {
16682       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
16683     }
16684   vec_free (pcap_file);
16685
16686   S (mp);
16687   W (ret);
16688   return ret;
16689 }
16690
16691 int
16692 api_pg_enable_disable (vat_main_t * vam)
16693 {
16694   unformat_input_t *input = vam->input;
16695   vl_api_pg_enable_disable_t *mp;
16696
16697   u8 enable = 1;
16698   u8 stream_name_set = 0;
16699   u8 *stream_name = 0;
16700   int ret;
16701   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16702     {
16703       if (unformat (input, "stream %s", &stream_name))
16704         stream_name_set = 1;
16705       else if (unformat (input, "disable"))
16706         enable = 0;
16707       else
16708         break;
16709     }
16710
16711   if (stream_name_set > 0)
16712     {
16713       if (vec_len (stream_name) > 255)
16714         {
16715           errmsg ("stream name too long");
16716           return -99;
16717         }
16718     }
16719
16720   u32 name_len = vec_len (stream_name);
16721   /* Construct the API message */
16722   M (PG_ENABLE_DISABLE, mp);
16723   mp->context = 0;
16724   mp->is_enabled = enable;
16725   if (stream_name_set != 0)
16726     {
16727       mp->stream_name_length = ntohl (name_len);
16728       clib_memcpy (mp->stream_name, stream_name, name_len);
16729     }
16730   vec_free (stream_name);
16731
16732   S (mp);
16733   W (ret);
16734   return ret;
16735 }
16736
16737 int
16738 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
16739 {
16740   unformat_input_t *input = vam->input;
16741   vl_api_ip_source_and_port_range_check_add_del_t *mp;
16742
16743   u16 *low_ports = 0;
16744   u16 *high_ports = 0;
16745   u16 this_low;
16746   u16 this_hi;
16747   ip4_address_t ip4_addr;
16748   ip6_address_t ip6_addr;
16749   u32 length;
16750   u32 tmp, tmp2;
16751   u8 prefix_set = 0;
16752   u32 vrf_id = ~0;
16753   u8 is_add = 1;
16754   u8 is_ipv6 = 0;
16755   int ret;
16756
16757   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16758     {
16759       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
16760         {
16761           prefix_set = 1;
16762         }
16763       else
16764         if (unformat
16765             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
16766         {
16767           prefix_set = 1;
16768           is_ipv6 = 1;
16769         }
16770       else if (unformat (input, "vrf %d", &vrf_id))
16771         ;
16772       else if (unformat (input, "del"))
16773         is_add = 0;
16774       else if (unformat (input, "port %d", &tmp))
16775         {
16776           if (tmp == 0 || tmp > 65535)
16777             {
16778               errmsg ("port %d out of range", tmp);
16779               return -99;
16780             }
16781           this_low = tmp;
16782           this_hi = this_low + 1;
16783           vec_add1 (low_ports, this_low);
16784           vec_add1 (high_ports, this_hi);
16785         }
16786       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
16787         {
16788           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
16789             {
16790               errmsg ("incorrect range parameters");
16791               return -99;
16792             }
16793           this_low = tmp;
16794           /* Note: in debug CLI +1 is added to high before
16795              passing to real fn that does "the work"
16796              (ip_source_and_port_range_check_add_del).
16797              This fn is a wrapper around the binary API fn a
16798              control plane will call, which expects this increment
16799              to have occurred. Hence letting the binary API control
16800              plane fn do the increment for consistency between VAT
16801              and other control planes.
16802            */
16803           this_hi = tmp2;
16804           vec_add1 (low_ports, this_low);
16805           vec_add1 (high_ports, this_hi);
16806         }
16807       else
16808         break;
16809     }
16810
16811   if (prefix_set == 0)
16812     {
16813       errmsg ("<address>/<mask> not specified");
16814       return -99;
16815     }
16816
16817   if (vrf_id == ~0)
16818     {
16819       errmsg ("VRF ID required, not specified");
16820       return -99;
16821     }
16822
16823   if (vrf_id == 0)
16824     {
16825       errmsg
16826         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
16827       return -99;
16828     }
16829
16830   if (vec_len (low_ports) == 0)
16831     {
16832       errmsg ("At least one port or port range required");
16833       return -99;
16834     }
16835
16836   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
16837
16838   mp->is_add = is_add;
16839
16840   if (is_ipv6)
16841     {
16842       mp->is_ipv6 = 1;
16843       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
16844     }
16845   else
16846     {
16847       mp->is_ipv6 = 0;
16848       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
16849     }
16850
16851   mp->mask_length = length;
16852   mp->number_of_ranges = vec_len (low_ports);
16853
16854   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
16855   vec_free (low_ports);
16856
16857   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
16858   vec_free (high_ports);
16859
16860   mp->vrf_id = ntohl (vrf_id);
16861
16862   S (mp);
16863   W (ret);
16864   return ret;
16865 }
16866
16867 int
16868 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
16869 {
16870   unformat_input_t *input = vam->input;
16871   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
16872   u32 sw_if_index = ~0;
16873   int vrf_set = 0;
16874   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
16875   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
16876   u8 is_add = 1;
16877   int ret;
16878
16879   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16880     {
16881       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16882         ;
16883       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16884         ;
16885       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
16886         vrf_set = 1;
16887       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
16888         vrf_set = 1;
16889       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
16890         vrf_set = 1;
16891       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
16892         vrf_set = 1;
16893       else if (unformat (input, "del"))
16894         is_add = 0;
16895       else
16896         break;
16897     }
16898
16899   if (sw_if_index == ~0)
16900     {
16901       errmsg ("Interface required but not specified");
16902       return -99;
16903     }
16904
16905   if (vrf_set == 0)
16906     {
16907       errmsg ("VRF ID required but not specified");
16908       return -99;
16909     }
16910
16911   if (tcp_out_vrf_id == 0
16912       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
16913     {
16914       errmsg
16915         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
16916       return -99;
16917     }
16918
16919   /* Construct the API message */
16920   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
16921
16922   mp->sw_if_index = ntohl (sw_if_index);
16923   mp->is_add = is_add;
16924   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
16925   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
16926   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
16927   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
16928
16929   /* send it... */
16930   S (mp);
16931
16932   /* Wait for a reply... */
16933   W (ret);
16934   return ret;
16935 }
16936
16937 static int
16938 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
16939 {
16940   unformat_input_t *i = vam->input;
16941   vl_api_ipsec_gre_add_del_tunnel_t *mp;
16942   u32 local_sa_id = 0;
16943   u32 remote_sa_id = 0;
16944   ip4_address_t src_address;
16945   ip4_address_t dst_address;
16946   u8 is_add = 1;
16947   int ret;
16948
16949   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16950     {
16951       if (unformat (i, "local_sa %d", &local_sa_id))
16952         ;
16953       else if (unformat (i, "remote_sa %d", &remote_sa_id))
16954         ;
16955       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
16956         ;
16957       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
16958         ;
16959       else if (unformat (i, "del"))
16960         is_add = 0;
16961       else
16962         {
16963           clib_warning ("parse error '%U'", format_unformat_error, i);
16964           return -99;
16965         }
16966     }
16967
16968   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
16969
16970   mp->local_sa_id = ntohl (local_sa_id);
16971   mp->remote_sa_id = ntohl (remote_sa_id);
16972   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
16973   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
16974   mp->is_add = is_add;
16975
16976   S (mp);
16977   W (ret);
16978   return ret;
16979 }
16980
16981 static int
16982 api_punt (vat_main_t * vam)
16983 {
16984   unformat_input_t *i = vam->input;
16985   vl_api_punt_t *mp;
16986   u32 ipv = ~0;
16987   u32 protocol = ~0;
16988   u32 port = ~0;
16989   int is_add = 1;
16990   int ret;
16991
16992   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16993     {
16994       if (unformat (i, "ip %d", &ipv))
16995         ;
16996       else if (unformat (i, "protocol %d", &protocol))
16997         ;
16998       else if (unformat (i, "port %d", &port))
16999         ;
17000       else if (unformat (i, "del"))
17001         is_add = 0;
17002       else
17003         {
17004           clib_warning ("parse error '%U'", format_unformat_error, i);
17005           return -99;
17006         }
17007     }
17008
17009   M (PUNT, mp);
17010
17011   mp->is_add = (u8) is_add;
17012   mp->ipv = (u8) ipv;
17013   mp->l4_protocol = (u8) protocol;
17014   mp->l4_port = htons ((u16) port);
17015
17016   S (mp);
17017   W (ret);
17018   return ret;
17019 }
17020
17021 static void vl_api_ipsec_gre_tunnel_details_t_handler
17022   (vl_api_ipsec_gre_tunnel_details_t * mp)
17023 {
17024   vat_main_t *vam = &vat_main;
17025
17026   print (vam->ofp, "%11d%15U%15U%14d%14d",
17027          ntohl (mp->sw_if_index),
17028          format_ip4_address, &mp->src_address,
17029          format_ip4_address, &mp->dst_address,
17030          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
17031 }
17032
17033 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
17034   (vl_api_ipsec_gre_tunnel_details_t * mp)
17035 {
17036   vat_main_t *vam = &vat_main;
17037   vat_json_node_t *node = NULL;
17038   struct in_addr ip4;
17039
17040   if (VAT_JSON_ARRAY != vam->json_tree.type)
17041     {
17042       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17043       vat_json_init_array (&vam->json_tree);
17044     }
17045   node = vat_json_array_add (&vam->json_tree);
17046
17047   vat_json_init_object (node);
17048   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17049   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
17050   vat_json_object_add_ip4 (node, "src_address", ip4);
17051   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
17052   vat_json_object_add_ip4 (node, "dst_address", ip4);
17053   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
17054   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
17055 }
17056
17057 static int
17058 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
17059 {
17060   unformat_input_t *i = vam->input;
17061   vl_api_ipsec_gre_tunnel_dump_t *mp;
17062   vl_api_control_ping_t *mp_ping;
17063   u32 sw_if_index;
17064   u8 sw_if_index_set = 0;
17065   int ret;
17066
17067   /* Parse args required to build the message */
17068   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17069     {
17070       if (unformat (i, "sw_if_index %d", &sw_if_index))
17071         sw_if_index_set = 1;
17072       else
17073         break;
17074     }
17075
17076   if (sw_if_index_set == 0)
17077     {
17078       sw_if_index = ~0;
17079     }
17080
17081   if (!vam->json_output)
17082     {
17083       print (vam->ofp, "%11s%15s%15s%14s%14s",
17084              "sw_if_index", "src_address", "dst_address",
17085              "local_sa_id", "remote_sa_id");
17086     }
17087
17088   /* Get list of gre-tunnel interfaces */
17089   M (IPSEC_GRE_TUNNEL_DUMP, mp);
17090
17091   mp->sw_if_index = htonl (sw_if_index);
17092
17093   S (mp);
17094
17095   /* Use a control ping for synchronization */
17096   M (CONTROL_PING, mp_ping);
17097   S (mp_ping);
17098
17099   W (ret);
17100   return ret;
17101 }
17102
17103 static int
17104 api_delete_subif (vat_main_t * vam)
17105 {
17106   unformat_input_t *i = vam->input;
17107   vl_api_delete_subif_t *mp;
17108   u32 sw_if_index = ~0;
17109   int ret;
17110
17111   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17112     {
17113       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17114         ;
17115       if (unformat (i, "sw_if_index %d", &sw_if_index))
17116         ;
17117       else
17118         break;
17119     }
17120
17121   if (sw_if_index == ~0)
17122     {
17123       errmsg ("missing sw_if_index");
17124       return -99;
17125     }
17126
17127   /* Construct the API message */
17128   M (DELETE_SUBIF, mp);
17129   mp->sw_if_index = ntohl (sw_if_index);
17130
17131   S (mp);
17132   W (ret);
17133   return ret;
17134 }
17135
17136 #define foreach_pbb_vtr_op      \
17137 _("disable",  L2_VTR_DISABLED)  \
17138 _("pop",  L2_VTR_POP_2)         \
17139 _("push",  L2_VTR_PUSH_2)
17140
17141 static int
17142 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
17143 {
17144   unformat_input_t *i = vam->input;
17145   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
17146   u32 sw_if_index = ~0, vtr_op = ~0;
17147   u16 outer_tag = ~0;
17148   u8 dmac[6], smac[6];
17149   u8 dmac_set = 0, smac_set = 0;
17150   u16 vlanid = 0;
17151   u32 sid = ~0;
17152   u32 tmp;
17153   int ret;
17154
17155   /* Shut up coverity */
17156   memset (dmac, 0, sizeof (dmac));
17157   memset (smac, 0, sizeof (smac));
17158
17159   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17160     {
17161       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17162         ;
17163       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17164         ;
17165       else if (unformat (i, "vtr_op %d", &vtr_op))
17166         ;
17167 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
17168       foreach_pbb_vtr_op
17169 #undef _
17170         else if (unformat (i, "translate_pbb_stag"))
17171         {
17172           if (unformat (i, "%d", &tmp))
17173             {
17174               vtr_op = L2_VTR_TRANSLATE_2_1;
17175               outer_tag = tmp;
17176             }
17177           else
17178             {
17179               errmsg
17180                 ("translate_pbb_stag operation requires outer tag definition");
17181               return -99;
17182             }
17183         }
17184       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
17185         dmac_set++;
17186       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
17187         smac_set++;
17188       else if (unformat (i, "sid %d", &sid))
17189         ;
17190       else if (unformat (i, "vlanid %d", &tmp))
17191         vlanid = tmp;
17192       else
17193         {
17194           clib_warning ("parse error '%U'", format_unformat_error, i);
17195           return -99;
17196         }
17197     }
17198
17199   if ((sw_if_index == ~0) || (vtr_op == ~0))
17200     {
17201       errmsg ("missing sw_if_index or vtr operation");
17202       return -99;
17203     }
17204   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
17205       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
17206     {
17207       errmsg
17208         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
17209       return -99;
17210     }
17211
17212   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
17213   mp->sw_if_index = ntohl (sw_if_index);
17214   mp->vtr_op = ntohl (vtr_op);
17215   mp->outer_tag = ntohs (outer_tag);
17216   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
17217   clib_memcpy (mp->b_smac, smac, sizeof (smac));
17218   mp->b_vlanid = ntohs (vlanid);
17219   mp->i_sid = ntohl (sid);
17220
17221   S (mp);
17222   W (ret);
17223   return ret;
17224 }
17225
17226 static int
17227 api_flow_classify_set_interface (vat_main_t * vam)
17228 {
17229   unformat_input_t *i = vam->input;
17230   vl_api_flow_classify_set_interface_t *mp;
17231   u32 sw_if_index;
17232   int sw_if_index_set;
17233   u32 ip4_table_index = ~0;
17234   u32 ip6_table_index = ~0;
17235   u8 is_add = 1;
17236   int ret;
17237
17238   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17239     {
17240       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17241         sw_if_index_set = 1;
17242       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17243         sw_if_index_set = 1;
17244       else if (unformat (i, "del"))
17245         is_add = 0;
17246       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17247         ;
17248       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17249         ;
17250       else
17251         {
17252           clib_warning ("parse error '%U'", format_unformat_error, i);
17253           return -99;
17254         }
17255     }
17256
17257   if (sw_if_index_set == 0)
17258     {
17259       errmsg ("missing interface name or sw_if_index");
17260       return -99;
17261     }
17262
17263   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
17264
17265   mp->sw_if_index = ntohl (sw_if_index);
17266   mp->ip4_table_index = ntohl (ip4_table_index);
17267   mp->ip6_table_index = ntohl (ip6_table_index);
17268   mp->is_add = is_add;
17269
17270   S (mp);
17271   W (ret);
17272   return ret;
17273 }
17274
17275 static int
17276 api_flow_classify_dump (vat_main_t * vam)
17277 {
17278   unformat_input_t *i = vam->input;
17279   vl_api_flow_classify_dump_t *mp;
17280   vl_api_control_ping_t *mp_ping;
17281   u8 type = FLOW_CLASSIFY_N_TABLES;
17282   int ret;
17283
17284   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
17285     ;
17286   else
17287     {
17288       errmsg ("classify table type must be specified");
17289       return -99;
17290     }
17291
17292   if (!vam->json_output)
17293     {
17294       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17295     }
17296
17297   M (FLOW_CLASSIFY_DUMP, mp);
17298   mp->type = type;
17299   /* send it... */
17300   S (mp);
17301
17302   /* Use a control ping for synchronization */
17303   M (CONTROL_PING, mp_ping);
17304   S (mp_ping);
17305
17306   /* Wait for a reply... */
17307   W (ret);
17308   return ret;
17309 }
17310
17311 static int
17312 api_feature_enable_disable (vat_main_t * vam)
17313 {
17314   unformat_input_t *i = vam->input;
17315   vl_api_feature_enable_disable_t *mp;
17316   u8 *arc_name = 0;
17317   u8 *feature_name = 0;
17318   u32 sw_if_index = ~0;
17319   u8 enable = 1;
17320   int ret;
17321
17322   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17323     {
17324       if (unformat (i, "arc_name %s", &arc_name))
17325         ;
17326       else if (unformat (i, "feature_name %s", &feature_name))
17327         ;
17328       else
17329         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17330         ;
17331       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17332         ;
17333       else if (unformat (i, "disable"))
17334         enable = 0;
17335       else
17336         break;
17337     }
17338
17339   if (arc_name == 0)
17340     {
17341       errmsg ("missing arc name");
17342       return -99;
17343     }
17344   if (vec_len (arc_name) > 63)
17345     {
17346       errmsg ("arc name too long");
17347     }
17348
17349   if (feature_name == 0)
17350     {
17351       errmsg ("missing feature name");
17352       return -99;
17353     }
17354   if (vec_len (feature_name) > 63)
17355     {
17356       errmsg ("feature name too long");
17357     }
17358
17359   if (sw_if_index == ~0)
17360     {
17361       errmsg ("missing interface name or sw_if_index");
17362       return -99;
17363     }
17364
17365   /* Construct the API message */
17366   M (FEATURE_ENABLE_DISABLE, mp);
17367   mp->sw_if_index = ntohl (sw_if_index);
17368   mp->enable = enable;
17369   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
17370   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
17371   vec_free (arc_name);
17372   vec_free (feature_name);
17373
17374   S (mp);
17375   W (ret);
17376   return ret;
17377 }
17378
17379 static int
17380 api_sw_interface_tag_add_del (vat_main_t * vam)
17381 {
17382   unformat_input_t *i = vam->input;
17383   vl_api_sw_interface_tag_add_del_t *mp;
17384   u32 sw_if_index = ~0;
17385   u8 *tag = 0;
17386   u8 enable = 1;
17387   int ret;
17388
17389   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17390     {
17391       if (unformat (i, "tag %s", &tag))
17392         ;
17393       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17394         ;
17395       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17396         ;
17397       else if (unformat (i, "del"))
17398         enable = 0;
17399       else
17400         break;
17401     }
17402
17403   if (sw_if_index == ~0)
17404     {
17405       errmsg ("missing interface name or sw_if_index");
17406       return -99;
17407     }
17408
17409   if (enable && (tag == 0))
17410     {
17411       errmsg ("no tag specified");
17412       return -99;
17413     }
17414
17415   /* Construct the API message */
17416   M (SW_INTERFACE_TAG_ADD_DEL, mp);
17417   mp->sw_if_index = ntohl (sw_if_index);
17418   mp->is_add = enable;
17419   if (enable)
17420     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
17421   vec_free (tag);
17422
17423   S (mp);
17424   W (ret);
17425   return ret;
17426 }
17427
17428 static void vl_api_l2_xconnect_details_t_handler
17429   (vl_api_l2_xconnect_details_t * mp)
17430 {
17431   vat_main_t *vam = &vat_main;
17432
17433   print (vam->ofp, "%15d%15d",
17434          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
17435 }
17436
17437 static void vl_api_l2_xconnect_details_t_handler_json
17438   (vl_api_l2_xconnect_details_t * mp)
17439 {
17440   vat_main_t *vam = &vat_main;
17441   vat_json_node_t *node = NULL;
17442
17443   if (VAT_JSON_ARRAY != vam->json_tree.type)
17444     {
17445       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17446       vat_json_init_array (&vam->json_tree);
17447     }
17448   node = vat_json_array_add (&vam->json_tree);
17449
17450   vat_json_init_object (node);
17451   vat_json_object_add_uint (node, "rx_sw_if_index",
17452                             ntohl (mp->rx_sw_if_index));
17453   vat_json_object_add_uint (node, "tx_sw_if_index",
17454                             ntohl (mp->tx_sw_if_index));
17455 }
17456
17457 static int
17458 api_l2_xconnect_dump (vat_main_t * vam)
17459 {
17460   vl_api_l2_xconnect_dump_t *mp;
17461   vl_api_control_ping_t *mp_ping;
17462   int ret;
17463
17464   if (!vam->json_output)
17465     {
17466       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
17467     }
17468
17469   M (L2_XCONNECT_DUMP, mp);
17470
17471   S (mp);
17472
17473   /* Use a control ping for synchronization */
17474   M (CONTROL_PING, mp_ping);
17475   S (mp_ping);
17476
17477   W (ret);
17478   return ret;
17479 }
17480
17481 static int
17482 api_sw_interface_set_mtu (vat_main_t * vam)
17483 {
17484   unformat_input_t *i = vam->input;
17485   vl_api_sw_interface_set_mtu_t *mp;
17486   u32 sw_if_index = ~0;
17487   u32 mtu = 0;
17488   int ret;
17489
17490   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17491     {
17492       if (unformat (i, "mtu %d", &mtu))
17493         ;
17494       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17495         ;
17496       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17497         ;
17498       else
17499         break;
17500     }
17501
17502   if (sw_if_index == ~0)
17503     {
17504       errmsg ("missing interface name or sw_if_index");
17505       return -99;
17506     }
17507
17508   if (mtu == 0)
17509     {
17510       errmsg ("no mtu specified");
17511       return -99;
17512     }
17513
17514   /* Construct the API message */
17515   M (SW_INTERFACE_SET_MTU, mp);
17516   mp->sw_if_index = ntohl (sw_if_index);
17517   mp->mtu = ntohs ((u16) mtu);
17518
17519   S (mp);
17520   W (ret);
17521   return ret;
17522 }
17523
17524
17525 static int
17526 q_or_quit (vat_main_t * vam)
17527 {
17528 #if VPP_API_TEST_BUILTIN == 0
17529   longjmp (vam->jump_buf, 1);
17530 #endif
17531   return 0;                     /* not so much */
17532 }
17533
17534 static int
17535 q (vat_main_t * vam)
17536 {
17537   return q_or_quit (vam);
17538 }
17539
17540 static int
17541 quit (vat_main_t * vam)
17542 {
17543   return q_or_quit (vam);
17544 }
17545
17546 static int
17547 comment (vat_main_t * vam)
17548 {
17549   return 0;
17550 }
17551
17552 static int
17553 cmd_cmp (void *a1, void *a2)
17554 {
17555   u8 **c1 = a1;
17556   u8 **c2 = a2;
17557
17558   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
17559 }
17560
17561 static int
17562 help (vat_main_t * vam)
17563 {
17564   u8 **cmds = 0;
17565   u8 *name = 0;
17566   hash_pair_t *p;
17567   unformat_input_t *i = vam->input;
17568   int j;
17569
17570   if (unformat (i, "%s", &name))
17571     {
17572       uword *hs;
17573
17574       vec_add1 (name, 0);
17575
17576       hs = hash_get_mem (vam->help_by_name, name);
17577       if (hs)
17578         print (vam->ofp, "usage: %s %s", name, hs[0]);
17579       else
17580         print (vam->ofp, "No such msg / command '%s'", name);
17581       vec_free (name);
17582       return 0;
17583     }
17584
17585   print (vam->ofp, "Help is available for the following:");
17586
17587     /* *INDENT-OFF* */
17588     hash_foreach_pair (p, vam->function_by_name,
17589     ({
17590       vec_add1 (cmds, (u8 *)(p->key));
17591     }));
17592     /* *INDENT-ON* */
17593
17594   vec_sort_with_function (cmds, cmd_cmp);
17595
17596   for (j = 0; j < vec_len (cmds); j++)
17597     print (vam->ofp, "%s", cmds[j]);
17598
17599   vec_free (cmds);
17600   return 0;
17601 }
17602
17603 static int
17604 set (vat_main_t * vam)
17605 {
17606   u8 *name = 0, *value = 0;
17607   unformat_input_t *i = vam->input;
17608
17609   if (unformat (i, "%s", &name))
17610     {
17611       /* The input buffer is a vector, not a string. */
17612       value = vec_dup (i->buffer);
17613       vec_delete (value, i->index, 0);
17614       /* Almost certainly has a trailing newline */
17615       if (value[vec_len (value) - 1] == '\n')
17616         value[vec_len (value) - 1] = 0;
17617       /* Make sure it's a proper string, one way or the other */
17618       vec_add1 (value, 0);
17619       (void) clib_macro_set_value (&vam->macro_main,
17620                                    (char *) name, (char *) value);
17621     }
17622   else
17623     errmsg ("usage: set <name> <value>");
17624
17625   vec_free (name);
17626   vec_free (value);
17627   return 0;
17628 }
17629
17630 static int
17631 unset (vat_main_t * vam)
17632 {
17633   u8 *name = 0;
17634
17635   if (unformat (vam->input, "%s", &name))
17636     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
17637       errmsg ("unset: %s wasn't set", name);
17638   vec_free (name);
17639   return 0;
17640 }
17641
17642 typedef struct
17643 {
17644   u8 *name;
17645   u8 *value;
17646 } macro_sort_t;
17647
17648
17649 static int
17650 macro_sort_cmp (void *a1, void *a2)
17651 {
17652   macro_sort_t *s1 = a1;
17653   macro_sort_t *s2 = a2;
17654
17655   return strcmp ((char *) (s1->name), (char *) (s2->name));
17656 }
17657
17658 static int
17659 dump_macro_table (vat_main_t * vam)
17660 {
17661   macro_sort_t *sort_me = 0, *sm;
17662   int i;
17663   hash_pair_t *p;
17664
17665     /* *INDENT-OFF* */
17666     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
17667     ({
17668       vec_add2 (sort_me, sm, 1);
17669       sm->name = (u8 *)(p->key);
17670       sm->value = (u8 *) (p->value[0]);
17671     }));
17672     /* *INDENT-ON* */
17673
17674   vec_sort_with_function (sort_me, macro_sort_cmp);
17675
17676   if (vec_len (sort_me))
17677     print (vam->ofp, "%-15s%s", "Name", "Value");
17678   else
17679     print (vam->ofp, "The macro table is empty...");
17680
17681   for (i = 0; i < vec_len (sort_me); i++)
17682     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
17683   return 0;
17684 }
17685
17686 static int
17687 dump_node_table (vat_main_t * vam)
17688 {
17689   int i, j;
17690   vlib_node_t *node, *next_node;
17691
17692   if (vec_len (vam->graph_nodes) == 0)
17693     {
17694       print (vam->ofp, "Node table empty, issue get_node_graph...");
17695       return 0;
17696     }
17697
17698   for (i = 0; i < vec_len (vam->graph_nodes); i++)
17699     {
17700       node = vam->graph_nodes[i];
17701       print (vam->ofp, "[%d] %s", i, node->name);
17702       for (j = 0; j < vec_len (node->next_nodes); j++)
17703         {
17704           if (node->next_nodes[j] != ~0)
17705             {
17706               next_node = vam->graph_nodes[node->next_nodes[j]];
17707               print (vam->ofp, "  [%d] %s", j, next_node->name);
17708             }
17709         }
17710     }
17711   return 0;
17712 }
17713
17714 static int
17715 value_sort_cmp (void *a1, void *a2)
17716 {
17717   name_sort_t *n1 = a1;
17718   name_sort_t *n2 = a2;
17719
17720   if (n1->value < n2->value)
17721     return -1;
17722   if (n1->value > n2->value)
17723     return 1;
17724   return 0;
17725 }
17726
17727
17728 static int
17729 dump_msg_api_table (vat_main_t * vam)
17730 {
17731   api_main_t *am = &api_main;
17732   name_sort_t *nses = 0, *ns;
17733   hash_pair_t *hp;
17734   int i;
17735
17736   /* *INDENT-OFF* */
17737   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
17738   ({
17739     vec_add2 (nses, ns, 1);
17740     ns->name = (u8 *)(hp->key);
17741     ns->value = (u32) hp->value[0];
17742   }));
17743   /* *INDENT-ON* */
17744
17745   vec_sort_with_function (nses, value_sort_cmp);
17746
17747   for (i = 0; i < vec_len (nses); i++)
17748     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
17749   vec_free (nses);
17750   return 0;
17751 }
17752
17753 static int
17754 get_msg_id (vat_main_t * vam)
17755 {
17756   u8 *name_and_crc;
17757   u32 message_index;
17758
17759   if (unformat (vam->input, "%s", &name_and_crc))
17760     {
17761       message_index = vl_api_get_msg_index (name_and_crc);
17762       if (message_index == ~0)
17763         {
17764           print (vam->ofp, " '%s' not found", name_and_crc);
17765           return 0;
17766         }
17767       print (vam->ofp, " '%s' has message index %d",
17768              name_and_crc, message_index);
17769       return 0;
17770     }
17771   errmsg ("name_and_crc required...");
17772   return 0;
17773 }
17774
17775 static int
17776 search_node_table (vat_main_t * vam)
17777 {
17778   unformat_input_t *line_input = vam->input;
17779   u8 *node_to_find;
17780   int j;
17781   vlib_node_t *node, *next_node;
17782   uword *p;
17783
17784   if (vam->graph_node_index_by_name == 0)
17785     {
17786       print (vam->ofp, "Node table empty, issue get_node_graph...");
17787       return 0;
17788     }
17789
17790   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
17791     {
17792       if (unformat (line_input, "%s", &node_to_find))
17793         {
17794           vec_add1 (node_to_find, 0);
17795           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
17796           if (p == 0)
17797             {
17798               print (vam->ofp, "%s not found...", node_to_find);
17799               goto out;
17800             }
17801           node = vam->graph_nodes[p[0]];
17802           print (vam->ofp, "[%d] %s", p[0], node->name);
17803           for (j = 0; j < vec_len (node->next_nodes); j++)
17804             {
17805               if (node->next_nodes[j] != ~0)
17806                 {
17807                   next_node = vam->graph_nodes[node->next_nodes[j]];
17808                   print (vam->ofp, "  [%d] %s", j, next_node->name);
17809                 }
17810             }
17811         }
17812
17813       else
17814         {
17815           clib_warning ("parse error '%U'", format_unformat_error,
17816                         line_input);
17817           return -99;
17818         }
17819
17820     out:
17821       vec_free (node_to_find);
17822
17823     }
17824
17825   return 0;
17826 }
17827
17828
17829 static int
17830 script (vat_main_t * vam)
17831 {
17832 #if (VPP_API_TEST_BUILTIN==0)
17833   u8 *s = 0;
17834   char *save_current_file;
17835   unformat_input_t save_input;
17836   jmp_buf save_jump_buf;
17837   u32 save_line_number;
17838
17839   FILE *new_fp, *save_ifp;
17840
17841   if (unformat (vam->input, "%s", &s))
17842     {
17843       new_fp = fopen ((char *) s, "r");
17844       if (new_fp == 0)
17845         {
17846           errmsg ("Couldn't open script file %s", s);
17847           vec_free (s);
17848           return -99;
17849         }
17850     }
17851   else
17852     {
17853       errmsg ("Missing script name");
17854       return -99;
17855     }
17856
17857   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
17858   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
17859   save_ifp = vam->ifp;
17860   save_line_number = vam->input_line_number;
17861   save_current_file = (char *) vam->current_file;
17862
17863   vam->input_line_number = 0;
17864   vam->ifp = new_fp;
17865   vam->current_file = s;
17866   do_one_file (vam);
17867
17868   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
17869   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
17870   vam->ifp = save_ifp;
17871   vam->input_line_number = save_line_number;
17872   vam->current_file = (u8 *) save_current_file;
17873   vec_free (s);
17874
17875   return 0;
17876 #else
17877   clib_warning ("use the exec command...");
17878   return -99;
17879 #endif
17880 }
17881
17882 static int
17883 echo (vat_main_t * vam)
17884 {
17885   print (vam->ofp, "%v", vam->input->buffer);
17886   return 0;
17887 }
17888
17889 /* List of API message constructors, CLI names map to api_xxx */
17890 #define foreach_vpe_api_msg                                             \
17891 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
17892 _(sw_interface_dump,"")                                                 \
17893 _(sw_interface_set_flags,                                               \
17894   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
17895 _(sw_interface_add_del_address,                                         \
17896   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
17897 _(sw_interface_set_table,                                               \
17898   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
17899 _(sw_interface_set_mpls_enable,                                         \
17900   "<intfc> | sw_if_index [disable | dis]")                              \
17901 _(sw_interface_set_vpath,                                               \
17902   "<intfc> | sw_if_index <id> enable | disable")                        \
17903 _(sw_interface_set_vxlan_bypass,                                        \
17904   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
17905 _(sw_interface_set_l2_xconnect,                                         \
17906   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17907   "enable | disable")                                                   \
17908 _(sw_interface_set_l2_bridge,                                           \
17909   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"               \
17910   "[shg <split-horizon-group>] [bvi]\n"                                 \
17911   "enable | disable")                                                   \
17912 _(bridge_domain_add_del,                                                \
17913   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n") \
17914 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
17915 _(l2fib_add_del,                                                        \
17916   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
17917 _(l2_flags,                                                             \
17918   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
17919 _(bridge_flags,                                                         \
17920   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
17921 _(tap_connect,                                                          \
17922   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
17923 _(tap_modify,                                                           \
17924   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
17925 _(tap_delete,                                                           \
17926   "<vpp-if-name> | sw_if_index <id>")                                   \
17927 _(sw_interface_tap_dump, "")                                            \
17928 _(ip_add_del_route,                                                     \
17929   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
17930   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
17931   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
17932   "[multipath] [count <n>]")                                            \
17933 _(ip_mroute_add_del,                                                    \
17934   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
17935   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
17936 _(mpls_route_add_del,                                                   \
17937   "<label> <eos> via <addr> [table-id <n>]\n"                           \
17938   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
17939   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
17940   "[multipath] [count <n>]")                                            \
17941 _(mpls_ip_bind_unbind,                                                  \
17942   "<label> <addr/len>")                                                 \
17943 _(mpls_tunnel_add_del,                                                  \
17944   " via <addr> [table-id <n>]\n"                                        \
17945   "sw_if_index <id>] [l2]  [del]")                                      \
17946 _(proxy_arp_add_del,                                                    \
17947   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
17948 _(proxy_arp_intfc_enable_disable,                                       \
17949   "<intfc> | sw_if_index <id> enable | disable")                        \
17950 _(sw_interface_set_unnumbered,                                          \
17951   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
17952 _(ip_neighbor_add_del,                                                  \
17953   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
17954   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
17955 _(reset_vrf, "vrf <id> [ipv6]")                                         \
17956 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
17957 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
17958   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
17959   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
17960   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
17961 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
17962 _(reset_fib, "vrf <n> [ipv6]")                                          \
17963 _(dhcp_proxy_config,                                                    \
17964   "svr <v46-address> src <v46-address>\n"                               \
17965    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
17966 _(dhcp_proxy_set_vss,                                                   \
17967   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
17968 _(dhcp_proxy_dump, "ip6")                                               \
17969 _(dhcp_client_config,                                                   \
17970   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
17971 _(set_ip_flow_hash,                                                     \
17972   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
17973 _(sw_interface_ip6_enable_disable,                                      \
17974   "<intfc> | sw_if_index <id> enable | disable")                        \
17975 _(sw_interface_ip6_set_link_local_address,                              \
17976   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
17977 _(sw_interface_ip6nd_ra_prefix,                                         \
17978   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
17979   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
17980   "[nolink] [isno]")                                                    \
17981 _(sw_interface_ip6nd_ra_config,                                         \
17982   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
17983   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
17984   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
17985 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
17986 _(l2_patch_add_del,                                                     \
17987   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17988   "enable | disable")                                                   \
17989 _(sr_localsid_add_del,                                                  \
17990   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
17991   "fib-table <num> (end.psp) sw_if_index <num>")                        \
17992 _(classify_add_del_table,                                               \
17993   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
17994   " [del] [del-chain] mask <mask-value>\n"                              \
17995   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
17996   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
17997 _(classify_add_del_session,                                             \
17998   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
17999   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
18000   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
18001   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
18002 _(classify_set_interface_ip_table,                                      \
18003   "<intfc> | sw_if_index <nn> table <nn>")                              \
18004 _(classify_set_interface_l2_tables,                                     \
18005   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18006   "  [other-table <nn>]")                                               \
18007 _(get_node_index, "node <node-name")                                    \
18008 _(add_node_next, "node <node-name> next <next-node-name>")              \
18009 _(l2tpv3_create_tunnel,                                                 \
18010   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
18011   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
18012   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
18013 _(l2tpv3_set_tunnel_cookies,                                            \
18014   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
18015   "[new_remote_cookie <nn>]\n")                                         \
18016 _(l2tpv3_interface_enable_disable,                                      \
18017   "<intfc> | sw_if_index <nn> enable | disable")                        \
18018 _(l2tpv3_set_lookup_key,                                                \
18019   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
18020 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
18021 _(vxlan_add_del_tunnel,                                                 \
18022   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
18023   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
18024   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
18025 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
18026 _(gre_add_del_tunnel,                                                   \
18027   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
18028 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
18029 _(l2_fib_clear_table, "")                                               \
18030 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
18031 _(l2_interface_vlan_tag_rewrite,                                        \
18032   "<intfc> | sw_if_index <nn> \n"                                       \
18033   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
18034   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
18035 _(create_vhost_user_if,                                                 \
18036         "socket <filename> [server] [renumber <dev_instance>] "         \
18037         "[mac <mac_address>]")                                          \
18038 _(modify_vhost_user_if,                                                 \
18039         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
18040         "[server] [renumber <dev_instance>]")                           \
18041 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
18042 _(sw_interface_vhost_user_dump, "")                                     \
18043 _(show_version, "")                                                     \
18044 _(vxlan_gpe_add_del_tunnel,                                             \
18045   "local <addr> remote <addr> vni <nn>\n"                               \
18046     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
18047   "[next-ethernet] [next-nsh]\n")                                       \
18048 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
18049 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
18050 _(interface_name_renumber,                                              \
18051   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
18052 _(input_acl_set_interface,                                              \
18053   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18054   "  [l2-table <nn>] [del]")                                            \
18055 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
18056 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
18057 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
18058 _(ip_dump, "ipv4 | ipv6")                                               \
18059 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
18060 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
18061   "  spid_id <n> ")                                                     \
18062 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
18063   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
18064   "  integ_alg <alg> integ_key <hex>")                                  \
18065 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
18066   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
18067   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
18068   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
18069 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
18070 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
18071 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
18072   "(auth_data 0x<data> | auth_data <data>)")                            \
18073 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
18074   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
18075 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
18076   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
18077   "(local|remote)")                                                     \
18078 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
18079 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
18080 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18081 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18082 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
18083 _(ikev2_initiate_sa_init, "<profile_name>")                             \
18084 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
18085 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
18086 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
18087 _(delete_loopback,"sw_if_index <nn>")                                   \
18088 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
18089 _(map_add_domain,                                                       \
18090   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
18091   "ip6-src <ip6addr> "                                                  \
18092   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
18093 _(map_del_domain, "index <n>")                                          \
18094 _(map_add_del_rule,                                                     \
18095   "index <n> psid <n> dst <ip6addr> [del]")                             \
18096 _(map_domain_dump, "")                                                  \
18097 _(map_rule_dump, "index <map-domain>")                                  \
18098 _(want_interface_events,  "enable|disable")                             \
18099 _(want_stats,"enable|disable")                                          \
18100 _(get_first_msg_id, "client <name>")                                    \
18101 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
18102 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
18103   "fib-id <nn> [ip4][ip6][default]")                                    \
18104 _(get_node_graph, " ")                                                  \
18105 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
18106 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
18107 _(ioam_disable, "")                                                     \
18108 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
18109                             " sw_if_index <sw_if_index> p <priority> "  \
18110                             "w <weight>] [del]")                        \
18111 _(one_add_del_locator, "locator-set <locator_name> "                    \
18112                         "iface <intf> | sw_if_index <sw_if_index> "     \
18113                         "p <priority> w <weight> [del]")                \
18114 _(one_add_del_local_eid,"vni <vni> eid "                                \
18115                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
18116                          "locator-set <locator_name> [del]"             \
18117                          "[key-id sha1|sha256 secret-key <secret-key>]")\
18118 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
18119 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
18120 _(one_enable_disable, "enable|disable")                                 \
18121 _(one_map_register_enable_disable, "enable|disable")                    \
18122 _(one_rloc_probe_enable_disable, "enable|disable")                      \
18123 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
18124                                "[seid <seid>] "                         \
18125                                "rloc <locator> p <prio> "               \
18126                                "w <weight> [rloc <loc> ... ] "          \
18127                                "action <action> [del-all]")             \
18128 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
18129                           "<local-eid>")                                \
18130 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
18131 _(one_map_request_mode, "src-dst|dst-only")                             \
18132 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
18133 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
18134 _(one_locator_set_dump, "[local | remote]")                             \
18135 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
18136 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
18137                        "[local] | [remote]")                            \
18138 _(one_eid_table_vni_dump, "")                                           \
18139 _(one_eid_table_map_dump, "l2|l3")                                      \
18140 _(one_map_resolver_dump, "")                                            \
18141 _(one_map_server_dump, "")                                              \
18142 _(one_adjacencies_get, "vni <vni>")                                     \
18143 _(show_one_rloc_probe_state, "")                                        \
18144 _(show_one_map_register_state, "")                                      \
18145 _(show_one_status, "")                                                  \
18146 _(one_get_map_request_itr_rlocs, "")                                    \
18147 _(show_one_pitr, "")                                                    \
18148 _(show_one_map_request_mode, "")                                        \
18149 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
18150                             " sw_if_index <sw_if_index> p <priority> "  \
18151                             "w <weight>] [del]")                        \
18152 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
18153                         "iface <intf> | sw_if_index <sw_if_index> "     \
18154                         "p <priority> w <weight> [del]")                \
18155 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
18156                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
18157                          "locator-set <locator_name> [del]"             \
18158                          "[key-id sha1|sha256 secret-key <secret-key>]") \
18159 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
18160 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
18161 _(lisp_enable_disable, "enable|disable")                                \
18162 _(lisp_map_register_enable_disable, "enable|disable")                   \
18163 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
18164 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
18165                                "[seid <seid>] "                         \
18166                                "rloc <locator> p <prio> "               \
18167                                "w <weight> [rloc <loc> ... ] "          \
18168                                "action <action> [del-all]")             \
18169 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
18170                           "<local-eid>")                                \
18171 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
18172 _(lisp_map_request_mode, "src-dst|dst-only")                            \
18173 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
18174 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
18175 _(lisp_locator_set_dump, "[local | remote]")                            \
18176 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
18177 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
18178                        "[local] | [remote]")                            \
18179 _(lisp_eid_table_vni_dump, "")                                          \
18180 _(lisp_eid_table_map_dump, "l2|l3")                                     \
18181 _(lisp_map_resolver_dump, "")                                           \
18182 _(lisp_map_server_dump, "")                                             \
18183 _(lisp_adjacencies_get, "vni <vni>")                                    \
18184 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
18185 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
18186 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
18187 _(gpe_get_encap_mode, "")                                               \
18188 _(lisp_gpe_add_del_iface, "up|down")                                    \
18189 _(lisp_gpe_enable_disable, "enable|disable")                            \
18190 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
18191   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
18192 _(show_lisp_rloc_probe_state, "")                                       \
18193 _(show_lisp_map_register_state, "")                                     \
18194 _(show_lisp_status, "")                                                 \
18195 _(lisp_get_map_request_itr_rlocs, "")                                   \
18196 _(show_lisp_pitr, "")                                                   \
18197 _(show_lisp_map_request_mode, "")                                       \
18198 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
18199 _(af_packet_delete, "name <host interface name>")                       \
18200 _(policer_add_del, "name <policer name> <params> [del]")                \
18201 _(policer_dump, "[name <policer name>]")                                \
18202 _(policer_classify_set_interface,                                       \
18203   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18204   "  [l2-table <nn>] [del]")                                            \
18205 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
18206 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
18207     "[master|slave]")                                                   \
18208 _(netmap_delete, "name <interface name>")                               \
18209 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
18210 _(mpls_fib_dump, "")                                                    \
18211 _(classify_table_ids, "")                                               \
18212 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
18213 _(classify_table_info, "table_id <nn>")                                 \
18214 _(classify_session_dump, "table_id <nn>")                               \
18215 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
18216     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
18217     "[template_interval <nn>] [udp_checksum]")                          \
18218 _(ipfix_exporter_dump, "")                                              \
18219 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
18220 _(ipfix_classify_stream_dump, "")                                       \
18221 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
18222 _(ipfix_classify_table_dump, "")                                        \
18223 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
18224 _(sw_interface_span_dump, "")                                           \
18225 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
18226 _(pg_create_interface, "if_id <nn>")                                    \
18227 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
18228 _(pg_enable_disable, "[stream <id>] disable")                           \
18229 _(ip_source_and_port_range_check_add_del,                               \
18230   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
18231 _(ip_source_and_port_range_check_interface_add_del,                     \
18232   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
18233   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
18234 _(ipsec_gre_add_del_tunnel,                                             \
18235   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
18236 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
18237 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
18238 _(l2_interface_pbb_tag_rewrite,                                         \
18239   "<intfc> | sw_if_index <nn> \n"                                       \
18240   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
18241   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
18242 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
18243 _(flow_classify_set_interface,                                          \
18244   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
18245 _(flow_classify_dump, "type [ip4|ip6]")                                 \
18246 _(ip_fib_dump, "")                                                      \
18247 _(ip_mfib_dump, "")                                                     \
18248 _(ip6_fib_dump, "")                                                     \
18249 _(ip6_mfib_dump, "")                                                    \
18250 _(feature_enable_disable, "arc_name <arc_name> "                        \
18251   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
18252 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
18253 "[disable]")                                                            \
18254 _(l2_xconnect_dump, "")                                                 \
18255 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
18256 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
18257 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
18258
18259 /* List of command functions, CLI names map directly to functions */
18260 #define foreach_cli_function                                    \
18261 _(comment, "usage: comment <ignore-rest-of-line>")              \
18262 _(dump_interface_table, "usage: dump_interface_table")          \
18263 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
18264 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
18265 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
18266 _(dump_stats_table, "usage: dump_stats_table")                  \
18267 _(dump_macro_table, "usage: dump_macro_table ")                 \
18268 _(dump_node_table, "usage: dump_node_table")                    \
18269 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
18270 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
18271 _(echo, "usage: echo <message>")                                \
18272 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
18273 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
18274 _(help, "usage: help")                                          \
18275 _(q, "usage: quit")                                             \
18276 _(quit, "usage: quit")                                          \
18277 _(search_node_table, "usage: search_node_table <name>...")      \
18278 _(set, "usage: set <variable-name> <value>")                    \
18279 _(script, "usage: script <file-name>")                          \
18280 _(unset, "usage: unset <variable-name>")
18281
18282 #define _(N,n)                                  \
18283     static void vl_api_##n##_t_handler_uni      \
18284     (vl_api_##n##_t * mp)                       \
18285     {                                           \
18286         vat_main_t * vam = &vat_main;           \
18287         if (vam->json_output) {                 \
18288             vl_api_##n##_t_handler_json(mp);    \
18289         } else {                                \
18290             vl_api_##n##_t_handler(mp);         \
18291         }                                       \
18292     }
18293 foreach_vpe_api_reply_msg;
18294 #if VPP_API_TEST_BUILTIN == 0
18295 foreach_standalone_reply_msg;
18296 #endif
18297 #undef _
18298
18299 void
18300 vat_api_hookup (vat_main_t * vam)
18301 {
18302 #define _(N,n)                                                  \
18303     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
18304                            vl_api_##n##_t_handler_uni,          \
18305                            vl_noop_handler,                     \
18306                            vl_api_##n##_t_endian,               \
18307                            vl_api_##n##_t_print,                \
18308                            sizeof(vl_api_##n##_t), 1);
18309   foreach_vpe_api_reply_msg;
18310 #if VPP_API_TEST_BUILTIN == 0
18311   foreach_standalone_reply_msg;
18312 #endif
18313 #undef _
18314
18315 #if (VPP_API_TEST_BUILTIN==0)
18316   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
18317
18318   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
18319
18320   vam->function_by_name = hash_create_string (0, sizeof (uword));
18321
18322   vam->help_by_name = hash_create_string (0, sizeof (uword));
18323 #endif
18324
18325   /* API messages we can send */
18326 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
18327   foreach_vpe_api_msg;
18328 #undef _
18329
18330   /* Help strings */
18331 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18332   foreach_vpe_api_msg;
18333 #undef _
18334
18335   /* CLI functions */
18336 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
18337   foreach_cli_function;
18338 #undef _
18339
18340   /* Help strings */
18341 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18342   foreach_cli_function;
18343 #undef _
18344 }
18345
18346 #if VPP_API_TEST_BUILTIN
18347 static clib_error_t *
18348 vat_api_hookup_shim (vlib_main_t * vm)
18349 {
18350   vat_api_hookup (&vat_main);
18351   return 0;
18352 }
18353
18354 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
18355 #endif
18356
18357 /*
18358  * fd.io coding-style-patch-verification: ON
18359  *
18360  * Local Variables:
18361  * eval: (c-set-style "gnu")
18362  * End:
18363  */