Evolving SRv6 (Segment Routing for IPv6)
[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   errmsg ("arp %s event: address %U new mac %U sw_if_index %d",
1258           mp->mac_ip ? "mac/ip binding" : "address resolution",
1259           format_ip4_address, &mp->address,
1260           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1261 }
1262
1263 static void
1264 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1265 {
1266   /* JSON output not supported */
1267 }
1268
1269 static void
1270 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1271 {
1272   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d",
1273           mp->mac_ip ? "mac/ip binding" : "address resolution",
1274           format_ip6_address, mp->address,
1275           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1276 }
1277
1278 static void
1279 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1280 {
1281   /* JSON output not supported */
1282 }
1283
1284 /*
1285  * Special-case: build the bridge domain table, maintain
1286  * the next bd id vbl.
1287  */
1288 static void vl_api_bridge_domain_details_t_handler
1289   (vl_api_bridge_domain_details_t * mp)
1290 {
1291   vat_main_t *vam = &vat_main;
1292   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1293
1294   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1295          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1296
1297   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1298          ntohl (mp->bd_id), mp->learn, mp->forward,
1299          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1300
1301   if (n_sw_ifs)
1302     print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG", "Interface Name");
1303 }
1304
1305 static void vl_api_bridge_domain_details_t_handler_json
1306   (vl_api_bridge_domain_details_t * mp)
1307 {
1308   vat_main_t *vam = &vat_main;
1309   vat_json_node_t *node, *array = NULL;
1310
1311   if (VAT_JSON_ARRAY != vam->json_tree.type)
1312     {
1313       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1314       vat_json_init_array (&vam->json_tree);
1315     }
1316   node = vat_json_array_add (&vam->json_tree);
1317
1318   vat_json_init_object (node);
1319   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1320   vat_json_object_add_uint (node, "flood", mp->flood);
1321   vat_json_object_add_uint (node, "forward", mp->forward);
1322   vat_json_object_add_uint (node, "learn", mp->learn);
1323   vat_json_object_add_uint (node, "bvi_sw_if_index",
1324                             ntohl (mp->bvi_sw_if_index));
1325   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1326   array = vat_json_object_add (node, "sw_if");
1327   vat_json_init_array (array);
1328 }
1329
1330 /*
1331  * Special-case: build the bridge domain sw if table.
1332  */
1333 static void vl_api_bridge_domain_sw_if_details_t_handler
1334   (vl_api_bridge_domain_sw_if_details_t * mp)
1335 {
1336   vat_main_t *vam = &vat_main;
1337   hash_pair_t *p;
1338   u8 *sw_if_name = 0;
1339   u32 sw_if_index;
1340
1341   sw_if_index = ntohl (mp->sw_if_index);
1342   /* *INDENT-OFF* */
1343   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1344   ({
1345     if ((u32) p->value[0] == sw_if_index)
1346       {
1347         sw_if_name = (u8 *)(p->key);
1348         break;
1349       }
1350   }));
1351   /* *INDENT-ON* */
1352
1353   print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1354          mp->shg, sw_if_name ? (char *) sw_if_name :
1355          "sw_if_index not found!");
1356 }
1357
1358 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1359   (vl_api_bridge_domain_sw_if_details_t * mp)
1360 {
1361   vat_main_t *vam = &vat_main;
1362   vat_json_node_t *node = NULL;
1363   uword last_index = 0;
1364
1365   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1366   ASSERT (vec_len (vam->json_tree.array) >= 1);
1367   last_index = vec_len (vam->json_tree.array) - 1;
1368   node = &vam->json_tree.array[last_index];
1369   node = vat_json_object_get_element (node, "sw_if");
1370   ASSERT (NULL != node);
1371   node = vat_json_array_add (node);
1372
1373   vat_json_init_object (node);
1374   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1375   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1376   vat_json_object_add_uint (node, "shg", mp->shg);
1377 }
1378
1379 static void vl_api_control_ping_reply_t_handler
1380   (vl_api_control_ping_reply_t * mp)
1381 {
1382   vat_main_t *vam = &vat_main;
1383   i32 retval = ntohl (mp->retval);
1384   if (vam->async_mode)
1385     {
1386       vam->async_errors += (retval < 0);
1387     }
1388   else
1389     {
1390       vam->retval = retval;
1391       vam->result_ready = 1;
1392     }
1393 }
1394
1395 static void vl_api_control_ping_reply_t_handler_json
1396   (vl_api_control_ping_reply_t * mp)
1397 {
1398   vat_main_t *vam = &vat_main;
1399   i32 retval = ntohl (mp->retval);
1400
1401   if (VAT_JSON_NONE != vam->json_tree.type)
1402     {
1403       vat_json_print (vam->ofp, &vam->json_tree);
1404       vat_json_free (&vam->json_tree);
1405       vam->json_tree.type = VAT_JSON_NONE;
1406     }
1407   else
1408     {
1409       /* just print [] */
1410       vat_json_init_array (&vam->json_tree);
1411       vat_json_print (vam->ofp, &vam->json_tree);
1412       vam->json_tree.type = VAT_JSON_NONE;
1413     }
1414
1415   vam->retval = retval;
1416   vam->result_ready = 1;
1417 }
1418
1419 static void
1420 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1421 {
1422   vat_main_t *vam = &vat_main;
1423   i32 retval = ntohl (mp->retval);
1424   if (vam->async_mode)
1425     {
1426       vam->async_errors += (retval < 0);
1427     }
1428   else
1429     {
1430       vam->retval = retval;
1431       vam->result_ready = 1;
1432     }
1433 }
1434
1435 static void vl_api_l2_flags_reply_t_handler_json
1436   (vl_api_l2_flags_reply_t * mp)
1437 {
1438   vat_main_t *vam = &vat_main;
1439   vat_json_node_t node;
1440
1441   vat_json_init_object (&node);
1442   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1443   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1444                             ntohl (mp->resulting_feature_bitmap));
1445
1446   vat_json_print (vam->ofp, &node);
1447   vat_json_free (&node);
1448
1449   vam->retval = ntohl (mp->retval);
1450   vam->result_ready = 1;
1451 }
1452
1453 static void vl_api_bridge_flags_reply_t_handler
1454   (vl_api_bridge_flags_reply_t * mp)
1455 {
1456   vat_main_t *vam = &vat_main;
1457   i32 retval = ntohl (mp->retval);
1458   if (vam->async_mode)
1459     {
1460       vam->async_errors += (retval < 0);
1461     }
1462   else
1463     {
1464       vam->retval = retval;
1465       vam->result_ready = 1;
1466     }
1467 }
1468
1469 static void vl_api_bridge_flags_reply_t_handler_json
1470   (vl_api_bridge_flags_reply_t * mp)
1471 {
1472   vat_main_t *vam = &vat_main;
1473   vat_json_node_t node;
1474
1475   vat_json_init_object (&node);
1476   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1477   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1478                             ntohl (mp->resulting_feature_bitmap));
1479
1480   vat_json_print (vam->ofp, &node);
1481   vat_json_free (&node);
1482
1483   vam->retval = ntohl (mp->retval);
1484   vam->result_ready = 1;
1485 }
1486
1487 static void vl_api_tap_connect_reply_t_handler
1488   (vl_api_tap_connect_reply_t * mp)
1489 {
1490   vat_main_t *vam = &vat_main;
1491   i32 retval = ntohl (mp->retval);
1492   if (vam->async_mode)
1493     {
1494       vam->async_errors += (retval < 0);
1495     }
1496   else
1497     {
1498       vam->retval = retval;
1499       vam->sw_if_index = ntohl (mp->sw_if_index);
1500       vam->result_ready = 1;
1501     }
1502
1503 }
1504
1505 static void vl_api_tap_connect_reply_t_handler_json
1506   (vl_api_tap_connect_reply_t * mp)
1507 {
1508   vat_main_t *vam = &vat_main;
1509   vat_json_node_t node;
1510
1511   vat_json_init_object (&node);
1512   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1513   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1514
1515   vat_json_print (vam->ofp, &node);
1516   vat_json_free (&node);
1517
1518   vam->retval = ntohl (mp->retval);
1519   vam->result_ready = 1;
1520
1521 }
1522
1523 static void
1524 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1525 {
1526   vat_main_t *vam = &vat_main;
1527   i32 retval = ntohl (mp->retval);
1528   if (vam->async_mode)
1529     {
1530       vam->async_errors += (retval < 0);
1531     }
1532   else
1533     {
1534       vam->retval = retval;
1535       vam->sw_if_index = ntohl (mp->sw_if_index);
1536       vam->result_ready = 1;
1537     }
1538 }
1539
1540 static void vl_api_tap_modify_reply_t_handler_json
1541   (vl_api_tap_modify_reply_t * mp)
1542 {
1543   vat_main_t *vam = &vat_main;
1544   vat_json_node_t node;
1545
1546   vat_json_init_object (&node);
1547   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1548   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1549
1550   vat_json_print (vam->ofp, &node);
1551   vat_json_free (&node);
1552
1553   vam->retval = ntohl (mp->retval);
1554   vam->result_ready = 1;
1555 }
1556
1557 static void
1558 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1559 {
1560   vat_main_t *vam = &vat_main;
1561   i32 retval = ntohl (mp->retval);
1562   if (vam->async_mode)
1563     {
1564       vam->async_errors += (retval < 0);
1565     }
1566   else
1567     {
1568       vam->retval = retval;
1569       vam->result_ready = 1;
1570     }
1571 }
1572
1573 static void vl_api_tap_delete_reply_t_handler_json
1574   (vl_api_tap_delete_reply_t * mp)
1575 {
1576   vat_main_t *vam = &vat_main;
1577   vat_json_node_t node;
1578
1579   vat_json_init_object (&node);
1580   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1581
1582   vat_json_print (vam->ofp, &node);
1583   vat_json_free (&node);
1584
1585   vam->retval = ntohl (mp->retval);
1586   vam->result_ready = 1;
1587 }
1588
1589 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1590   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1591 {
1592   vat_main_t *vam = &vat_main;
1593   i32 retval = ntohl (mp->retval);
1594   if (vam->async_mode)
1595     {
1596       vam->async_errors += (retval < 0);
1597     }
1598   else
1599     {
1600       vam->retval = retval;
1601       vam->result_ready = 1;
1602     }
1603 }
1604
1605 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1606   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1607 {
1608   vat_main_t *vam = &vat_main;
1609   vat_json_node_t node;
1610
1611   vat_json_init_object (&node);
1612   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1613   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1614                             ntohl (mp->sw_if_index));
1615
1616   vat_json_print (vam->ofp, &node);
1617   vat_json_free (&node);
1618
1619   vam->retval = ntohl (mp->retval);
1620   vam->result_ready = 1;
1621 }
1622
1623 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1624   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1625 {
1626   vat_main_t *vam = &vat_main;
1627   i32 retval = ntohl (mp->retval);
1628   if (vam->async_mode)
1629     {
1630       vam->async_errors += (retval < 0);
1631     }
1632   else
1633     {
1634       vam->retval = retval;
1635       vam->sw_if_index = ntohl (mp->sw_if_index);
1636       vam->result_ready = 1;
1637     }
1638 }
1639
1640 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1641   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1642 {
1643   vat_main_t *vam = &vat_main;
1644   vat_json_node_t node;
1645
1646   vat_json_init_object (&node);
1647   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1648   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1649
1650   vat_json_print (vam->ofp, &node);
1651   vat_json_free (&node);
1652
1653   vam->retval = ntohl (mp->retval);
1654   vam->result_ready = 1;
1655 }
1656
1657
1658 static void vl_api_one_add_del_locator_set_reply_t_handler
1659   (vl_api_one_add_del_locator_set_reply_t * mp)
1660 {
1661   vat_main_t *vam = &vat_main;
1662   i32 retval = ntohl (mp->retval);
1663   if (vam->async_mode)
1664     {
1665       vam->async_errors += (retval < 0);
1666     }
1667   else
1668     {
1669       vam->retval = retval;
1670       vam->result_ready = 1;
1671     }
1672 }
1673
1674 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1675   (vl_api_one_add_del_locator_set_reply_t * mp)
1676 {
1677   vat_main_t *vam = &vat_main;
1678   vat_json_node_t node;
1679
1680   vat_json_init_object (&node);
1681   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1682   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1683
1684   vat_json_print (vam->ofp, &node);
1685   vat_json_free (&node);
1686
1687   vam->retval = ntohl (mp->retval);
1688   vam->result_ready = 1;
1689 }
1690
1691 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1692   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1693 {
1694   vat_main_t *vam = &vat_main;
1695   i32 retval = ntohl (mp->retval);
1696   if (vam->async_mode)
1697     {
1698       vam->async_errors += (retval < 0);
1699     }
1700   else
1701     {
1702       vam->retval = retval;
1703       vam->sw_if_index = ntohl (mp->sw_if_index);
1704       vam->result_ready = 1;
1705     }
1706 }
1707
1708 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1709   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1710 {
1711   vat_main_t *vam = &vat_main;
1712   vat_json_node_t node;
1713
1714   vat_json_init_object (&node);
1715   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1716   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1717
1718   vat_json_print (vam->ofp, &node);
1719   vat_json_free (&node);
1720
1721   vam->retval = ntohl (mp->retval);
1722   vam->result_ready = 1;
1723 }
1724
1725 static void vl_api_gre_add_del_tunnel_reply_t_handler
1726   (vl_api_gre_add_del_tunnel_reply_t * mp)
1727 {
1728   vat_main_t *vam = &vat_main;
1729   i32 retval = ntohl (mp->retval);
1730   if (vam->async_mode)
1731     {
1732       vam->async_errors += (retval < 0);
1733     }
1734   else
1735     {
1736       vam->retval = retval;
1737       vam->sw_if_index = ntohl (mp->sw_if_index);
1738       vam->result_ready = 1;
1739     }
1740 }
1741
1742 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1743   (vl_api_gre_add_del_tunnel_reply_t * mp)
1744 {
1745   vat_main_t *vam = &vat_main;
1746   vat_json_node_t node;
1747
1748   vat_json_init_object (&node);
1749   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1750   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1751
1752   vat_json_print (vam->ofp, &node);
1753   vat_json_free (&node);
1754
1755   vam->retval = ntohl (mp->retval);
1756   vam->result_ready = 1;
1757 }
1758
1759 static void vl_api_create_vhost_user_if_reply_t_handler
1760   (vl_api_create_vhost_user_if_reply_t * mp)
1761 {
1762   vat_main_t *vam = &vat_main;
1763   i32 retval = ntohl (mp->retval);
1764   if (vam->async_mode)
1765     {
1766       vam->async_errors += (retval < 0);
1767     }
1768   else
1769     {
1770       vam->retval = retval;
1771       vam->sw_if_index = ntohl (mp->sw_if_index);
1772       vam->result_ready = 1;
1773     }
1774 }
1775
1776 static void vl_api_create_vhost_user_if_reply_t_handler_json
1777   (vl_api_create_vhost_user_if_reply_t * mp)
1778 {
1779   vat_main_t *vam = &vat_main;
1780   vat_json_node_t node;
1781
1782   vat_json_init_object (&node);
1783   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1784   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1785
1786   vat_json_print (vam->ofp, &node);
1787   vat_json_free (&node);
1788
1789   vam->retval = ntohl (mp->retval);
1790   vam->result_ready = 1;
1791 }
1792
1793 static void vl_api_ip_address_details_t_handler
1794   (vl_api_ip_address_details_t * mp)
1795 {
1796   vat_main_t *vam = &vat_main;
1797   static ip_address_details_t empty_ip_address_details = { {0} };
1798   ip_address_details_t *address = NULL;
1799   ip_details_t *current_ip_details = NULL;
1800   ip_details_t *details = NULL;
1801
1802   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1803
1804   if (!details || vam->current_sw_if_index >= vec_len (details)
1805       || !details[vam->current_sw_if_index].present)
1806     {
1807       errmsg ("ip address details arrived but not stored");
1808       errmsg ("ip_dump should be called first");
1809       return;
1810     }
1811
1812   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1813
1814 #define addresses (current_ip_details->addr)
1815
1816   vec_validate_init_empty (addresses, vec_len (addresses),
1817                            empty_ip_address_details);
1818
1819   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1820
1821   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1822   address->prefix_length = mp->prefix_length;
1823 #undef addresses
1824 }
1825
1826 static void vl_api_ip_address_details_t_handler_json
1827   (vl_api_ip_address_details_t * mp)
1828 {
1829   vat_main_t *vam = &vat_main;
1830   vat_json_node_t *node = NULL;
1831   struct in6_addr ip6;
1832   struct in_addr ip4;
1833
1834   if (VAT_JSON_ARRAY != vam->json_tree.type)
1835     {
1836       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1837       vat_json_init_array (&vam->json_tree);
1838     }
1839   node = vat_json_array_add (&vam->json_tree);
1840
1841   vat_json_init_object (node);
1842   if (vam->is_ipv6)
1843     {
1844       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1845       vat_json_object_add_ip6 (node, "ip", ip6);
1846     }
1847   else
1848     {
1849       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1850       vat_json_object_add_ip4 (node, "ip", ip4);
1851     }
1852   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1853 }
1854
1855 static void
1856 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1857 {
1858   vat_main_t *vam = &vat_main;
1859   static ip_details_t empty_ip_details = { 0 };
1860   ip_details_t *ip = NULL;
1861   u32 sw_if_index = ~0;
1862
1863   sw_if_index = ntohl (mp->sw_if_index);
1864
1865   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1866                            sw_if_index, empty_ip_details);
1867
1868   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1869                          sw_if_index);
1870
1871   ip->present = 1;
1872 }
1873
1874 static void
1875 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1876 {
1877   vat_main_t *vam = &vat_main;
1878
1879   if (VAT_JSON_ARRAY != vam->json_tree.type)
1880     {
1881       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1882       vat_json_init_array (&vam->json_tree);
1883     }
1884   vat_json_array_add_uint (&vam->json_tree,
1885                            clib_net_to_host_u32 (mp->sw_if_index));
1886 }
1887
1888 static void vl_api_map_domain_details_t_handler_json
1889   (vl_api_map_domain_details_t * mp)
1890 {
1891   vat_json_node_t *node = NULL;
1892   vat_main_t *vam = &vat_main;
1893   struct in6_addr ip6;
1894   struct in_addr ip4;
1895
1896   if (VAT_JSON_ARRAY != vam->json_tree.type)
1897     {
1898       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1899       vat_json_init_array (&vam->json_tree);
1900     }
1901
1902   node = vat_json_array_add (&vam->json_tree);
1903   vat_json_init_object (node);
1904
1905   vat_json_object_add_uint (node, "domain_index",
1906                             clib_net_to_host_u32 (mp->domain_index));
1907   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1908   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1909   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1910   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1911   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1912   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1913   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1914   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1915   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1916   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1917   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1918   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1919   vat_json_object_add_uint (node, "flags", mp->flags);
1920   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1921   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1922 }
1923
1924 static void vl_api_map_domain_details_t_handler
1925   (vl_api_map_domain_details_t * mp)
1926 {
1927   vat_main_t *vam = &vat_main;
1928
1929   if (mp->is_translation)
1930     {
1931       print (vam->ofp,
1932              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
1933              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1934              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1935              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1936              clib_net_to_host_u32 (mp->domain_index));
1937     }
1938   else
1939     {
1940       print (vam->ofp,
1941              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
1942              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1943              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1944              format_ip6_address, mp->ip6_src,
1945              clib_net_to_host_u32 (mp->domain_index));
1946     }
1947   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
1948          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1949          mp->is_translation ? "map-t" : "");
1950 }
1951
1952 static void vl_api_map_rule_details_t_handler_json
1953   (vl_api_map_rule_details_t * mp)
1954 {
1955   struct in6_addr ip6;
1956   vat_json_node_t *node = NULL;
1957   vat_main_t *vam = &vat_main;
1958
1959   if (VAT_JSON_ARRAY != vam->json_tree.type)
1960     {
1961       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1962       vat_json_init_array (&vam->json_tree);
1963     }
1964
1965   node = vat_json_array_add (&vam->json_tree);
1966   vat_json_init_object (node);
1967
1968   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1969   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1970   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1971 }
1972
1973 static void
1974 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1975 {
1976   vat_main_t *vam = &vat_main;
1977   print (vam->ofp, " %d (psid) %U (ip6-dst)",
1978          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1979 }
1980
1981 static void
1982 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1983 {
1984   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1985           "router_addr %U host_mac %U",
1986           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1987           format_ip4_address, &mp->host_address,
1988           format_ip4_address, &mp->router_address,
1989           format_ethernet_address, mp->host_mac);
1990 }
1991
1992 static void vl_api_dhcp_compl_event_t_handler_json
1993   (vl_api_dhcp_compl_event_t * mp)
1994 {
1995   /* JSON output not supported */
1996 }
1997
1998 static void
1999 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2000                               u32 counter)
2001 {
2002   vat_main_t *vam = &vat_main;
2003   static u64 default_counter = 0;
2004
2005   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2006                            NULL);
2007   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2008                            sw_if_index, default_counter);
2009   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2010 }
2011
2012 static void
2013 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2014                                 interface_counter_t counter)
2015 {
2016   vat_main_t *vam = &vat_main;
2017   static interface_counter_t default_counter = { 0, };
2018
2019   vec_validate_init_empty (vam->combined_interface_counters,
2020                            vnet_counter_type, NULL);
2021   vec_validate_init_empty (vam->combined_interface_counters
2022                            [vnet_counter_type], sw_if_index, default_counter);
2023   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2024 }
2025
2026 static void vl_api_vnet_interface_counters_t_handler
2027   (vl_api_vnet_interface_counters_t * mp)
2028 {
2029   /* not supported */
2030 }
2031
2032 static void vl_api_vnet_interface_counters_t_handler_json
2033   (vl_api_vnet_interface_counters_t * mp)
2034 {
2035   interface_counter_t counter;
2036   vlib_counter_t *v;
2037   u64 *v_packets;
2038   u64 packets;
2039   u32 count;
2040   u32 first_sw_if_index;
2041   int i;
2042
2043   count = ntohl (mp->count);
2044   first_sw_if_index = ntohl (mp->first_sw_if_index);
2045
2046   if (!mp->is_combined)
2047     {
2048       v_packets = (u64 *) & mp->data;
2049       for (i = 0; i < count; i++)
2050         {
2051           packets =
2052             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2053           set_simple_interface_counter (mp->vnet_counter_type,
2054                                         first_sw_if_index + i, packets);
2055           v_packets++;
2056         }
2057     }
2058   else
2059     {
2060       v = (vlib_counter_t *) & mp->data;
2061       for (i = 0; i < count; i++)
2062         {
2063           counter.packets =
2064             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2065           counter.bytes =
2066             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2067           set_combined_interface_counter (mp->vnet_counter_type,
2068                                           first_sw_if_index + i, counter);
2069           v++;
2070         }
2071     }
2072 }
2073
2074 static u32
2075 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2076 {
2077   vat_main_t *vam = &vat_main;
2078   u32 i;
2079
2080   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2081     {
2082       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2083         {
2084           return i;
2085         }
2086     }
2087   return ~0;
2088 }
2089
2090 static u32
2091 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2092 {
2093   vat_main_t *vam = &vat_main;
2094   u32 i;
2095
2096   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2097     {
2098       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2099         {
2100           return i;
2101         }
2102     }
2103   return ~0;
2104 }
2105
2106 static void vl_api_vnet_ip4_fib_counters_t_handler
2107   (vl_api_vnet_ip4_fib_counters_t * mp)
2108 {
2109   /* not supported */
2110 }
2111
2112 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2113   (vl_api_vnet_ip4_fib_counters_t * mp)
2114 {
2115   vat_main_t *vam = &vat_main;
2116   vl_api_ip4_fib_counter_t *v;
2117   ip4_fib_counter_t *counter;
2118   struct in_addr ip4;
2119   u32 vrf_id;
2120   u32 vrf_index;
2121   u32 count;
2122   int i;
2123
2124   vrf_id = ntohl (mp->vrf_id);
2125   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2126   if (~0 == vrf_index)
2127     {
2128       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2129       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2130       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2131       vec_validate (vam->ip4_fib_counters, vrf_index);
2132       vam->ip4_fib_counters[vrf_index] = NULL;
2133     }
2134
2135   vec_free (vam->ip4_fib_counters[vrf_index]);
2136   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2137   count = ntohl (mp->count);
2138   for (i = 0; i < count; i++)
2139     {
2140       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2141       counter = &vam->ip4_fib_counters[vrf_index][i];
2142       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2143       counter->address = ip4;
2144       counter->address_length = v->address_length;
2145       counter->packets = clib_net_to_host_u64 (v->packets);
2146       counter->bytes = clib_net_to_host_u64 (v->bytes);
2147       v++;
2148     }
2149 }
2150
2151 static void vl_api_vnet_ip4_nbr_counters_t_handler
2152   (vl_api_vnet_ip4_nbr_counters_t * mp)
2153 {
2154   /* not supported */
2155 }
2156
2157 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2158   (vl_api_vnet_ip4_nbr_counters_t * mp)
2159 {
2160   vat_main_t *vam = &vat_main;
2161   vl_api_ip4_nbr_counter_t *v;
2162   ip4_nbr_counter_t *counter;
2163   u32 sw_if_index;
2164   u32 count;
2165   int i;
2166
2167   sw_if_index = ntohl (mp->sw_if_index);
2168   count = ntohl (mp->count);
2169   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2170
2171   if (mp->begin)
2172     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2173
2174   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2175   for (i = 0; i < count; i++)
2176     {
2177       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2178       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2179       counter->address.s_addr = v->address;
2180       counter->packets = clib_net_to_host_u64 (v->packets);
2181       counter->bytes = clib_net_to_host_u64 (v->bytes);
2182       counter->linkt = v->link_type;
2183       v++;
2184     }
2185 }
2186
2187 static void vl_api_vnet_ip6_fib_counters_t_handler
2188   (vl_api_vnet_ip6_fib_counters_t * mp)
2189 {
2190   /* not supported */
2191 }
2192
2193 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2194   (vl_api_vnet_ip6_fib_counters_t * mp)
2195 {
2196   vat_main_t *vam = &vat_main;
2197   vl_api_ip6_fib_counter_t *v;
2198   ip6_fib_counter_t *counter;
2199   struct in6_addr ip6;
2200   u32 vrf_id;
2201   u32 vrf_index;
2202   u32 count;
2203   int i;
2204
2205   vrf_id = ntohl (mp->vrf_id);
2206   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2207   if (~0 == vrf_index)
2208     {
2209       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2210       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2211       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2212       vec_validate (vam->ip6_fib_counters, vrf_index);
2213       vam->ip6_fib_counters[vrf_index] = NULL;
2214     }
2215
2216   vec_free (vam->ip6_fib_counters[vrf_index]);
2217   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2218   count = ntohl (mp->count);
2219   for (i = 0; i < count; i++)
2220     {
2221       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2222       counter = &vam->ip6_fib_counters[vrf_index][i];
2223       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2224       counter->address = ip6;
2225       counter->address_length = v->address_length;
2226       counter->packets = clib_net_to_host_u64 (v->packets);
2227       counter->bytes = clib_net_to_host_u64 (v->bytes);
2228       v++;
2229     }
2230 }
2231
2232 static void vl_api_vnet_ip6_nbr_counters_t_handler
2233   (vl_api_vnet_ip6_nbr_counters_t * mp)
2234 {
2235   /* not supported */
2236 }
2237
2238 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2239   (vl_api_vnet_ip6_nbr_counters_t * mp)
2240 {
2241   vat_main_t *vam = &vat_main;
2242   vl_api_ip6_nbr_counter_t *v;
2243   ip6_nbr_counter_t *counter;
2244   struct in6_addr ip6;
2245   u32 sw_if_index;
2246   u32 count;
2247   int i;
2248
2249   sw_if_index = ntohl (mp->sw_if_index);
2250   count = ntohl (mp->count);
2251   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2252
2253   if (mp->begin)
2254     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2255
2256   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2257   for (i = 0; i < count; i++)
2258     {
2259       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2260       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2261       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2262       counter->address = ip6;
2263       counter->packets = clib_net_to_host_u64 (v->packets);
2264       counter->bytes = clib_net_to_host_u64 (v->bytes);
2265       v++;
2266     }
2267 }
2268
2269 static void vl_api_get_first_msg_id_reply_t_handler
2270   (vl_api_get_first_msg_id_reply_t * mp)
2271 {
2272   vat_main_t *vam = &vat_main;
2273   i32 retval = ntohl (mp->retval);
2274
2275   if (vam->async_mode)
2276     {
2277       vam->async_errors += (retval < 0);
2278     }
2279   else
2280     {
2281       vam->retval = retval;
2282       vam->result_ready = 1;
2283     }
2284   if (retval >= 0)
2285     {
2286       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2287     }
2288 }
2289
2290 static void vl_api_get_first_msg_id_reply_t_handler_json
2291   (vl_api_get_first_msg_id_reply_t * mp)
2292 {
2293   vat_main_t *vam = &vat_main;
2294   vat_json_node_t node;
2295
2296   vat_json_init_object (&node);
2297   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2298   vat_json_object_add_uint (&node, "first_msg_id",
2299                             (uint) ntohs (mp->first_msg_id));
2300
2301   vat_json_print (vam->ofp, &node);
2302   vat_json_free (&node);
2303
2304   vam->retval = ntohl (mp->retval);
2305   vam->result_ready = 1;
2306 }
2307
2308 static void vl_api_get_node_graph_reply_t_handler
2309   (vl_api_get_node_graph_reply_t * mp)
2310 {
2311   vat_main_t *vam = &vat_main;
2312   api_main_t *am = &api_main;
2313   i32 retval = ntohl (mp->retval);
2314   u8 *pvt_copy, *reply;
2315   void *oldheap;
2316   vlib_node_t *node;
2317   int i;
2318
2319   if (vam->async_mode)
2320     {
2321       vam->async_errors += (retval < 0);
2322     }
2323   else
2324     {
2325       vam->retval = retval;
2326       vam->result_ready = 1;
2327     }
2328
2329   /* "Should never happen..." */
2330   if (retval != 0)
2331     return;
2332
2333   reply = (u8 *) (mp->reply_in_shmem);
2334   pvt_copy = vec_dup (reply);
2335
2336   /* Toss the shared-memory original... */
2337   pthread_mutex_lock (&am->vlib_rp->mutex);
2338   oldheap = svm_push_data_heap (am->vlib_rp);
2339
2340   vec_free (reply);
2341
2342   svm_pop_heap (oldheap);
2343   pthread_mutex_unlock (&am->vlib_rp->mutex);
2344
2345   if (vam->graph_nodes)
2346     {
2347       hash_free (vam->graph_node_index_by_name);
2348
2349       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2350         {
2351           node = vam->graph_nodes[i];
2352           vec_free (node->name);
2353           vec_free (node->next_nodes);
2354           vec_free (node);
2355         }
2356       vec_free (vam->graph_nodes);
2357     }
2358
2359   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2360   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2361   vec_free (pvt_copy);
2362
2363   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2364     {
2365       node = vam->graph_nodes[i];
2366       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2367     }
2368 }
2369
2370 static void vl_api_get_node_graph_reply_t_handler_json
2371   (vl_api_get_node_graph_reply_t * mp)
2372 {
2373   vat_main_t *vam = &vat_main;
2374   api_main_t *am = &api_main;
2375   void *oldheap;
2376   vat_json_node_t node;
2377   u8 *reply;
2378
2379   /* $$$$ make this real? */
2380   vat_json_init_object (&node);
2381   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2382   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2383
2384   reply = (u8 *) (mp->reply_in_shmem);
2385
2386   /* Toss the shared-memory original... */
2387   pthread_mutex_lock (&am->vlib_rp->mutex);
2388   oldheap = svm_push_data_heap (am->vlib_rp);
2389
2390   vec_free (reply);
2391
2392   svm_pop_heap (oldheap);
2393   pthread_mutex_unlock (&am->vlib_rp->mutex);
2394
2395   vat_json_print (vam->ofp, &node);
2396   vat_json_free (&node);
2397
2398   vam->retval = ntohl (mp->retval);
2399   vam->result_ready = 1;
2400 }
2401
2402 static void
2403 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2404 {
2405   vat_main_t *vam = &vat_main;
2406   u8 *s = 0;
2407
2408   if (mp->local)
2409     {
2410       s = format (s, "%=16d%=16d%=16d",
2411                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2412     }
2413   else
2414     {
2415       s = format (s, "%=16U%=16d%=16d",
2416                   mp->is_ipv6 ? format_ip6_address :
2417                   format_ip4_address,
2418                   mp->ip_address, mp->priority, mp->weight);
2419     }
2420
2421   print (vam->ofp, "%v", s);
2422   vec_free (s);
2423 }
2424
2425 static void
2426 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2427 {
2428   vat_main_t *vam = &vat_main;
2429   vat_json_node_t *node = NULL;
2430   struct in6_addr ip6;
2431   struct in_addr ip4;
2432
2433   if (VAT_JSON_ARRAY != vam->json_tree.type)
2434     {
2435       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2436       vat_json_init_array (&vam->json_tree);
2437     }
2438   node = vat_json_array_add (&vam->json_tree);
2439   vat_json_init_object (node);
2440
2441   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2442   vat_json_object_add_uint (node, "priority", mp->priority);
2443   vat_json_object_add_uint (node, "weight", mp->weight);
2444
2445   if (mp->local)
2446     vat_json_object_add_uint (node, "sw_if_index",
2447                               clib_net_to_host_u32 (mp->sw_if_index));
2448   else
2449     {
2450       if (mp->is_ipv6)
2451         {
2452           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2453           vat_json_object_add_ip6 (node, "address", ip6);
2454         }
2455       else
2456         {
2457           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2458           vat_json_object_add_ip4 (node, "address", ip4);
2459         }
2460     }
2461 }
2462
2463 static void
2464 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2465                                           mp)
2466 {
2467   vat_main_t *vam = &vat_main;
2468   u8 *ls_name = 0;
2469
2470   ls_name = format (0, "%s", mp->ls_name);
2471
2472   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2473          ls_name);
2474   vec_free (ls_name);
2475 }
2476
2477 static void
2478   vl_api_one_locator_set_details_t_handler_json
2479   (vl_api_one_locator_set_details_t * mp)
2480 {
2481   vat_main_t *vam = &vat_main;
2482   vat_json_node_t *node = 0;
2483   u8 *ls_name = 0;
2484
2485   ls_name = format (0, "%s", mp->ls_name);
2486   vec_add1 (ls_name, 0);
2487
2488   if (VAT_JSON_ARRAY != vam->json_tree.type)
2489     {
2490       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2491       vat_json_init_array (&vam->json_tree);
2492     }
2493   node = vat_json_array_add (&vam->json_tree);
2494
2495   vat_json_init_object (node);
2496   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2497   vat_json_object_add_uint (node, "ls_index",
2498                             clib_net_to_host_u32 (mp->ls_index));
2499   vec_free (ls_name);
2500 }
2501
2502 static u8 *
2503 format_lisp_flat_eid (u8 * s, va_list * args)
2504 {
2505   u32 type = va_arg (*args, u32);
2506   u8 *eid = va_arg (*args, u8 *);
2507   u32 eid_len = va_arg (*args, u32);
2508
2509   switch (type)
2510     {
2511     case 0:
2512       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2513     case 1:
2514       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2515     case 2:
2516       return format (s, "%U", format_ethernet_address, eid);
2517     }
2518   return 0;
2519 }
2520
2521 static u8 *
2522 format_lisp_eid_vat (u8 * s, va_list * args)
2523 {
2524   u32 type = va_arg (*args, u32);
2525   u8 *eid = va_arg (*args, u8 *);
2526   u32 eid_len = va_arg (*args, u32);
2527   u8 *seid = va_arg (*args, u8 *);
2528   u32 seid_len = va_arg (*args, u32);
2529   u32 is_src_dst = va_arg (*args, u32);
2530
2531   if (is_src_dst)
2532     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2533
2534   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2535
2536   return s;
2537 }
2538
2539 static void
2540 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2541 {
2542   vat_main_t *vam = &vat_main;
2543   u8 *s = 0, *eid = 0;
2544
2545   if (~0 == mp->locator_set_index)
2546     s = format (0, "action: %d", mp->action);
2547   else
2548     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2549
2550   eid = format (0, "%U", format_lisp_eid_vat,
2551                 mp->eid_type,
2552                 mp->eid,
2553                 mp->eid_prefix_len,
2554                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2555   vec_add1 (eid, 0);
2556
2557   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2558          clib_net_to_host_u32 (mp->vni),
2559          eid,
2560          mp->is_local ? "local" : "remote",
2561          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2562          clib_net_to_host_u16 (mp->key_id), mp->key);
2563
2564   vec_free (s);
2565   vec_free (eid);
2566 }
2567
2568 static void
2569 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2570                                              * mp)
2571 {
2572   vat_main_t *vam = &vat_main;
2573   vat_json_node_t *node = 0;
2574   u8 *eid = 0;
2575
2576   if (VAT_JSON_ARRAY != vam->json_tree.type)
2577     {
2578       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2579       vat_json_init_array (&vam->json_tree);
2580     }
2581   node = vat_json_array_add (&vam->json_tree);
2582
2583   vat_json_init_object (node);
2584   if (~0 == mp->locator_set_index)
2585     vat_json_object_add_uint (node, "action", mp->action);
2586   else
2587     vat_json_object_add_uint (node, "locator_set_index",
2588                               clib_net_to_host_u32 (mp->locator_set_index));
2589
2590   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2591   eid = format (0, "%U", format_lisp_eid_vat,
2592                 mp->eid_type,
2593                 mp->eid,
2594                 mp->eid_prefix_len,
2595                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2596   vec_add1 (eid, 0);
2597   vat_json_object_add_string_copy (node, "eid", eid);
2598   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2599   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2600   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2601
2602   if (mp->key_id)
2603     {
2604       vat_json_object_add_uint (node, "key_id",
2605                                 clib_net_to_host_u16 (mp->key_id));
2606       vat_json_object_add_string_copy (node, "key", mp->key);
2607     }
2608   vec_free (eid);
2609 }
2610
2611 static void
2612   vl_api_one_eid_table_map_details_t_handler
2613   (vl_api_one_eid_table_map_details_t * mp)
2614 {
2615   vat_main_t *vam = &vat_main;
2616
2617   u8 *line = format (0, "%=10d%=10d",
2618                      clib_net_to_host_u32 (mp->vni),
2619                      clib_net_to_host_u32 (mp->dp_table));
2620   print (vam->ofp, "%v", line);
2621   vec_free (line);
2622 }
2623
2624 static void
2625   vl_api_one_eid_table_map_details_t_handler_json
2626   (vl_api_one_eid_table_map_details_t * mp)
2627 {
2628   vat_main_t *vam = &vat_main;
2629   vat_json_node_t *node = NULL;
2630
2631   if (VAT_JSON_ARRAY != vam->json_tree.type)
2632     {
2633       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2634       vat_json_init_array (&vam->json_tree);
2635     }
2636   node = vat_json_array_add (&vam->json_tree);
2637   vat_json_init_object (node);
2638   vat_json_object_add_uint (node, "dp_table",
2639                             clib_net_to_host_u32 (mp->dp_table));
2640   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2641 }
2642
2643 static void
2644   vl_api_one_eid_table_vni_details_t_handler
2645   (vl_api_one_eid_table_vni_details_t * mp)
2646 {
2647   vat_main_t *vam = &vat_main;
2648
2649   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2650   print (vam->ofp, "%v", line);
2651   vec_free (line);
2652 }
2653
2654 static void
2655   vl_api_one_eid_table_vni_details_t_handler_json
2656   (vl_api_one_eid_table_vni_details_t * mp)
2657 {
2658   vat_main_t *vam = &vat_main;
2659   vat_json_node_t *node = NULL;
2660
2661   if (VAT_JSON_ARRAY != vam->json_tree.type)
2662     {
2663       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2664       vat_json_init_array (&vam->json_tree);
2665     }
2666   node = vat_json_array_add (&vam->json_tree);
2667   vat_json_init_object (node);
2668   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2669 }
2670
2671 static void
2672   vl_api_show_one_map_register_state_reply_t_handler
2673   (vl_api_show_one_map_register_state_reply_t * mp)
2674 {
2675   vat_main_t *vam = &vat_main;
2676   int retval = clib_net_to_host_u32 (mp->retval);
2677
2678   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2679
2680   vam->retval = retval;
2681   vam->result_ready = 1;
2682 }
2683
2684 static void
2685   vl_api_show_one_map_register_state_reply_t_handler_json
2686   (vl_api_show_one_map_register_state_reply_t * mp)
2687 {
2688   vat_main_t *vam = &vat_main;
2689   vat_json_node_t _node, *node = &_node;
2690   int retval = clib_net_to_host_u32 (mp->retval);
2691
2692   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2693
2694   vat_json_init_object (node);
2695   vat_json_object_add_string_copy (node, "state", s);
2696
2697   vat_json_print (vam->ofp, node);
2698   vat_json_free (node);
2699
2700   vam->retval = retval;
2701   vam->result_ready = 1;
2702   vec_free (s);
2703 }
2704
2705 static void
2706   vl_api_show_one_rloc_probe_state_reply_t_handler
2707   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2708 {
2709   vat_main_t *vam = &vat_main;
2710   int retval = clib_net_to_host_u32 (mp->retval);
2711
2712   if (retval)
2713     goto end;
2714
2715   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2716 end:
2717   vam->retval = retval;
2718   vam->result_ready = 1;
2719 }
2720
2721 static void
2722   vl_api_show_one_rloc_probe_state_reply_t_handler_json
2723   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2724 {
2725   vat_main_t *vam = &vat_main;
2726   vat_json_node_t _node, *node = &_node;
2727   int retval = clib_net_to_host_u32 (mp->retval);
2728
2729   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2730   vat_json_init_object (node);
2731   vat_json_object_add_string_copy (node, "state", s);
2732
2733   vat_json_print (vam->ofp, node);
2734   vat_json_free (node);
2735
2736   vam->retval = retval;
2737   vam->result_ready = 1;
2738   vec_free (s);
2739 }
2740
2741 static void
2742 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
2743 {
2744   e->dp_table = clib_net_to_host_u32 (e->dp_table);
2745   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
2746 }
2747
2748 static void
2749   gpe_fwd_entries_get_reply_t_net_to_host
2750   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2751 {
2752   u32 i;
2753
2754   mp->count = clib_net_to_host_u32 (mp->count);
2755   for (i = 0; i < mp->count; i++)
2756     {
2757       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
2758     }
2759 }
2760
2761 static u8 *
2762 format_gpe_encap_mode (u8 * s, va_list * args)
2763 {
2764   u32 mode = va_arg (*args, u32);
2765
2766   switch (mode)
2767     {
2768     case 0:
2769       return format (s, "lisp");
2770     case 1:
2771       return format (s, "vxlan");
2772     }
2773   return 0;
2774 }
2775
2776 static void
2777   vl_api_gpe_get_encap_mode_reply_t_handler
2778   (vl_api_gpe_get_encap_mode_reply_t * mp)
2779 {
2780   vat_main_t *vam = &vat_main;
2781
2782   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
2783   vam->retval = ntohl (mp->retval);
2784   vam->result_ready = 1;
2785 }
2786
2787 static void
2788   vl_api_gpe_get_encap_mode_reply_t_handler_json
2789   (vl_api_gpe_get_encap_mode_reply_t * mp)
2790 {
2791   vat_main_t *vam = &vat_main;
2792   vat_json_node_t node;
2793
2794   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
2795   vec_add1 (encap_mode, 0);
2796
2797   vat_json_init_object (&node);
2798   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
2799
2800   vec_free (encap_mode);
2801   vat_json_print (vam->ofp, &node);
2802   vat_json_free (&node);
2803
2804   vam->retval = ntohl (mp->retval);
2805   vam->result_ready = 1;
2806 }
2807
2808 static void
2809   vl_api_gpe_fwd_entry_path_details_t_handler
2810   (vl_api_gpe_fwd_entry_path_details_t * mp)
2811 {
2812   vat_main_t *vam = &vat_main;
2813   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2814
2815   if (mp->lcl_loc.is_ip4)
2816     format_ip_address_fcn = format_ip4_address;
2817   else
2818     format_ip_address_fcn = format_ip6_address;
2819
2820   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
2821          format_ip_address_fcn, &mp->lcl_loc,
2822          format_ip_address_fcn, &mp->rmt_loc);
2823 }
2824
2825 static void
2826 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
2827 {
2828   struct in6_addr ip6;
2829   struct in_addr ip4;
2830
2831   if (loc->is_ip4)
2832     {
2833       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
2834       vat_json_object_add_ip4 (n, "address", ip4);
2835     }
2836   else
2837     {
2838       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
2839       vat_json_object_add_ip6 (n, "address", ip6);
2840     }
2841   vat_json_object_add_uint (n, "weight", loc->weight);
2842 }
2843
2844 static void
2845   vl_api_gpe_fwd_entry_path_details_t_handler_json
2846   (vl_api_gpe_fwd_entry_path_details_t * mp)
2847 {
2848   vat_main_t *vam = &vat_main;
2849   vat_json_node_t *node = NULL;
2850   vat_json_node_t *loc_node;
2851
2852   if (VAT_JSON_ARRAY != vam->json_tree.type)
2853     {
2854       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2855       vat_json_init_array (&vam->json_tree);
2856     }
2857   node = vat_json_array_add (&vam->json_tree);
2858   vat_json_init_object (node);
2859
2860   loc_node = vat_json_object_add (node, "local_locator");
2861   vat_json_init_object (loc_node);
2862   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
2863
2864   loc_node = vat_json_object_add (node, "remote_locator");
2865   vat_json_init_object (loc_node);
2866   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
2867 }
2868
2869 static void
2870   vl_api_gpe_fwd_entries_get_reply_t_handler
2871   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2872 {
2873   vat_main_t *vam = &vat_main;
2874   u32 i;
2875   int retval = clib_net_to_host_u32 (mp->retval);
2876   vl_api_gpe_fwd_entry_t *e;
2877
2878   if (retval)
2879     goto end;
2880
2881   gpe_fwd_entries_get_reply_t_net_to_host (mp);
2882
2883   for (i = 0; i < mp->count; i++)
2884     {
2885       e = &mp->entries[i];
2886       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
2887              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
2888              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
2889     }
2890
2891 end:
2892   vam->retval = retval;
2893   vam->result_ready = 1;
2894 }
2895
2896 static void
2897   vl_api_gpe_fwd_entries_get_reply_t_handler_json
2898   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2899 {
2900   u8 *s = 0;
2901   vat_main_t *vam = &vat_main;
2902   vat_json_node_t *e = 0, root;
2903   u32 i;
2904   int retval = clib_net_to_host_u32 (mp->retval);
2905   vl_api_gpe_fwd_entry_t *fwd;
2906
2907   if (retval)
2908     goto end;
2909
2910   gpe_fwd_entries_get_reply_t_net_to_host (mp);
2911   vat_json_init_array (&root);
2912
2913   for (i = 0; i < mp->count; i++)
2914     {
2915       e = vat_json_array_add (&root);
2916       fwd = &mp->entries[i];
2917
2918       vat_json_init_object (e);
2919       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
2920       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
2921
2922       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
2923                   fwd->leid_prefix_len);
2924       vec_add1 (s, 0);
2925       vat_json_object_add_string_copy (e, "leid", s);
2926       vec_free (s);
2927
2928       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
2929                   fwd->reid_prefix_len);
2930       vec_add1 (s, 0);
2931       vat_json_object_add_string_copy (e, "reid", s);
2932       vec_free (s);
2933     }
2934
2935   vat_json_print (vam->ofp, &root);
2936   vat_json_free (&root);
2937
2938 end:
2939   vam->retval = retval;
2940   vam->result_ready = 1;
2941 }
2942
2943 static void
2944   vl_api_one_adjacencies_get_reply_t_handler
2945   (vl_api_one_adjacencies_get_reply_t * mp)
2946 {
2947   vat_main_t *vam = &vat_main;
2948   u32 i, n;
2949   int retval = clib_net_to_host_u32 (mp->retval);
2950   vl_api_one_adjacency_t *a;
2951
2952   if (retval)
2953     goto end;
2954
2955   n = clib_net_to_host_u32 (mp->count);
2956
2957   for (i = 0; i < n; i++)
2958     {
2959       a = &mp->adjacencies[i];
2960       print (vam->ofp, "%U %40U",
2961              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2962              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
2963     }
2964
2965 end:
2966   vam->retval = retval;
2967   vam->result_ready = 1;
2968 }
2969
2970 static void
2971   vl_api_one_adjacencies_get_reply_t_handler_json
2972   (vl_api_one_adjacencies_get_reply_t * mp)
2973 {
2974   u8 *s = 0;
2975   vat_main_t *vam = &vat_main;
2976   vat_json_node_t *e = 0, root;
2977   u32 i, n;
2978   int retval = clib_net_to_host_u32 (mp->retval);
2979   vl_api_one_adjacency_t *a;
2980
2981   if (retval)
2982     goto end;
2983
2984   n = clib_net_to_host_u32 (mp->count);
2985   vat_json_init_array (&root);
2986
2987   for (i = 0; i < n; i++)
2988     {
2989       e = vat_json_array_add (&root);
2990       a = &mp->adjacencies[i];
2991
2992       vat_json_init_object (e);
2993       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2994                   a->leid_prefix_len);
2995       vec_add1 (s, 0);
2996       vat_json_object_add_string_copy (e, "leid", s);
2997       vec_free (s);
2998
2999       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3000                   a->reid_prefix_len);
3001       vec_add1 (s, 0);
3002       vat_json_object_add_string_copy (e, "reid", s);
3003       vec_free (s);
3004     }
3005
3006   vat_json_print (vam->ofp, &root);
3007   vat_json_free (&root);
3008
3009 end:
3010   vam->retval = retval;
3011   vam->result_ready = 1;
3012 }
3013
3014 static void
3015 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3016 {
3017   vat_main_t *vam = &vat_main;
3018
3019   print (vam->ofp, "%=20U",
3020          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3021          mp->ip_address);
3022 }
3023
3024 static void
3025   vl_api_one_map_server_details_t_handler_json
3026   (vl_api_one_map_server_details_t * mp)
3027 {
3028   vat_main_t *vam = &vat_main;
3029   vat_json_node_t *node = NULL;
3030   struct in6_addr ip6;
3031   struct in_addr ip4;
3032
3033   if (VAT_JSON_ARRAY != vam->json_tree.type)
3034     {
3035       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3036       vat_json_init_array (&vam->json_tree);
3037     }
3038   node = vat_json_array_add (&vam->json_tree);
3039
3040   vat_json_init_object (node);
3041   if (mp->is_ipv6)
3042     {
3043       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3044       vat_json_object_add_ip6 (node, "map-server", ip6);
3045     }
3046   else
3047     {
3048       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3049       vat_json_object_add_ip4 (node, "map-server", ip4);
3050     }
3051 }
3052
3053 static void
3054 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3055                                            * mp)
3056 {
3057   vat_main_t *vam = &vat_main;
3058
3059   print (vam->ofp, "%=20U",
3060          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3061          mp->ip_address);
3062 }
3063
3064 static void
3065   vl_api_one_map_resolver_details_t_handler_json
3066   (vl_api_one_map_resolver_details_t * mp)
3067 {
3068   vat_main_t *vam = &vat_main;
3069   vat_json_node_t *node = NULL;
3070   struct in6_addr ip6;
3071   struct in_addr ip4;
3072
3073   if (VAT_JSON_ARRAY != vam->json_tree.type)
3074     {
3075       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3076       vat_json_init_array (&vam->json_tree);
3077     }
3078   node = vat_json_array_add (&vam->json_tree);
3079
3080   vat_json_init_object (node);
3081   if (mp->is_ipv6)
3082     {
3083       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3084       vat_json_object_add_ip6 (node, "map resolver", ip6);
3085     }
3086   else
3087     {
3088       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3089       vat_json_object_add_ip4 (node, "map resolver", ip4);
3090     }
3091 }
3092
3093 static void
3094 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
3095 {
3096   vat_main_t *vam = &vat_main;
3097   i32 retval = ntohl (mp->retval);
3098
3099   if (0 <= retval)
3100     {
3101       print (vam->ofp, "feature: %s\ngpe: %s",
3102              mp->feature_status ? "enabled" : "disabled",
3103              mp->gpe_status ? "enabled" : "disabled");
3104     }
3105
3106   vam->retval = retval;
3107   vam->result_ready = 1;
3108 }
3109
3110 static void
3111   vl_api_show_one_status_reply_t_handler_json
3112   (vl_api_show_one_status_reply_t * mp)
3113 {
3114   vat_main_t *vam = &vat_main;
3115   vat_json_node_t node;
3116   u8 *gpe_status = NULL;
3117   u8 *feature_status = NULL;
3118
3119   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
3120   feature_status = format (0, "%s",
3121                            mp->feature_status ? "enabled" : "disabled");
3122   vec_add1 (gpe_status, 0);
3123   vec_add1 (feature_status, 0);
3124
3125   vat_json_init_object (&node);
3126   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
3127   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
3128
3129   vec_free (gpe_status);
3130   vec_free (feature_status);
3131
3132   vat_json_print (vam->ofp, &node);
3133   vat_json_free (&node);
3134
3135   vam->retval = ntohl (mp->retval);
3136   vam->result_ready = 1;
3137 }
3138
3139 static void
3140   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
3141   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3142 {
3143   vat_main_t *vam = &vat_main;
3144   i32 retval = ntohl (mp->retval);
3145
3146   if (retval >= 0)
3147     {
3148       print (vam->ofp, "%=20s", mp->locator_set_name);
3149     }
3150
3151   vam->retval = retval;
3152   vam->result_ready = 1;
3153 }
3154
3155 static void
3156   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
3157   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3158 {
3159   vat_main_t *vam = &vat_main;
3160   vat_json_node_t *node = NULL;
3161
3162   if (VAT_JSON_ARRAY != vam->json_tree.type)
3163     {
3164       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3165       vat_json_init_array (&vam->json_tree);
3166     }
3167   node = vat_json_array_add (&vam->json_tree);
3168
3169   vat_json_init_object (node);
3170   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
3171
3172   vat_json_print (vam->ofp, node);
3173   vat_json_free (node);
3174
3175   vam->retval = ntohl (mp->retval);
3176   vam->result_ready = 1;
3177 }
3178
3179 static u8 *
3180 format_lisp_map_request_mode (u8 * s, va_list * args)
3181 {
3182   u32 mode = va_arg (*args, u32);
3183
3184   switch (mode)
3185     {
3186     case 0:
3187       return format (0, "dst-only");
3188     case 1:
3189       return format (0, "src-dst");
3190     }
3191   return 0;
3192 }
3193
3194 static void
3195   vl_api_show_one_map_request_mode_reply_t_handler
3196   (vl_api_show_one_map_request_mode_reply_t * mp)
3197 {
3198   vat_main_t *vam = &vat_main;
3199   i32 retval = ntohl (mp->retval);
3200
3201   if (0 <= retval)
3202     {
3203       u32 mode = mp->mode;
3204       print (vam->ofp, "map_request_mode: %U",
3205              format_lisp_map_request_mode, mode);
3206     }
3207
3208   vam->retval = retval;
3209   vam->result_ready = 1;
3210 }
3211
3212 static void
3213   vl_api_show_one_map_request_mode_reply_t_handler_json
3214   (vl_api_show_one_map_request_mode_reply_t * mp)
3215 {
3216   vat_main_t *vam = &vat_main;
3217   vat_json_node_t node;
3218   u8 *s = 0;
3219   u32 mode;
3220
3221   mode = mp->mode;
3222   s = format (0, "%U", format_lisp_map_request_mode, mode);
3223   vec_add1 (s, 0);
3224
3225   vat_json_init_object (&node);
3226   vat_json_object_add_string_copy (&node, "map_request_mode", s);
3227   vat_json_print (vam->ofp, &node);
3228   vat_json_free (&node);
3229
3230   vec_free (s);
3231   vam->retval = ntohl (mp->retval);
3232   vam->result_ready = 1;
3233 }
3234
3235 static void
3236 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
3237 {
3238   vat_main_t *vam = &vat_main;
3239   i32 retval = ntohl (mp->retval);
3240
3241   if (0 <= retval)
3242     {
3243       print (vam->ofp, "%-20s%-16s",
3244              mp->status ? "enabled" : "disabled",
3245              mp->status ? (char *) mp->locator_set_name : "");
3246     }
3247
3248   vam->retval = retval;
3249   vam->result_ready = 1;
3250 }
3251
3252 static void
3253 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
3254 {
3255   vat_main_t *vam = &vat_main;
3256   vat_json_node_t node;
3257   u8 *status = 0;
3258
3259   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3260   vec_add1 (status, 0);
3261
3262   vat_json_init_object (&node);
3263   vat_json_object_add_string_copy (&node, "status", status);
3264   if (mp->status)
3265     {
3266       vat_json_object_add_string_copy (&node, "locator_set",
3267                                        mp->locator_set_name);
3268     }
3269
3270   vec_free (status);
3271
3272   vat_json_print (vam->ofp, &node);
3273   vat_json_free (&node);
3274
3275   vam->retval = ntohl (mp->retval);
3276   vam->result_ready = 1;
3277 }
3278
3279 static u8 *
3280 format_policer_type (u8 * s, va_list * va)
3281 {
3282   u32 i = va_arg (*va, u32);
3283
3284   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
3285     s = format (s, "1r2c");
3286   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
3287     s = format (s, "1r3c");
3288   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
3289     s = format (s, "2r3c-2698");
3290   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
3291     s = format (s, "2r3c-4115");
3292   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
3293     s = format (s, "2r3c-mef5cf1");
3294   else
3295     s = format (s, "ILLEGAL");
3296   return s;
3297 }
3298
3299 static u8 *
3300 format_policer_rate_type (u8 * s, va_list * va)
3301 {
3302   u32 i = va_arg (*va, u32);
3303
3304   if (i == SSE2_QOS_RATE_KBPS)
3305     s = format (s, "kbps");
3306   else if (i == SSE2_QOS_RATE_PPS)
3307     s = format (s, "pps");
3308   else
3309     s = format (s, "ILLEGAL");
3310   return s;
3311 }
3312
3313 static u8 *
3314 format_policer_round_type (u8 * s, va_list * va)
3315 {
3316   u32 i = va_arg (*va, u32);
3317
3318   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3319     s = format (s, "closest");
3320   else if (i == SSE2_QOS_ROUND_TO_UP)
3321     s = format (s, "up");
3322   else if (i == SSE2_QOS_ROUND_TO_DOWN)
3323     s = format (s, "down");
3324   else
3325     s = format (s, "ILLEGAL");
3326   return s;
3327 }
3328
3329 static u8 *
3330 format_policer_action_type (u8 * s, va_list * va)
3331 {
3332   u32 i = va_arg (*va, u32);
3333
3334   if (i == SSE2_QOS_ACTION_DROP)
3335     s = format (s, "drop");
3336   else if (i == SSE2_QOS_ACTION_TRANSMIT)
3337     s = format (s, "transmit");
3338   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3339     s = format (s, "mark-and-transmit");
3340   else
3341     s = format (s, "ILLEGAL");
3342   return s;
3343 }
3344
3345 static u8 *
3346 format_dscp (u8 * s, va_list * va)
3347 {
3348   u32 i = va_arg (*va, u32);
3349   char *t = 0;
3350
3351   switch (i)
3352     {
3353 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3354       foreach_vnet_dscp
3355 #undef _
3356     default:
3357       return format (s, "ILLEGAL");
3358     }
3359   s = format (s, "%s", t);
3360   return s;
3361 }
3362
3363 static void
3364 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3365 {
3366   vat_main_t *vam = &vat_main;
3367   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3368
3369   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3370     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3371   else
3372     conform_dscp_str = format (0, "");
3373
3374   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3375     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3376   else
3377     exceed_dscp_str = format (0, "");
3378
3379   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3380     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3381   else
3382     violate_dscp_str = format (0, "");
3383
3384   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3385          "rate type %U, round type %U, %s rate, %s color-aware, "
3386          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3387          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3388          "conform action %U%s, exceed action %U%s, violate action %U%s",
3389          mp->name,
3390          format_policer_type, mp->type,
3391          ntohl (mp->cir),
3392          ntohl (mp->eir),
3393          clib_net_to_host_u64 (mp->cb),
3394          clib_net_to_host_u64 (mp->eb),
3395          format_policer_rate_type, mp->rate_type,
3396          format_policer_round_type, mp->round_type,
3397          mp->single_rate ? "single" : "dual",
3398          mp->color_aware ? "is" : "not",
3399          ntohl (mp->cir_tokens_per_period),
3400          ntohl (mp->pir_tokens_per_period),
3401          ntohl (mp->scale),
3402          ntohl (mp->current_limit),
3403          ntohl (mp->current_bucket),
3404          ntohl (mp->extended_limit),
3405          ntohl (mp->extended_bucket),
3406          clib_net_to_host_u64 (mp->last_update_time),
3407          format_policer_action_type, mp->conform_action_type,
3408          conform_dscp_str,
3409          format_policer_action_type, mp->exceed_action_type,
3410          exceed_dscp_str,
3411          format_policer_action_type, mp->violate_action_type,
3412          violate_dscp_str);
3413
3414   vec_free (conform_dscp_str);
3415   vec_free (exceed_dscp_str);
3416   vec_free (violate_dscp_str);
3417 }
3418
3419 static void vl_api_policer_details_t_handler_json
3420   (vl_api_policer_details_t * mp)
3421 {
3422   vat_main_t *vam = &vat_main;
3423   vat_json_node_t *node;
3424   u8 *rate_type_str, *round_type_str, *type_str;
3425   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3426
3427   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3428   round_type_str =
3429     format (0, "%U", format_policer_round_type, mp->round_type);
3430   type_str = format (0, "%U", format_policer_type, mp->type);
3431   conform_action_str = format (0, "%U", format_policer_action_type,
3432                                mp->conform_action_type);
3433   exceed_action_str = format (0, "%U", format_policer_action_type,
3434                               mp->exceed_action_type);
3435   violate_action_str = format (0, "%U", format_policer_action_type,
3436                                mp->violate_action_type);
3437
3438   if (VAT_JSON_ARRAY != vam->json_tree.type)
3439     {
3440       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3441       vat_json_init_array (&vam->json_tree);
3442     }
3443   node = vat_json_array_add (&vam->json_tree);
3444
3445   vat_json_init_object (node);
3446   vat_json_object_add_string_copy (node, "name", mp->name);
3447   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3448   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3449   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3450   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3451   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3452   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3453   vat_json_object_add_string_copy (node, "type", type_str);
3454   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3455   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3456   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3457   vat_json_object_add_uint (node, "cir_tokens_per_period",
3458                             ntohl (mp->cir_tokens_per_period));
3459   vat_json_object_add_uint (node, "eir_tokens_per_period",
3460                             ntohl (mp->pir_tokens_per_period));
3461   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3462   vat_json_object_add_uint (node, "current_bucket",
3463                             ntohl (mp->current_bucket));
3464   vat_json_object_add_uint (node, "extended_limit",
3465                             ntohl (mp->extended_limit));
3466   vat_json_object_add_uint (node, "extended_bucket",
3467                             ntohl (mp->extended_bucket));
3468   vat_json_object_add_uint (node, "last_update_time",
3469                             ntohl (mp->last_update_time));
3470   vat_json_object_add_string_copy (node, "conform_action",
3471                                    conform_action_str);
3472   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3473     {
3474       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3475       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3476       vec_free (dscp_str);
3477     }
3478   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3479   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3480     {
3481       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3482       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3483       vec_free (dscp_str);
3484     }
3485   vat_json_object_add_string_copy (node, "violate_action",
3486                                    violate_action_str);
3487   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3488     {
3489       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3490       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3491       vec_free (dscp_str);
3492     }
3493
3494   vec_free (rate_type_str);
3495   vec_free (round_type_str);
3496   vec_free (type_str);
3497   vec_free (conform_action_str);
3498   vec_free (exceed_action_str);
3499   vec_free (violate_action_str);
3500 }
3501
3502 static void
3503 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3504                                            mp)
3505 {
3506   vat_main_t *vam = &vat_main;
3507   int i, count = ntohl (mp->count);
3508
3509   if (count > 0)
3510     print (vam->ofp, "classify table ids (%d) : ", count);
3511   for (i = 0; i < count; i++)
3512     {
3513       print (vam->ofp, "%d", ntohl (mp->ids[i]));
3514       print (vam->ofp, (i < count - 1) ? "," : "");
3515     }
3516   vam->retval = ntohl (mp->retval);
3517   vam->result_ready = 1;
3518 }
3519
3520 static void
3521   vl_api_classify_table_ids_reply_t_handler_json
3522   (vl_api_classify_table_ids_reply_t * mp)
3523 {
3524   vat_main_t *vam = &vat_main;
3525   int i, count = ntohl (mp->count);
3526
3527   if (count > 0)
3528     {
3529       vat_json_node_t node;
3530
3531       vat_json_init_object (&node);
3532       for (i = 0; i < count; i++)
3533         {
3534           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3535         }
3536       vat_json_print (vam->ofp, &node);
3537       vat_json_free (&node);
3538     }
3539   vam->retval = ntohl (mp->retval);
3540   vam->result_ready = 1;
3541 }
3542
3543 static void
3544   vl_api_classify_table_by_interface_reply_t_handler
3545   (vl_api_classify_table_by_interface_reply_t * mp)
3546 {
3547   vat_main_t *vam = &vat_main;
3548   u32 table_id;
3549
3550   table_id = ntohl (mp->l2_table_id);
3551   if (table_id != ~0)
3552     print (vam->ofp, "l2 table id : %d", table_id);
3553   else
3554     print (vam->ofp, "l2 table id : No input ACL tables configured");
3555   table_id = ntohl (mp->ip4_table_id);
3556   if (table_id != ~0)
3557     print (vam->ofp, "ip4 table id : %d", table_id);
3558   else
3559     print (vam->ofp, "ip4 table id : No input ACL tables configured");
3560   table_id = ntohl (mp->ip6_table_id);
3561   if (table_id != ~0)
3562     print (vam->ofp, "ip6 table id : %d", table_id);
3563   else
3564     print (vam->ofp, "ip6 table id : No input ACL tables configured");
3565   vam->retval = ntohl (mp->retval);
3566   vam->result_ready = 1;
3567 }
3568
3569 static void
3570   vl_api_classify_table_by_interface_reply_t_handler_json
3571   (vl_api_classify_table_by_interface_reply_t * mp)
3572 {
3573   vat_main_t *vam = &vat_main;
3574   vat_json_node_t node;
3575
3576   vat_json_init_object (&node);
3577
3578   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3579   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3580   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3581
3582   vat_json_print (vam->ofp, &node);
3583   vat_json_free (&node);
3584
3585   vam->retval = ntohl (mp->retval);
3586   vam->result_ready = 1;
3587 }
3588
3589 static void vl_api_policer_add_del_reply_t_handler
3590   (vl_api_policer_add_del_reply_t * mp)
3591 {
3592   vat_main_t *vam = &vat_main;
3593   i32 retval = ntohl (mp->retval);
3594   if (vam->async_mode)
3595     {
3596       vam->async_errors += (retval < 0);
3597     }
3598   else
3599     {
3600       vam->retval = retval;
3601       vam->result_ready = 1;
3602       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3603         /*
3604          * Note: this is just barely thread-safe, depends on
3605          * the main thread spinning waiting for an answer...
3606          */
3607         errmsg ("policer index %d", ntohl (mp->policer_index));
3608     }
3609 }
3610
3611 static void vl_api_policer_add_del_reply_t_handler_json
3612   (vl_api_policer_add_del_reply_t * mp)
3613 {
3614   vat_main_t *vam = &vat_main;
3615   vat_json_node_t node;
3616
3617   vat_json_init_object (&node);
3618   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3619   vat_json_object_add_uint (&node, "policer_index",
3620                             ntohl (mp->policer_index));
3621
3622   vat_json_print (vam->ofp, &node);
3623   vat_json_free (&node);
3624
3625   vam->retval = ntohl (mp->retval);
3626   vam->result_ready = 1;
3627 }
3628
3629 /* Format hex dump. */
3630 u8 *
3631 format_hex_bytes (u8 * s, va_list * va)
3632 {
3633   u8 *bytes = va_arg (*va, u8 *);
3634   int n_bytes = va_arg (*va, int);
3635   uword i;
3636
3637   /* Print short or long form depending on byte count. */
3638   uword short_form = n_bytes <= 32;
3639   uword indent = format_get_indent (s);
3640
3641   if (n_bytes == 0)
3642     return s;
3643
3644   for (i = 0; i < n_bytes; i++)
3645     {
3646       if (!short_form && (i % 32) == 0)
3647         s = format (s, "%08x: ", i);
3648       s = format (s, "%02x", bytes[i]);
3649       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3650         s = format (s, "\n%U", format_white_space, indent);
3651     }
3652
3653   return s;
3654 }
3655
3656 static void
3657 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3658                                             * mp)
3659 {
3660   vat_main_t *vam = &vat_main;
3661   i32 retval = ntohl (mp->retval);
3662   if (retval == 0)
3663     {
3664       print (vam->ofp, "classify table info :");
3665       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3666              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3667              ntohl (mp->miss_next_index));
3668       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3669              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3670              ntohl (mp->match_n_vectors));
3671       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3672              ntohl (mp->mask_length));
3673     }
3674   vam->retval = retval;
3675   vam->result_ready = 1;
3676 }
3677
3678 static void
3679   vl_api_classify_table_info_reply_t_handler_json
3680   (vl_api_classify_table_info_reply_t * mp)
3681 {
3682   vat_main_t *vam = &vat_main;
3683   vat_json_node_t node;
3684
3685   i32 retval = ntohl (mp->retval);
3686   if (retval == 0)
3687     {
3688       vat_json_init_object (&node);
3689
3690       vat_json_object_add_int (&node, "sessions",
3691                                ntohl (mp->active_sessions));
3692       vat_json_object_add_int (&node, "nexttbl",
3693                                ntohl (mp->next_table_index));
3694       vat_json_object_add_int (&node, "nextnode",
3695                                ntohl (mp->miss_next_index));
3696       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3697       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3698       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3699       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3700                       ntohl (mp->mask_length), 0);
3701       vat_json_object_add_string_copy (&node, "mask", s);
3702
3703       vat_json_print (vam->ofp, &node);
3704       vat_json_free (&node);
3705     }
3706   vam->retval = ntohl (mp->retval);
3707   vam->result_ready = 1;
3708 }
3709
3710 static void
3711 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3712                                            mp)
3713 {
3714   vat_main_t *vam = &vat_main;
3715
3716   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3717          ntohl (mp->hit_next_index), ntohl (mp->advance),
3718          ntohl (mp->opaque_index));
3719   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3720          ntohl (mp->match_length));
3721 }
3722
3723 static void
3724   vl_api_classify_session_details_t_handler_json
3725   (vl_api_classify_session_details_t * mp)
3726 {
3727   vat_main_t *vam = &vat_main;
3728   vat_json_node_t *node = NULL;
3729
3730   if (VAT_JSON_ARRAY != vam->json_tree.type)
3731     {
3732       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3733       vat_json_init_array (&vam->json_tree);
3734     }
3735   node = vat_json_array_add (&vam->json_tree);
3736
3737   vat_json_init_object (node);
3738   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3739   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3740   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3741   u8 *s =
3742     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3743             0);
3744   vat_json_object_add_string_copy (node, "match", s);
3745 }
3746
3747 static void vl_api_pg_create_interface_reply_t_handler
3748   (vl_api_pg_create_interface_reply_t * mp)
3749 {
3750   vat_main_t *vam = &vat_main;
3751
3752   vam->retval = ntohl (mp->retval);
3753   vam->result_ready = 1;
3754 }
3755
3756 static void vl_api_pg_create_interface_reply_t_handler_json
3757   (vl_api_pg_create_interface_reply_t * mp)
3758 {
3759   vat_main_t *vam = &vat_main;
3760   vat_json_node_t node;
3761
3762   i32 retval = ntohl (mp->retval);
3763   if (retval == 0)
3764     {
3765       vat_json_init_object (&node);
3766
3767       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3768
3769       vat_json_print (vam->ofp, &node);
3770       vat_json_free (&node);
3771     }
3772   vam->retval = ntohl (mp->retval);
3773   vam->result_ready = 1;
3774 }
3775
3776 static void vl_api_policer_classify_details_t_handler
3777   (vl_api_policer_classify_details_t * mp)
3778 {
3779   vat_main_t *vam = &vat_main;
3780
3781   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3782          ntohl (mp->table_index));
3783 }
3784
3785 static void vl_api_policer_classify_details_t_handler_json
3786   (vl_api_policer_classify_details_t * mp)
3787 {
3788   vat_main_t *vam = &vat_main;
3789   vat_json_node_t *node;
3790
3791   if (VAT_JSON_ARRAY != vam->json_tree.type)
3792     {
3793       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3794       vat_json_init_array (&vam->json_tree);
3795     }
3796   node = vat_json_array_add (&vam->json_tree);
3797
3798   vat_json_init_object (node);
3799   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3800   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3801 }
3802
3803 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3804   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3805 {
3806   vat_main_t *vam = &vat_main;
3807   i32 retval = ntohl (mp->retval);
3808   if (vam->async_mode)
3809     {
3810       vam->async_errors += (retval < 0);
3811     }
3812   else
3813     {
3814       vam->retval = retval;
3815       vam->sw_if_index = ntohl (mp->sw_if_index);
3816       vam->result_ready = 1;
3817     }
3818 }
3819
3820 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3821   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3822 {
3823   vat_main_t *vam = &vat_main;
3824   vat_json_node_t node;
3825
3826   vat_json_init_object (&node);
3827   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3828   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3829
3830   vat_json_print (vam->ofp, &node);
3831   vat_json_free (&node);
3832
3833   vam->retval = ntohl (mp->retval);
3834   vam->result_ready = 1;
3835 }
3836
3837 static void vl_api_flow_classify_details_t_handler
3838   (vl_api_flow_classify_details_t * mp)
3839 {
3840   vat_main_t *vam = &vat_main;
3841
3842   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3843          ntohl (mp->table_index));
3844 }
3845
3846 static void vl_api_flow_classify_details_t_handler_json
3847   (vl_api_flow_classify_details_t * mp)
3848 {
3849   vat_main_t *vam = &vat_main;
3850   vat_json_node_t *node;
3851
3852   if (VAT_JSON_ARRAY != vam->json_tree.type)
3853     {
3854       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3855       vat_json_init_array (&vam->json_tree);
3856     }
3857   node = vat_json_array_add (&vam->json_tree);
3858
3859   vat_json_init_object (node);
3860   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3861   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3862 }
3863
3864
3865
3866 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3867 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3868 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3869 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3870 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
3871 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
3872 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
3873 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
3874 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
3875 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
3876
3877 /*
3878  * Generate boilerplate reply handlers, which
3879  * dig the return value out of the xxx_reply_t API message,
3880  * stick it into vam->retval, and set vam->result_ready
3881  *
3882  * Could also do this by pointing N message decode slots at
3883  * a single function, but that could break in subtle ways.
3884  */
3885
3886 #define foreach_standard_reply_retval_handler           \
3887 _(sw_interface_set_flags_reply)                         \
3888 _(sw_interface_add_del_address_reply)                   \
3889 _(sw_interface_set_table_reply)                         \
3890 _(sw_interface_set_mpls_enable_reply)                   \
3891 _(sw_interface_set_vpath_reply)                         \
3892 _(sw_interface_set_vxlan_bypass_reply)                  \
3893 _(sw_interface_set_l2_bridge_reply)                     \
3894 _(bridge_domain_add_del_reply)                          \
3895 _(sw_interface_set_l2_xconnect_reply)                   \
3896 _(l2fib_add_del_reply)                                  \
3897 _(ip_add_del_route_reply)                               \
3898 _(ip_mroute_add_del_reply)                              \
3899 _(mpls_route_add_del_reply)                             \
3900 _(mpls_ip_bind_unbind_reply)                            \
3901 _(proxy_arp_add_del_reply)                              \
3902 _(proxy_arp_intfc_enable_disable_reply)                 \
3903 _(sw_interface_set_unnumbered_reply)                    \
3904 _(ip_neighbor_add_del_reply)                            \
3905 _(reset_vrf_reply)                                      \
3906 _(oam_add_del_reply)                                    \
3907 _(reset_fib_reply)                                      \
3908 _(dhcp_proxy_config_reply)                              \
3909 _(dhcp_proxy_set_vss_reply)                             \
3910 _(dhcp_client_config_reply)                             \
3911 _(set_ip_flow_hash_reply)                               \
3912 _(sw_interface_ip6_enable_disable_reply)                \
3913 _(sw_interface_ip6_set_link_local_address_reply)        \
3914 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3915 _(sw_interface_ip6nd_ra_config_reply)                   \
3916 _(set_arp_neighbor_limit_reply)                         \
3917 _(l2_patch_add_del_reply)                               \
3918 _(sr_policy_add_reply)                                  \
3919 _(sr_policy_mod_reply)                                  \
3920 _(sr_policy_del_reply)                                  \
3921 _(sr_localsid_add_del_reply)                            \
3922 _(sr_steering_add_del_reply)                            \
3923 _(classify_add_del_session_reply)                       \
3924 _(classify_set_interface_ip_table_reply)                \
3925 _(classify_set_interface_l2_tables_reply)               \
3926 _(l2tpv3_set_tunnel_cookies_reply)                      \
3927 _(l2tpv3_interface_enable_disable_reply)                \
3928 _(l2tpv3_set_lookup_key_reply)                          \
3929 _(l2_fib_clear_table_reply)                             \
3930 _(l2_interface_efp_filter_reply)                        \
3931 _(l2_interface_vlan_tag_rewrite_reply)                  \
3932 _(modify_vhost_user_if_reply)                           \
3933 _(delete_vhost_user_if_reply)                           \
3934 _(want_ip4_arp_events_reply)                            \
3935 _(want_ip6_nd_events_reply)                             \
3936 _(input_acl_set_interface_reply)                        \
3937 _(ipsec_spd_add_del_reply)                              \
3938 _(ipsec_interface_add_del_spd_reply)                    \
3939 _(ipsec_spd_add_del_entry_reply)                        \
3940 _(ipsec_sad_add_del_entry_reply)                        \
3941 _(ipsec_sa_set_key_reply)                               \
3942 _(ikev2_profile_add_del_reply)                          \
3943 _(ikev2_profile_set_auth_reply)                         \
3944 _(ikev2_profile_set_id_reply)                           \
3945 _(ikev2_profile_set_ts_reply)                           \
3946 _(ikev2_set_local_key_reply)                            \
3947 _(ikev2_set_responder_reply)                            \
3948 _(ikev2_set_ike_transforms_reply)                       \
3949 _(ikev2_set_esp_transforms_reply)                       \
3950 _(ikev2_set_sa_lifetime_reply)                          \
3951 _(ikev2_initiate_sa_init_reply)                         \
3952 _(ikev2_initiate_del_ike_sa_reply)                      \
3953 _(ikev2_initiate_del_child_sa_reply)                    \
3954 _(ikev2_initiate_rekey_child_sa_reply)                  \
3955 _(delete_loopback_reply)                                \
3956 _(bd_ip_mac_add_del_reply)                              \
3957 _(map_del_domain_reply)                                 \
3958 _(map_add_del_rule_reply)                               \
3959 _(want_interface_events_reply)                          \
3960 _(want_stats_reply)                                     \
3961 _(cop_interface_enable_disable_reply)                   \
3962 _(cop_whitelist_enable_disable_reply)                   \
3963 _(sw_interface_clear_stats_reply)                       \
3964 _(ioam_enable_reply)                              \
3965 _(ioam_disable_reply)                              \
3966 _(one_add_del_locator_reply)                            \
3967 _(one_add_del_local_eid_reply)                          \
3968 _(one_add_del_remote_mapping_reply)                     \
3969 _(one_add_del_adjacency_reply)                          \
3970 _(one_add_del_map_resolver_reply)                       \
3971 _(one_add_del_map_server_reply)                         \
3972 _(one_enable_disable_reply)                             \
3973 _(one_rloc_probe_enable_disable_reply)                  \
3974 _(one_map_register_enable_disable_reply)                \
3975 _(one_pitr_set_locator_set_reply)                       \
3976 _(one_map_request_mode_reply)                           \
3977 _(one_add_del_map_request_itr_rlocs_reply)              \
3978 _(one_eid_table_add_del_map_reply)                      \
3979 _(gpe_add_del_fwd_entry_reply)                          \
3980 _(gpe_enable_disable_reply)                             \
3981 _(gpe_set_encap_mode_reply)                             \
3982 _(gpe_add_del_iface_reply)                              \
3983 _(vxlan_gpe_add_del_tunnel_reply)                       \
3984 _(af_packet_delete_reply)                               \
3985 _(policer_classify_set_interface_reply)                 \
3986 _(netmap_create_reply)                                  \
3987 _(netmap_delete_reply)                                  \
3988 _(set_ipfix_exporter_reply)                             \
3989 _(set_ipfix_classify_stream_reply)                      \
3990 _(ipfix_classify_table_add_del_reply)                   \
3991 _(flow_classify_set_interface_reply)                    \
3992 _(sw_interface_span_enable_disable_reply)               \
3993 _(pg_capture_reply)                                     \
3994 _(pg_enable_disable_reply)                              \
3995 _(ip_source_and_port_range_check_add_del_reply)         \
3996 _(ip_source_and_port_range_check_interface_add_del_reply)\
3997 _(delete_subif_reply)                                   \
3998 _(l2_interface_pbb_tag_rewrite_reply)                   \
3999 _(punt_reply)                                           \
4000 _(feature_enable_disable_reply)                         \
4001 _(sw_interface_tag_add_del_reply)                       \
4002 _(sw_interface_set_mtu_reply)
4003
4004 #define _(n)                                    \
4005     static void vl_api_##n##_t_handler          \
4006     (vl_api_##n##_t * mp)                       \
4007     {                                           \
4008         vat_main_t * vam = &vat_main;           \
4009         i32 retval = ntohl(mp->retval);         \
4010         if (vam->async_mode) {                  \
4011             vam->async_errors += (retval < 0);  \
4012         } else {                                \
4013             vam->retval = retval;               \
4014             vam->result_ready = 1;              \
4015         }                                       \
4016     }
4017 foreach_standard_reply_retval_handler;
4018 #undef _
4019
4020 #define _(n)                                    \
4021     static void vl_api_##n##_t_handler_json     \
4022     (vl_api_##n##_t * mp)                       \
4023     {                                           \
4024         vat_main_t * vam = &vat_main;           \
4025         vat_json_node_t node;                   \
4026         vat_json_init_object(&node);            \
4027         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
4028         vat_json_print(vam->ofp, &node);        \
4029         vam->retval = ntohl(mp->retval);        \
4030         vam->result_ready = 1;                  \
4031     }
4032 foreach_standard_reply_retval_handler;
4033 #undef _
4034
4035 /*
4036  * Table of message reply handlers, must include boilerplate handlers
4037  * we just generated
4038  */
4039
4040 #define foreach_vpe_api_reply_msg                                       \
4041 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
4042 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
4043 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
4044 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
4045 _(CONTROL_PING_REPLY, control_ping_reply)                               \
4046 _(CLI_REPLY, cli_reply)                                                 \
4047 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
4048 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
4049   sw_interface_add_del_address_reply)                                   \
4050 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
4051 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
4052 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
4053 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
4054 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
4055   sw_interface_set_l2_xconnect_reply)                                   \
4056 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
4057   sw_interface_set_l2_bridge_reply)                                     \
4058 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
4059 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
4060 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
4061 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
4062 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
4063 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
4064 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
4065 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
4066 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
4067 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
4068 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
4069 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
4070 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
4071 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
4072 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
4073 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
4074   proxy_arp_intfc_enable_disable_reply)                                 \
4075 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
4076 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
4077   sw_interface_set_unnumbered_reply)                                    \
4078 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
4079 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
4080 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
4081 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
4082 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
4083 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
4084 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
4085 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
4086 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
4087 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
4088 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
4089 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
4090   sw_interface_ip6_enable_disable_reply)                                \
4091 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
4092   sw_interface_ip6_set_link_local_address_reply)                        \
4093 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
4094   sw_interface_ip6nd_ra_prefix_reply)                                   \
4095 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
4096   sw_interface_ip6nd_ra_config_reply)                                   \
4097 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
4098 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
4099 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
4100 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
4101 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
4102 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
4103 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
4104 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
4105 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
4106 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
4107 classify_set_interface_ip_table_reply)                                  \
4108 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
4109   classify_set_interface_l2_tables_reply)                               \
4110 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
4111 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
4112 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
4113 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
4114 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
4115   l2tpv3_interface_enable_disable_reply)                                \
4116 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
4117 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
4118 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
4119 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
4120 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
4121 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
4122 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
4123 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
4124 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4125 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
4126 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
4127 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
4128 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
4129 _(SHOW_VERSION_REPLY, show_version_reply)                               \
4130 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
4131 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
4132 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
4133 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
4134 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
4135 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
4136 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
4137 _(IP6_ND_EVENT, ip6_nd_event)                                           \
4138 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
4139 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
4140 _(IP_DETAILS, ip_details)                                               \
4141 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
4142 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4143 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
4144 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
4145 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
4146 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
4147 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
4148 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
4149 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
4150 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
4151 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
4152 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
4153 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
4154 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
4155 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
4156 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
4157 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
4158 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
4159 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
4160 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
4161 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
4162 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
4163 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
4164 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
4165 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
4166 _(MAP_RULE_DETAILS, map_rule_details)                                   \
4167 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
4168 _(WANT_STATS_REPLY, want_stats_reply)                                   \
4169 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
4170 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4171 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4172 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
4173 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
4174 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
4175 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
4176 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
4177 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
4178 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
4179 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
4180 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
4181 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
4182 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
4183 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
4184 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
4185   one_map_register_enable_disable_reply)                                \
4186 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
4187   one_rloc_probe_enable_disable_reply)                                  \
4188 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
4189 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
4190 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
4191 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
4192 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
4193 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
4194 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
4195 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
4196 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
4197 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
4198 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
4199 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
4200 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
4201 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
4202 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
4203 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
4204 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
4205 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
4206   gpe_fwd_entry_path_details)                                           \
4207 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
4208 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
4209   one_add_del_map_request_itr_rlocs_reply)                              \
4210 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
4211   one_get_map_request_itr_rlocs_reply)                                  \
4212 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
4213 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
4214 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
4215 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
4216   show_one_map_register_state_reply)                                    \
4217 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
4218 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
4219 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
4220 _(POLICER_DETAILS, policer_details)                                     \
4221 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4222 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
4223 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
4224 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
4225 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
4226 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
4227 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
4228 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4229 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
4230 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
4231 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
4232 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
4233 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
4234 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
4235 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4236 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
4237 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4238 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
4239 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
4240 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
4241 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
4242 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
4243 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
4244 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
4245 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
4246  ip_source_and_port_range_check_add_del_reply)                          \
4247 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
4248  ip_source_and_port_range_check_interface_add_del_reply)                \
4249 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
4250 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
4251 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
4252 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
4253 _(PUNT_REPLY, punt_reply)                                               \
4254 _(IP_FIB_DETAILS, ip_fib_details)                                       \
4255 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
4256 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
4257 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
4258 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
4259 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
4260 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
4261 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
4262
4263 #define foreach_standalone_reply_msg                                    \
4264 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
4265 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
4266 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
4267 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
4268 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
4269 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
4270
4271 typedef struct
4272 {
4273   u8 *name;
4274   u32 value;
4275 } name_sort_t;
4276
4277
4278 #define STR_VTR_OP_CASE(op)     \
4279     case L2_VTR_ ## op:         \
4280         return "" # op;
4281
4282 static const char *
4283 str_vtr_op (u32 vtr_op)
4284 {
4285   switch (vtr_op)
4286     {
4287       STR_VTR_OP_CASE (DISABLED);
4288       STR_VTR_OP_CASE (PUSH_1);
4289       STR_VTR_OP_CASE (PUSH_2);
4290       STR_VTR_OP_CASE (POP_1);
4291       STR_VTR_OP_CASE (POP_2);
4292       STR_VTR_OP_CASE (TRANSLATE_1_1);
4293       STR_VTR_OP_CASE (TRANSLATE_1_2);
4294       STR_VTR_OP_CASE (TRANSLATE_2_1);
4295       STR_VTR_OP_CASE (TRANSLATE_2_2);
4296     }
4297
4298   return "UNKNOWN";
4299 }
4300
4301 static int
4302 dump_sub_interface_table (vat_main_t * vam)
4303 {
4304   const sw_interface_subif_t *sub = NULL;
4305
4306   if (vam->json_output)
4307     {
4308       clib_warning
4309         ("JSON output supported only for VPE API calls and dump_stats_table");
4310       return -99;
4311     }
4312
4313   print (vam->ofp,
4314          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4315          "Interface", "sw_if_index",
4316          "sub id", "dot1ad", "tags", "outer id",
4317          "inner id", "exact", "default", "outer any", "inner any");
4318
4319   vec_foreach (sub, vam->sw_if_subif_table)
4320   {
4321     print (vam->ofp,
4322            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4323            sub->interface_name,
4324            sub->sw_if_index,
4325            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4326            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4327            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4328            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4329     if (sub->vtr_op != L2_VTR_DISABLED)
4330       {
4331         print (vam->ofp,
4332                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4333                "tag1: %d tag2: %d ]",
4334                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4335                sub->vtr_tag1, sub->vtr_tag2);
4336       }
4337   }
4338
4339   return 0;
4340 }
4341
4342 static int
4343 name_sort_cmp (void *a1, void *a2)
4344 {
4345   name_sort_t *n1 = a1;
4346   name_sort_t *n2 = a2;
4347
4348   return strcmp ((char *) n1->name, (char *) n2->name);
4349 }
4350
4351 static int
4352 dump_interface_table (vat_main_t * vam)
4353 {
4354   hash_pair_t *p;
4355   name_sort_t *nses = 0, *ns;
4356
4357   if (vam->json_output)
4358     {
4359       clib_warning
4360         ("JSON output supported only for VPE API calls and dump_stats_table");
4361       return -99;
4362     }
4363
4364   /* *INDENT-OFF* */
4365   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4366   ({
4367     vec_add2 (nses, ns, 1);
4368     ns->name = (u8 *)(p->key);
4369     ns->value = (u32) p->value[0];
4370   }));
4371   /* *INDENT-ON* */
4372
4373   vec_sort_with_function (nses, name_sort_cmp);
4374
4375   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4376   vec_foreach (ns, nses)
4377   {
4378     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4379   }
4380   vec_free (nses);
4381   return 0;
4382 }
4383
4384 static int
4385 dump_ip_table (vat_main_t * vam, int is_ipv6)
4386 {
4387   const ip_details_t *det = NULL;
4388   const ip_address_details_t *address = NULL;
4389   u32 i = ~0;
4390
4391   print (vam->ofp, "%-12s", "sw_if_index");
4392
4393   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4394   {
4395     i++;
4396     if (!det->present)
4397       {
4398         continue;
4399       }
4400     print (vam->ofp, "%-12d", i);
4401     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
4402     if (!det->addr)
4403       {
4404         continue;
4405       }
4406     vec_foreach (address, det->addr)
4407     {
4408       print (vam->ofp,
4409              "            %-30U%-13d",
4410              is_ipv6 ? format_ip6_address : format_ip4_address,
4411              address->ip, address->prefix_length);
4412     }
4413   }
4414
4415   return 0;
4416 }
4417
4418 static int
4419 dump_ipv4_table (vat_main_t * vam)
4420 {
4421   if (vam->json_output)
4422     {
4423       clib_warning
4424         ("JSON output supported only for VPE API calls and dump_stats_table");
4425       return -99;
4426     }
4427
4428   return dump_ip_table (vam, 0);
4429 }
4430
4431 static int
4432 dump_ipv6_table (vat_main_t * vam)
4433 {
4434   if (vam->json_output)
4435     {
4436       clib_warning
4437         ("JSON output supported only for VPE API calls and dump_stats_table");
4438       return -99;
4439     }
4440
4441   return dump_ip_table (vam, 1);
4442 }
4443
4444 static char *
4445 counter_type_to_str (u8 counter_type, u8 is_combined)
4446 {
4447   if (!is_combined)
4448     {
4449       switch (counter_type)
4450         {
4451         case VNET_INTERFACE_COUNTER_DROP:
4452           return "drop";
4453         case VNET_INTERFACE_COUNTER_PUNT:
4454           return "punt";
4455         case VNET_INTERFACE_COUNTER_IP4:
4456           return "ip4";
4457         case VNET_INTERFACE_COUNTER_IP6:
4458           return "ip6";
4459         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4460           return "rx-no-buf";
4461         case VNET_INTERFACE_COUNTER_RX_MISS:
4462           return "rx-miss";
4463         case VNET_INTERFACE_COUNTER_RX_ERROR:
4464           return "rx-error";
4465         case VNET_INTERFACE_COUNTER_TX_ERROR:
4466           return "tx-error";
4467         default:
4468           return "INVALID-COUNTER-TYPE";
4469         }
4470     }
4471   else
4472     {
4473       switch (counter_type)
4474         {
4475         case VNET_INTERFACE_COUNTER_RX:
4476           return "rx";
4477         case VNET_INTERFACE_COUNTER_TX:
4478           return "tx";
4479         default:
4480           return "INVALID-COUNTER-TYPE";
4481         }
4482     }
4483 }
4484
4485 static int
4486 dump_stats_table (vat_main_t * vam)
4487 {
4488   vat_json_node_t node;
4489   vat_json_node_t *msg_array;
4490   vat_json_node_t *msg;
4491   vat_json_node_t *counter_array;
4492   vat_json_node_t *counter;
4493   interface_counter_t c;
4494   u64 packets;
4495   ip4_fib_counter_t *c4;
4496   ip6_fib_counter_t *c6;
4497   ip4_nbr_counter_t *n4;
4498   ip6_nbr_counter_t *n6;
4499   int i, j;
4500
4501   if (!vam->json_output)
4502     {
4503       clib_warning ("dump_stats_table supported only in JSON format");
4504       return -99;
4505     }
4506
4507   vat_json_init_object (&node);
4508
4509   /* interface counters */
4510   msg_array = vat_json_object_add (&node, "interface_counters");
4511   vat_json_init_array (msg_array);
4512   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4513     {
4514       msg = vat_json_array_add (msg_array);
4515       vat_json_init_object (msg);
4516       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4517                                        (u8 *) counter_type_to_str (i, 0));
4518       vat_json_object_add_int (msg, "is_combined", 0);
4519       counter_array = vat_json_object_add (msg, "data");
4520       vat_json_init_array (counter_array);
4521       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4522         {
4523           packets = vam->simple_interface_counters[i][j];
4524           vat_json_array_add_uint (counter_array, packets);
4525         }
4526     }
4527   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4528     {
4529       msg = vat_json_array_add (msg_array);
4530       vat_json_init_object (msg);
4531       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4532                                        (u8 *) counter_type_to_str (i, 1));
4533       vat_json_object_add_int (msg, "is_combined", 1);
4534       counter_array = vat_json_object_add (msg, "data");
4535       vat_json_init_array (counter_array);
4536       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4537         {
4538           c = vam->combined_interface_counters[i][j];
4539           counter = vat_json_array_add (counter_array);
4540           vat_json_init_object (counter);
4541           vat_json_object_add_uint (counter, "packets", c.packets);
4542           vat_json_object_add_uint (counter, "bytes", c.bytes);
4543         }
4544     }
4545
4546   /* ip4 fib counters */
4547   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4548   vat_json_init_array (msg_array);
4549   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4550     {
4551       msg = vat_json_array_add (msg_array);
4552       vat_json_init_object (msg);
4553       vat_json_object_add_uint (msg, "vrf_id",
4554                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4555       counter_array = vat_json_object_add (msg, "c");
4556       vat_json_init_array (counter_array);
4557       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4558         {
4559           counter = vat_json_array_add (counter_array);
4560           vat_json_init_object (counter);
4561           c4 = &vam->ip4_fib_counters[i][j];
4562           vat_json_object_add_ip4 (counter, "address", c4->address);
4563           vat_json_object_add_uint (counter, "address_length",
4564                                     c4->address_length);
4565           vat_json_object_add_uint (counter, "packets", c4->packets);
4566           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4567         }
4568     }
4569
4570   /* ip6 fib counters */
4571   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4572   vat_json_init_array (msg_array);
4573   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4574     {
4575       msg = vat_json_array_add (msg_array);
4576       vat_json_init_object (msg);
4577       vat_json_object_add_uint (msg, "vrf_id",
4578                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4579       counter_array = vat_json_object_add (msg, "c");
4580       vat_json_init_array (counter_array);
4581       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4582         {
4583           counter = vat_json_array_add (counter_array);
4584           vat_json_init_object (counter);
4585           c6 = &vam->ip6_fib_counters[i][j];
4586           vat_json_object_add_ip6 (counter, "address", c6->address);
4587           vat_json_object_add_uint (counter, "address_length",
4588                                     c6->address_length);
4589           vat_json_object_add_uint (counter, "packets", c6->packets);
4590           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4591         }
4592     }
4593
4594   /* ip4 nbr counters */
4595   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
4596   vat_json_init_array (msg_array);
4597   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
4598     {
4599       msg = vat_json_array_add (msg_array);
4600       vat_json_init_object (msg);
4601       vat_json_object_add_uint (msg, "sw_if_index", i);
4602       counter_array = vat_json_object_add (msg, "c");
4603       vat_json_init_array (counter_array);
4604       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
4605         {
4606           counter = vat_json_array_add (counter_array);
4607           vat_json_init_object (counter);
4608           n4 = &vam->ip4_nbr_counters[i][j];
4609           vat_json_object_add_ip4 (counter, "address", n4->address);
4610           vat_json_object_add_uint (counter, "link-type", n4->linkt);
4611           vat_json_object_add_uint (counter, "packets", n4->packets);
4612           vat_json_object_add_uint (counter, "bytes", n4->bytes);
4613         }
4614     }
4615
4616   /* ip6 nbr counters */
4617   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
4618   vat_json_init_array (msg_array);
4619   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
4620     {
4621       msg = vat_json_array_add (msg_array);
4622       vat_json_init_object (msg);
4623       vat_json_object_add_uint (msg, "sw_if_index", i);
4624       counter_array = vat_json_object_add (msg, "c");
4625       vat_json_init_array (counter_array);
4626       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
4627         {
4628           counter = vat_json_array_add (counter_array);
4629           vat_json_init_object (counter);
4630           n6 = &vam->ip6_nbr_counters[i][j];
4631           vat_json_object_add_ip6 (counter, "address", n6->address);
4632           vat_json_object_add_uint (counter, "packets", n6->packets);
4633           vat_json_object_add_uint (counter, "bytes", n6->bytes);
4634         }
4635     }
4636
4637   vat_json_print (vam->ofp, &node);
4638   vat_json_free (&node);
4639
4640   return 0;
4641 }
4642
4643 int
4644 exec (vat_main_t * vam)
4645 {
4646   api_main_t *am = &api_main;
4647   vl_api_cli_request_t *mp;
4648   f64 timeout;
4649   void *oldheap;
4650   u8 *cmd = 0;
4651   unformat_input_t *i = vam->input;
4652
4653   if (vec_len (i->buffer) == 0)
4654     return -1;
4655
4656   if (vam->exec_mode == 0 && unformat (i, "mode"))
4657     {
4658       vam->exec_mode = 1;
4659       return 0;
4660     }
4661   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4662     {
4663       vam->exec_mode = 0;
4664       return 0;
4665     }
4666
4667
4668   M (CLI_REQUEST, mp);
4669
4670   /*
4671    * Copy cmd into shared memory.
4672    * In order for the CLI command to work, it
4673    * must be a vector ending in \n, not a C-string ending
4674    * in \n\0.
4675    */
4676   pthread_mutex_lock (&am->vlib_rp->mutex);
4677   oldheap = svm_push_data_heap (am->vlib_rp);
4678
4679   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4680   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4681
4682   svm_pop_heap (oldheap);
4683   pthread_mutex_unlock (&am->vlib_rp->mutex);
4684
4685   mp->cmd_in_shmem = (u64) cmd;
4686   S (mp);
4687   timeout = vat_time_now (vam) + 10.0;
4688
4689   while (vat_time_now (vam) < timeout)
4690     {
4691       if (vam->result_ready == 1)
4692         {
4693           u8 *free_me;
4694           if (vam->shmem_result != NULL)
4695             print (vam->ofp, "%s", vam->shmem_result);
4696           pthread_mutex_lock (&am->vlib_rp->mutex);
4697           oldheap = svm_push_data_heap (am->vlib_rp);
4698
4699           free_me = (u8 *) vam->shmem_result;
4700           vec_free (free_me);
4701
4702           svm_pop_heap (oldheap);
4703           pthread_mutex_unlock (&am->vlib_rp->mutex);
4704           return 0;
4705         }
4706     }
4707   return -99;
4708 }
4709
4710 /*
4711  * Future replacement of exec() that passes CLI buffers directly in
4712  * the API messages instead of an additional shared memory area.
4713  */
4714 static int
4715 exec_inband (vat_main_t * vam)
4716 {
4717   vl_api_cli_inband_t *mp;
4718   unformat_input_t *i = vam->input;
4719   int ret;
4720
4721   if (vec_len (i->buffer) == 0)
4722     return -1;
4723
4724   if (vam->exec_mode == 0 && unformat (i, "mode"))
4725     {
4726       vam->exec_mode = 1;
4727       return 0;
4728     }
4729   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4730     {
4731       vam->exec_mode = 0;
4732       return 0;
4733     }
4734
4735   /*
4736    * In order for the CLI command to work, it
4737    * must be a vector ending in \n, not a C-string ending
4738    * in \n\0.
4739    */
4740   u32 len = vec_len (vam->input->buffer);
4741   M2 (CLI_INBAND, mp, len);
4742   clib_memcpy (mp->cmd, vam->input->buffer, len);
4743   mp->length = htonl (len);
4744
4745   S (mp);
4746   W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
4747   return ret;
4748 }
4749
4750 static int
4751 api_create_loopback (vat_main_t * vam)
4752 {
4753   unformat_input_t *i = vam->input;
4754   vl_api_create_loopback_t *mp;
4755   vl_api_create_loopback_instance_t *mp_lbi;
4756   u8 mac_address[6];
4757   u8 mac_set = 0;
4758   u8 is_specified = 0;
4759   u32 user_instance = 0;
4760   int ret;
4761
4762   memset (mac_address, 0, sizeof (mac_address));
4763
4764   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4765     {
4766       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4767         mac_set = 1;
4768       if (unformat (i, "instance %d", &user_instance))
4769         is_specified = 1;
4770       else
4771         break;
4772     }
4773
4774   if (is_specified)
4775     {
4776       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
4777       mp_lbi->is_specified = is_specified;
4778       if (is_specified)
4779         mp_lbi->user_instance = htonl (user_instance);
4780       if (mac_set)
4781         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
4782       S (mp_lbi);
4783     }
4784   else
4785     {
4786       /* Construct the API message */
4787       M (CREATE_LOOPBACK, mp);
4788       if (mac_set)
4789         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4790       S (mp);
4791     }
4792
4793   W (ret);
4794   return ret;
4795 }
4796
4797 static int
4798 api_delete_loopback (vat_main_t * vam)
4799 {
4800   unformat_input_t *i = vam->input;
4801   vl_api_delete_loopback_t *mp;
4802   u32 sw_if_index = ~0;
4803   int ret;
4804
4805   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4806     {
4807       if (unformat (i, "sw_if_index %d", &sw_if_index))
4808         ;
4809       else
4810         break;
4811     }
4812
4813   if (sw_if_index == ~0)
4814     {
4815       errmsg ("missing sw_if_index");
4816       return -99;
4817     }
4818
4819   /* Construct the API message */
4820   M (DELETE_LOOPBACK, mp);
4821   mp->sw_if_index = ntohl (sw_if_index);
4822
4823   S (mp);
4824   W (ret);
4825   return ret;
4826 }
4827
4828 static int
4829 api_want_stats (vat_main_t * vam)
4830 {
4831   unformat_input_t *i = vam->input;
4832   vl_api_want_stats_t *mp;
4833   int enable = -1;
4834   int ret;
4835
4836   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4837     {
4838       if (unformat (i, "enable"))
4839         enable = 1;
4840       else if (unformat (i, "disable"))
4841         enable = 0;
4842       else
4843         break;
4844     }
4845
4846   if (enable == -1)
4847     {
4848       errmsg ("missing enable|disable");
4849       return -99;
4850     }
4851
4852   M (WANT_STATS, mp);
4853   mp->enable_disable = enable;
4854
4855   S (mp);
4856   W (ret);
4857   return ret;
4858 }
4859
4860 static int
4861 api_want_interface_events (vat_main_t * vam)
4862 {
4863   unformat_input_t *i = vam->input;
4864   vl_api_want_interface_events_t *mp;
4865   int enable = -1;
4866   int ret;
4867
4868   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4869     {
4870       if (unformat (i, "enable"))
4871         enable = 1;
4872       else if (unformat (i, "disable"))
4873         enable = 0;
4874       else
4875         break;
4876     }
4877
4878   if (enable == -1)
4879     {
4880       errmsg ("missing enable|disable");
4881       return -99;
4882     }
4883
4884   M (WANT_INTERFACE_EVENTS, mp);
4885   mp->enable_disable = enable;
4886
4887   vam->interface_event_display = enable;
4888
4889   S (mp);
4890   W (ret);
4891   return ret;
4892 }
4893
4894
4895 /* Note: non-static, called once to set up the initial intfc table */
4896 int
4897 api_sw_interface_dump (vat_main_t * vam)
4898 {
4899   vl_api_sw_interface_dump_t *mp;
4900   vl_api_control_ping_t *mp_ping;
4901   hash_pair_t *p;
4902   name_sort_t *nses = 0, *ns;
4903   sw_interface_subif_t *sub = NULL;
4904   int ret;
4905
4906   /* Toss the old name table */
4907   /* *INDENT-OFF* */
4908   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4909   ({
4910     vec_add2 (nses, ns, 1);
4911     ns->name = (u8 *)(p->key);
4912     ns->value = (u32) p->value[0];
4913   }));
4914   /* *INDENT-ON* */
4915
4916   hash_free (vam->sw_if_index_by_interface_name);
4917
4918   vec_foreach (ns, nses) vec_free (ns->name);
4919
4920   vec_free (nses);
4921
4922   vec_foreach (sub, vam->sw_if_subif_table)
4923   {
4924     vec_free (sub->interface_name);
4925   }
4926   vec_free (vam->sw_if_subif_table);
4927
4928   /* recreate the interface name hash table */
4929   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4930
4931   /* Get list of ethernets */
4932   M (SW_INTERFACE_DUMP, mp);
4933   mp->name_filter_valid = 1;
4934   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4935   S (mp);
4936
4937   /* and local / loopback interfaces */
4938   M (SW_INTERFACE_DUMP, mp);
4939   mp->name_filter_valid = 1;
4940   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4941   S (mp);
4942
4943   /* and packet-generator interfaces */
4944   M (SW_INTERFACE_DUMP, mp);
4945   mp->name_filter_valid = 1;
4946   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4947   S (mp);
4948
4949   /* and vxlan-gpe tunnel interfaces */
4950   M (SW_INTERFACE_DUMP, mp);
4951   mp->name_filter_valid = 1;
4952   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4953            sizeof (mp->name_filter) - 1);
4954   S (mp);
4955
4956   /* and vxlan tunnel interfaces */
4957   M (SW_INTERFACE_DUMP, mp);
4958   mp->name_filter_valid = 1;
4959   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4960   S (mp);
4961
4962   /* and host (af_packet) interfaces */
4963   M (SW_INTERFACE_DUMP, mp);
4964   mp->name_filter_valid = 1;
4965   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4966   S (mp);
4967
4968   /* and l2tpv3 tunnel interfaces */
4969   M (SW_INTERFACE_DUMP, mp);
4970   mp->name_filter_valid = 1;
4971   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4972            sizeof (mp->name_filter) - 1);
4973   S (mp);
4974
4975   /* and GRE tunnel interfaces */
4976   M (SW_INTERFACE_DUMP, mp);
4977   mp->name_filter_valid = 1;
4978   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4979   S (mp);
4980
4981   /* and LISP-GPE interfaces */
4982   M (SW_INTERFACE_DUMP, mp);
4983   mp->name_filter_valid = 1;
4984   strncpy ((char *) mp->name_filter, "lisp_gpe",
4985            sizeof (mp->name_filter) - 1);
4986   S (mp);
4987
4988   /* and IPSEC tunnel interfaces */
4989   M (SW_INTERFACE_DUMP, mp);
4990   mp->name_filter_valid = 1;
4991   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4992   S (mp);
4993
4994   /* Use a control ping for synchronization */
4995   M (CONTROL_PING, mp_ping);
4996   S (mp_ping);
4997
4998   W (ret);
4999   return ret;
5000 }
5001
5002 static int
5003 api_sw_interface_set_flags (vat_main_t * vam)
5004 {
5005   unformat_input_t *i = vam->input;
5006   vl_api_sw_interface_set_flags_t *mp;
5007   u32 sw_if_index;
5008   u8 sw_if_index_set = 0;
5009   u8 admin_up = 0, link_up = 0;
5010   int ret;
5011
5012   /* Parse args required to build the message */
5013   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5014     {
5015       if (unformat (i, "admin-up"))
5016         admin_up = 1;
5017       else if (unformat (i, "admin-down"))
5018         admin_up = 0;
5019       else if (unformat (i, "link-up"))
5020         link_up = 1;
5021       else if (unformat (i, "link-down"))
5022         link_up = 0;
5023       else
5024         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5025         sw_if_index_set = 1;
5026       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5027         sw_if_index_set = 1;
5028       else
5029         break;
5030     }
5031
5032   if (sw_if_index_set == 0)
5033     {
5034       errmsg ("missing interface name or sw_if_index");
5035       return -99;
5036     }
5037
5038   /* Construct the API message */
5039   M (SW_INTERFACE_SET_FLAGS, mp);
5040   mp->sw_if_index = ntohl (sw_if_index);
5041   mp->admin_up_down = admin_up;
5042   mp->link_up_down = link_up;
5043
5044   /* send it... */
5045   S (mp);
5046
5047   /* Wait for a reply, return the good/bad news... */
5048   W (ret);
5049   return ret;
5050 }
5051
5052 static int
5053 api_sw_interface_clear_stats (vat_main_t * vam)
5054 {
5055   unformat_input_t *i = vam->input;
5056   vl_api_sw_interface_clear_stats_t *mp;
5057   u32 sw_if_index;
5058   u8 sw_if_index_set = 0;
5059   int ret;
5060
5061   /* Parse args required to build the message */
5062   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5063     {
5064       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5065         sw_if_index_set = 1;
5066       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5067         sw_if_index_set = 1;
5068       else
5069         break;
5070     }
5071
5072   /* Construct the API message */
5073   M (SW_INTERFACE_CLEAR_STATS, mp);
5074
5075   if (sw_if_index_set == 1)
5076     mp->sw_if_index = ntohl (sw_if_index);
5077   else
5078     mp->sw_if_index = ~0;
5079
5080   /* send it... */
5081   S (mp);
5082
5083   /* Wait for a reply, return the good/bad news... */
5084   W (ret);
5085   return ret;
5086 }
5087
5088 static int
5089 api_sw_interface_add_del_address (vat_main_t * vam)
5090 {
5091   unformat_input_t *i = vam->input;
5092   vl_api_sw_interface_add_del_address_t *mp;
5093   u32 sw_if_index;
5094   u8 sw_if_index_set = 0;
5095   u8 is_add = 1, del_all = 0;
5096   u32 address_length = 0;
5097   u8 v4_address_set = 0;
5098   u8 v6_address_set = 0;
5099   ip4_address_t v4address;
5100   ip6_address_t v6address;
5101   int ret;
5102
5103   /* Parse args required to build the message */
5104   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5105     {
5106       if (unformat (i, "del-all"))
5107         del_all = 1;
5108       else if (unformat (i, "del"))
5109         is_add = 0;
5110       else
5111         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5112         sw_if_index_set = 1;
5113       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5114         sw_if_index_set = 1;
5115       else if (unformat (i, "%U/%d",
5116                          unformat_ip4_address, &v4address, &address_length))
5117         v4_address_set = 1;
5118       else if (unformat (i, "%U/%d",
5119                          unformat_ip6_address, &v6address, &address_length))
5120         v6_address_set = 1;
5121       else
5122         break;
5123     }
5124
5125   if (sw_if_index_set == 0)
5126     {
5127       errmsg ("missing interface name or sw_if_index");
5128       return -99;
5129     }
5130   if (v4_address_set && v6_address_set)
5131     {
5132       errmsg ("both v4 and v6 addresses set");
5133       return -99;
5134     }
5135   if (!v4_address_set && !v6_address_set && !del_all)
5136     {
5137       errmsg ("no addresses set");
5138       return -99;
5139     }
5140
5141   /* Construct the API message */
5142   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
5143
5144   mp->sw_if_index = ntohl (sw_if_index);
5145   mp->is_add = is_add;
5146   mp->del_all = del_all;
5147   if (v6_address_set)
5148     {
5149       mp->is_ipv6 = 1;
5150       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5151     }
5152   else
5153     {
5154       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5155     }
5156   mp->address_length = address_length;
5157
5158   /* send it... */
5159   S (mp);
5160
5161   /* Wait for a reply, return good/bad news  */
5162   W (ret);
5163   return ret;
5164 }
5165
5166 static int
5167 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5168 {
5169   unformat_input_t *i = vam->input;
5170   vl_api_sw_interface_set_mpls_enable_t *mp;
5171   u32 sw_if_index;
5172   u8 sw_if_index_set = 0;
5173   u8 enable = 1;
5174   int ret;
5175
5176   /* Parse args required to build the message */
5177   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5178     {
5179       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5180         sw_if_index_set = 1;
5181       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5182         sw_if_index_set = 1;
5183       else if (unformat (i, "disable"))
5184         enable = 0;
5185       else if (unformat (i, "dis"))
5186         enable = 0;
5187       else
5188         break;
5189     }
5190
5191   if (sw_if_index_set == 0)
5192     {
5193       errmsg ("missing interface name or sw_if_index");
5194       return -99;
5195     }
5196
5197   /* Construct the API message */
5198   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
5199
5200   mp->sw_if_index = ntohl (sw_if_index);
5201   mp->enable = enable;
5202
5203   /* send it... */
5204   S (mp);
5205
5206   /* Wait for a reply... */
5207   W (ret);
5208   return ret;
5209 }
5210
5211 static int
5212 api_sw_interface_set_table (vat_main_t * vam)
5213 {
5214   unformat_input_t *i = vam->input;
5215   vl_api_sw_interface_set_table_t *mp;
5216   u32 sw_if_index, vrf_id = 0;
5217   u8 sw_if_index_set = 0;
5218   u8 is_ipv6 = 0;
5219   int ret;
5220
5221   /* Parse args required to build the message */
5222   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5223     {
5224       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5225         sw_if_index_set = 1;
5226       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5227         sw_if_index_set = 1;
5228       else if (unformat (i, "vrf %d", &vrf_id))
5229         ;
5230       else if (unformat (i, "ipv6"))
5231         is_ipv6 = 1;
5232       else
5233         break;
5234     }
5235
5236   if (sw_if_index_set == 0)
5237     {
5238       errmsg ("missing interface name or sw_if_index");
5239       return -99;
5240     }
5241
5242   /* Construct the API message */
5243   M (SW_INTERFACE_SET_TABLE, mp);
5244
5245   mp->sw_if_index = ntohl (sw_if_index);
5246   mp->is_ipv6 = is_ipv6;
5247   mp->vrf_id = ntohl (vrf_id);
5248
5249   /* send it... */
5250   S (mp);
5251
5252   /* Wait for a reply... */
5253   W (ret);
5254   return ret;
5255 }
5256
5257 static void vl_api_sw_interface_get_table_reply_t_handler
5258   (vl_api_sw_interface_get_table_reply_t * mp)
5259 {
5260   vat_main_t *vam = &vat_main;
5261
5262   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5263
5264   vam->retval = ntohl (mp->retval);
5265   vam->result_ready = 1;
5266
5267 }
5268
5269 static void vl_api_sw_interface_get_table_reply_t_handler_json
5270   (vl_api_sw_interface_get_table_reply_t * mp)
5271 {
5272   vat_main_t *vam = &vat_main;
5273   vat_json_node_t node;
5274
5275   vat_json_init_object (&node);
5276   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5277   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5278
5279   vat_json_print (vam->ofp, &node);
5280   vat_json_free (&node);
5281
5282   vam->retval = ntohl (mp->retval);
5283   vam->result_ready = 1;
5284 }
5285
5286 static int
5287 api_sw_interface_get_table (vat_main_t * vam)
5288 {
5289   unformat_input_t *i = vam->input;
5290   vl_api_sw_interface_get_table_t *mp;
5291   u32 sw_if_index;
5292   u8 sw_if_index_set = 0;
5293   u8 is_ipv6 = 0;
5294   int ret;
5295
5296   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5297     {
5298       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5299         sw_if_index_set = 1;
5300       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5301         sw_if_index_set = 1;
5302       else if (unformat (i, "ipv6"))
5303         is_ipv6 = 1;
5304       else
5305         break;
5306     }
5307
5308   if (sw_if_index_set == 0)
5309     {
5310       errmsg ("missing interface name or sw_if_index");
5311       return -99;
5312     }
5313
5314   M (SW_INTERFACE_GET_TABLE, mp);
5315   mp->sw_if_index = htonl (sw_if_index);
5316   mp->is_ipv6 = is_ipv6;
5317
5318   S (mp);
5319   W (ret);
5320   return ret;
5321 }
5322
5323 static int
5324 api_sw_interface_set_vpath (vat_main_t * vam)
5325 {
5326   unformat_input_t *i = vam->input;
5327   vl_api_sw_interface_set_vpath_t *mp;
5328   u32 sw_if_index = 0;
5329   u8 sw_if_index_set = 0;
5330   u8 is_enable = 0;
5331   int ret;
5332
5333   /* Parse args required to build the message */
5334   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5335     {
5336       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5337         sw_if_index_set = 1;
5338       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5339         sw_if_index_set = 1;
5340       else if (unformat (i, "enable"))
5341         is_enable = 1;
5342       else if (unformat (i, "disable"))
5343         is_enable = 0;
5344       else
5345         break;
5346     }
5347
5348   if (sw_if_index_set == 0)
5349     {
5350       errmsg ("missing interface name or sw_if_index");
5351       return -99;
5352     }
5353
5354   /* Construct the API message */
5355   M (SW_INTERFACE_SET_VPATH, mp);
5356
5357   mp->sw_if_index = ntohl (sw_if_index);
5358   mp->enable = is_enable;
5359
5360   /* send it... */
5361   S (mp);
5362
5363   /* Wait for a reply... */
5364   W (ret);
5365   return ret;
5366 }
5367
5368 static int
5369 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5370 {
5371   unformat_input_t *i = vam->input;
5372   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5373   u32 sw_if_index = 0;
5374   u8 sw_if_index_set = 0;
5375   u8 is_enable = 1;
5376   u8 is_ipv6 = 0;
5377   int ret;
5378
5379   /* Parse args required to build the message */
5380   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5381     {
5382       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5383         sw_if_index_set = 1;
5384       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5385         sw_if_index_set = 1;
5386       else if (unformat (i, "enable"))
5387         is_enable = 1;
5388       else if (unformat (i, "disable"))
5389         is_enable = 0;
5390       else if (unformat (i, "ip4"))
5391         is_ipv6 = 0;
5392       else if (unformat (i, "ip6"))
5393         is_ipv6 = 1;
5394       else
5395         break;
5396     }
5397
5398   if (sw_if_index_set == 0)
5399     {
5400       errmsg ("missing interface name or sw_if_index");
5401       return -99;
5402     }
5403
5404   /* Construct the API message */
5405   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
5406
5407   mp->sw_if_index = ntohl (sw_if_index);
5408   mp->enable = is_enable;
5409   mp->is_ipv6 = is_ipv6;
5410
5411   /* send it... */
5412   S (mp);
5413
5414   /* Wait for a reply... */
5415   W (ret);
5416   return ret;
5417 }
5418
5419 static int
5420 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5421 {
5422   unformat_input_t *i = vam->input;
5423   vl_api_sw_interface_set_l2_xconnect_t *mp;
5424   u32 rx_sw_if_index;
5425   u8 rx_sw_if_index_set = 0;
5426   u32 tx_sw_if_index;
5427   u8 tx_sw_if_index_set = 0;
5428   u8 enable = 1;
5429   int ret;
5430
5431   /* Parse args required to build the message */
5432   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5433     {
5434       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5435         rx_sw_if_index_set = 1;
5436       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5437         tx_sw_if_index_set = 1;
5438       else if (unformat (i, "rx"))
5439         {
5440           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5441             {
5442               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5443                             &rx_sw_if_index))
5444                 rx_sw_if_index_set = 1;
5445             }
5446           else
5447             break;
5448         }
5449       else if (unformat (i, "tx"))
5450         {
5451           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5452             {
5453               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5454                             &tx_sw_if_index))
5455                 tx_sw_if_index_set = 1;
5456             }
5457           else
5458             break;
5459         }
5460       else if (unformat (i, "enable"))
5461         enable = 1;
5462       else if (unformat (i, "disable"))
5463         enable = 0;
5464       else
5465         break;
5466     }
5467
5468   if (rx_sw_if_index_set == 0)
5469     {
5470       errmsg ("missing rx interface name or rx_sw_if_index");
5471       return -99;
5472     }
5473
5474   if (enable && (tx_sw_if_index_set == 0))
5475     {
5476       errmsg ("missing tx interface name or tx_sw_if_index");
5477       return -99;
5478     }
5479
5480   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
5481
5482   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5483   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5484   mp->enable = enable;
5485
5486   S (mp);
5487   W (ret);
5488   return ret;
5489 }
5490
5491 static int
5492 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5493 {
5494   unformat_input_t *i = vam->input;
5495   vl_api_sw_interface_set_l2_bridge_t *mp;
5496   u32 rx_sw_if_index;
5497   u8 rx_sw_if_index_set = 0;
5498   u32 bd_id;
5499   u8 bd_id_set = 0;
5500   u8 bvi = 0;
5501   u32 shg = 0;
5502   u8 enable = 1;
5503   int ret;
5504
5505   /* Parse args required to build the message */
5506   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5507     {
5508       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5509         rx_sw_if_index_set = 1;
5510       else if (unformat (i, "bd_id %d", &bd_id))
5511         bd_id_set = 1;
5512       else
5513         if (unformat
5514             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5515         rx_sw_if_index_set = 1;
5516       else if (unformat (i, "shg %d", &shg))
5517         ;
5518       else if (unformat (i, "bvi"))
5519         bvi = 1;
5520       else if (unformat (i, "enable"))
5521         enable = 1;
5522       else if (unformat (i, "disable"))
5523         enable = 0;
5524       else
5525         break;
5526     }
5527
5528   if (rx_sw_if_index_set == 0)
5529     {
5530       errmsg ("missing rx interface name or sw_if_index");
5531       return -99;
5532     }
5533
5534   if (enable && (bd_id_set == 0))
5535     {
5536       errmsg ("missing bridge domain");
5537       return -99;
5538     }
5539
5540   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
5541
5542   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5543   mp->bd_id = ntohl (bd_id);
5544   mp->shg = (u8) shg;
5545   mp->bvi = bvi;
5546   mp->enable = enable;
5547
5548   S (mp);
5549   W (ret);
5550   return ret;
5551 }
5552
5553 static int
5554 api_bridge_domain_dump (vat_main_t * vam)
5555 {
5556   unformat_input_t *i = vam->input;
5557   vl_api_bridge_domain_dump_t *mp;
5558   vl_api_control_ping_t *mp_ping;
5559   u32 bd_id = ~0;
5560   int ret;
5561
5562   /* Parse args required to build the message */
5563   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5564     {
5565       if (unformat (i, "bd_id %d", &bd_id))
5566         ;
5567       else
5568         break;
5569     }
5570
5571   M (BRIDGE_DOMAIN_DUMP, mp);
5572   mp->bd_id = ntohl (bd_id);
5573   S (mp);
5574
5575   /* Use a control ping for synchronization */
5576   M (CONTROL_PING, mp_ping);
5577   S (mp_ping);
5578
5579   W (ret);
5580   return ret;
5581 }
5582
5583 static int
5584 api_bridge_domain_add_del (vat_main_t * vam)
5585 {
5586   unformat_input_t *i = vam->input;
5587   vl_api_bridge_domain_add_del_t *mp;
5588   u32 bd_id = ~0;
5589   u8 is_add = 1;
5590   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5591   u32 mac_age = 0;
5592   int ret;
5593
5594   /* Parse args required to build the message */
5595   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5596     {
5597       if (unformat (i, "bd_id %d", &bd_id))
5598         ;
5599       else if (unformat (i, "flood %d", &flood))
5600         ;
5601       else if (unformat (i, "uu-flood %d", &uu_flood))
5602         ;
5603       else if (unformat (i, "forward %d", &forward))
5604         ;
5605       else if (unformat (i, "learn %d", &learn))
5606         ;
5607       else if (unformat (i, "arp-term %d", &arp_term))
5608         ;
5609       else if (unformat (i, "mac-age %d", &mac_age))
5610         ;
5611       else if (unformat (i, "del"))
5612         {
5613           is_add = 0;
5614           flood = uu_flood = forward = learn = 0;
5615         }
5616       else
5617         break;
5618     }
5619
5620   if (bd_id == ~0)
5621     {
5622       errmsg ("missing bridge domain");
5623       return -99;
5624     }
5625
5626   if (mac_age > 255)
5627     {
5628       errmsg ("mac age must be less than 256 ");
5629       return -99;
5630     }
5631
5632   M (BRIDGE_DOMAIN_ADD_DEL, mp);
5633
5634   mp->bd_id = ntohl (bd_id);
5635   mp->flood = flood;
5636   mp->uu_flood = uu_flood;
5637   mp->forward = forward;
5638   mp->learn = learn;
5639   mp->arp_term = arp_term;
5640   mp->is_add = is_add;
5641   mp->mac_age = (u8) mac_age;
5642
5643   S (mp);
5644   W (ret);
5645   return ret;
5646 }
5647
5648 static int
5649 api_l2fib_add_del (vat_main_t * vam)
5650 {
5651   unformat_input_t *i = vam->input;
5652   vl_api_l2fib_add_del_t *mp;
5653   f64 timeout;
5654   u64 mac = 0;
5655   u8 mac_set = 0;
5656   u32 bd_id;
5657   u8 bd_id_set = 0;
5658   u32 sw_if_index = ~0;
5659   u8 sw_if_index_set = 0;
5660   u8 is_add = 1;
5661   u8 static_mac = 0;
5662   u8 filter_mac = 0;
5663   u8 bvi_mac = 0;
5664   int count = 1;
5665   f64 before = 0;
5666   int j;
5667
5668   /* Parse args required to build the message */
5669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5670     {
5671       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5672         mac_set = 1;
5673       else if (unformat (i, "bd_id %d", &bd_id))
5674         bd_id_set = 1;
5675       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5676         sw_if_index_set = 1;
5677       else if (unformat (i, "sw_if"))
5678         {
5679           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5680             {
5681               if (unformat
5682                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5683                 sw_if_index_set = 1;
5684             }
5685           else
5686             break;
5687         }
5688       else if (unformat (i, "static"))
5689         static_mac = 1;
5690       else if (unformat (i, "filter"))
5691         {
5692           filter_mac = 1;
5693           static_mac = 1;
5694         }
5695       else if (unformat (i, "bvi"))
5696         {
5697           bvi_mac = 1;
5698           static_mac = 1;
5699         }
5700       else if (unformat (i, "del"))
5701         is_add = 0;
5702       else if (unformat (i, "count %d", &count))
5703         ;
5704       else
5705         break;
5706     }
5707
5708   if (mac_set == 0)
5709     {
5710       errmsg ("missing mac address");
5711       return -99;
5712     }
5713
5714   if (bd_id_set == 0)
5715     {
5716       errmsg ("missing bridge domain");
5717       return -99;
5718     }
5719
5720   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
5721     {
5722       errmsg ("missing interface name or sw_if_index");
5723       return -99;
5724     }
5725
5726   if (count > 1)
5727     {
5728       /* Turn on async mode */
5729       vam->async_mode = 1;
5730       vam->async_errors = 0;
5731       before = vat_time_now (vam);
5732     }
5733
5734   for (j = 0; j < count; j++)
5735     {
5736       M (L2FIB_ADD_DEL, mp);
5737
5738       mp->mac = mac;
5739       mp->bd_id = ntohl (bd_id);
5740       mp->is_add = is_add;
5741
5742       if (is_add)
5743         {
5744           mp->sw_if_index = ntohl (sw_if_index);
5745           mp->static_mac = static_mac;
5746           mp->filter_mac = filter_mac;
5747           mp->bvi_mac = bvi_mac;
5748         }
5749       increment_mac_address (&mac);
5750       /* send it... */
5751       S (mp);
5752     }
5753
5754   if (count > 1)
5755     {
5756       vl_api_control_ping_t *mp_ping;
5757       f64 after;
5758
5759       /* Shut off async mode */
5760       vam->async_mode = 0;
5761
5762       M (CONTROL_PING, mp_ping);
5763       S (mp_ping);
5764
5765       timeout = vat_time_now (vam) + 1.0;
5766       while (vat_time_now (vam) < timeout)
5767         if (vam->result_ready == 1)
5768           goto out;
5769       vam->retval = -99;
5770
5771     out:
5772       if (vam->retval == -99)
5773         errmsg ("timeout");
5774
5775       if (vam->async_errors > 0)
5776         {
5777           errmsg ("%d asynchronous errors", vam->async_errors);
5778           vam->retval = -98;
5779         }
5780       vam->async_errors = 0;
5781       after = vat_time_now (vam);
5782
5783       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
5784              count, after - before, count / (after - before));
5785     }
5786   else
5787     {
5788       int ret;
5789
5790       /* Wait for a reply... */
5791       W (ret);
5792       return ret;
5793     }
5794   /* Return the good/bad news */
5795   return (vam->retval);
5796 }
5797
5798 static int
5799 api_l2_flags (vat_main_t * vam)
5800 {
5801   unformat_input_t *i = vam->input;
5802   vl_api_l2_flags_t *mp;
5803   u32 sw_if_index;
5804   u32 feature_bitmap = 0;
5805   u8 sw_if_index_set = 0;
5806   int ret;
5807
5808   /* Parse args required to build the message */
5809   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5810     {
5811       if (unformat (i, "sw_if_index %d", &sw_if_index))
5812         sw_if_index_set = 1;
5813       else if (unformat (i, "sw_if"))
5814         {
5815           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5816             {
5817               if (unformat
5818                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5819                 sw_if_index_set = 1;
5820             }
5821           else
5822             break;
5823         }
5824       else if (unformat (i, "learn"))
5825         feature_bitmap |= L2INPUT_FEAT_LEARN;
5826       else if (unformat (i, "forward"))
5827         feature_bitmap |= L2INPUT_FEAT_FWD;
5828       else if (unformat (i, "flood"))
5829         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5830       else if (unformat (i, "uu-flood"))
5831         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5832       else
5833         break;
5834     }
5835
5836   if (sw_if_index_set == 0)
5837     {
5838       errmsg ("missing interface name or sw_if_index");
5839       return -99;
5840     }
5841
5842   M (L2_FLAGS, mp);
5843
5844   mp->sw_if_index = ntohl (sw_if_index);
5845   mp->feature_bitmap = ntohl (feature_bitmap);
5846
5847   S (mp);
5848   W (ret);
5849   return ret;
5850 }
5851
5852 static int
5853 api_bridge_flags (vat_main_t * vam)
5854 {
5855   unformat_input_t *i = vam->input;
5856   vl_api_bridge_flags_t *mp;
5857   u32 bd_id;
5858   u8 bd_id_set = 0;
5859   u8 is_set = 1;
5860   u32 flags = 0;
5861   int ret;
5862
5863   /* Parse args required to build the message */
5864   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5865     {
5866       if (unformat (i, "bd_id %d", &bd_id))
5867         bd_id_set = 1;
5868       else if (unformat (i, "learn"))
5869         flags |= L2_LEARN;
5870       else if (unformat (i, "forward"))
5871         flags |= L2_FWD;
5872       else if (unformat (i, "flood"))
5873         flags |= L2_FLOOD;
5874       else if (unformat (i, "uu-flood"))
5875         flags |= L2_UU_FLOOD;
5876       else if (unformat (i, "arp-term"))
5877         flags |= L2_ARP_TERM;
5878       else if (unformat (i, "off"))
5879         is_set = 0;
5880       else if (unformat (i, "disable"))
5881         is_set = 0;
5882       else
5883         break;
5884     }
5885
5886   if (bd_id_set == 0)
5887     {
5888       errmsg ("missing bridge domain");
5889       return -99;
5890     }
5891
5892   M (BRIDGE_FLAGS, mp);
5893
5894   mp->bd_id = ntohl (bd_id);
5895   mp->feature_bitmap = ntohl (flags);
5896   mp->is_set = is_set;
5897
5898   S (mp);
5899   W (ret);
5900   return ret;
5901 }
5902
5903 static int
5904 api_bd_ip_mac_add_del (vat_main_t * vam)
5905 {
5906   unformat_input_t *i = vam->input;
5907   vl_api_bd_ip_mac_add_del_t *mp;
5908   u32 bd_id;
5909   u8 is_ipv6 = 0;
5910   u8 is_add = 1;
5911   u8 bd_id_set = 0;
5912   u8 ip_set = 0;
5913   u8 mac_set = 0;
5914   ip4_address_t v4addr;
5915   ip6_address_t v6addr;
5916   u8 macaddr[6];
5917   int ret;
5918
5919
5920   /* Parse args required to build the message */
5921   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5922     {
5923       if (unformat (i, "bd_id %d", &bd_id))
5924         {
5925           bd_id_set++;
5926         }
5927       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5928         {
5929           ip_set++;
5930         }
5931       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5932         {
5933           ip_set++;
5934           is_ipv6++;
5935         }
5936       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5937         {
5938           mac_set++;
5939         }
5940       else if (unformat (i, "del"))
5941         is_add = 0;
5942       else
5943         break;
5944     }
5945
5946   if (bd_id_set == 0)
5947     {
5948       errmsg ("missing bridge domain");
5949       return -99;
5950     }
5951   else if (ip_set == 0)
5952     {
5953       errmsg ("missing IP address");
5954       return -99;
5955     }
5956   else if (mac_set == 0)
5957     {
5958       errmsg ("missing MAC address");
5959       return -99;
5960     }
5961
5962   M (BD_IP_MAC_ADD_DEL, mp);
5963
5964   mp->bd_id = ntohl (bd_id);
5965   mp->is_ipv6 = is_ipv6;
5966   mp->is_add = is_add;
5967   if (is_ipv6)
5968     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5969   else
5970     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5971   clib_memcpy (mp->mac_address, macaddr, 6);
5972   S (mp);
5973   W (ret);
5974   return ret;
5975 }
5976
5977 static int
5978 api_tap_connect (vat_main_t * vam)
5979 {
5980   unformat_input_t *i = vam->input;
5981   vl_api_tap_connect_t *mp;
5982   u8 mac_address[6];
5983   u8 random_mac = 1;
5984   u8 name_set = 0;
5985   u8 *tap_name;
5986   u8 *tag = 0;
5987   ip4_address_t ip4_address;
5988   u32 ip4_mask_width;
5989   int ip4_address_set = 0;
5990   ip6_address_t ip6_address;
5991   u32 ip6_mask_width;
5992   int ip6_address_set = 0;
5993   int ret;
5994
5995   memset (mac_address, 0, sizeof (mac_address));
5996
5997   /* Parse args required to build the message */
5998   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5999     {
6000       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6001         {
6002           random_mac = 0;
6003         }
6004       else if (unformat (i, "random-mac"))
6005         random_mac = 1;
6006       else if (unformat (i, "tapname %s", &tap_name))
6007         name_set = 1;
6008       else if (unformat (i, "tag %s", &tag))
6009         ;
6010       else if (unformat (i, "address %U/%d",
6011                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
6012         ip4_address_set = 1;
6013       else if (unformat (i, "address %U/%d",
6014                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
6015         ip6_address_set = 1;
6016       else
6017         break;
6018     }
6019
6020   if (name_set == 0)
6021     {
6022       errmsg ("missing tap name");
6023       return -99;
6024     }
6025   if (vec_len (tap_name) > 63)
6026     {
6027       errmsg ("tap name too long");
6028       return -99;
6029     }
6030   vec_add1 (tap_name, 0);
6031
6032   if (vec_len (tag) > 63)
6033     {
6034       errmsg ("tag too long");
6035       return -99;
6036     }
6037
6038   /* Construct the API message */
6039   M (TAP_CONNECT, mp);
6040
6041   mp->use_random_mac = random_mac;
6042   clib_memcpy (mp->mac_address, mac_address, 6);
6043   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6044   if (tag)
6045     clib_memcpy (mp->tag, tag, vec_len (tag));
6046
6047   if (ip4_address_set)
6048     {
6049       mp->ip4_address_set = 1;
6050       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6051       mp->ip4_mask_width = ip4_mask_width;
6052     }
6053   if (ip6_address_set)
6054     {
6055       mp->ip6_address_set = 1;
6056       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6057       mp->ip6_mask_width = ip6_mask_width;
6058     }
6059
6060   vec_free (tap_name);
6061   vec_free (tag);
6062
6063   /* send it... */
6064   S (mp);
6065
6066   /* Wait for a reply... */
6067   W (ret);
6068   return ret;
6069 }
6070
6071 static int
6072 api_tap_modify (vat_main_t * vam)
6073 {
6074   unformat_input_t *i = vam->input;
6075   vl_api_tap_modify_t *mp;
6076   u8 mac_address[6];
6077   u8 random_mac = 1;
6078   u8 name_set = 0;
6079   u8 *tap_name;
6080   u32 sw_if_index = ~0;
6081   u8 sw_if_index_set = 0;
6082   int ret;
6083
6084   memset (mac_address, 0, sizeof (mac_address));
6085
6086   /* Parse args required to build the message */
6087   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6088     {
6089       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6090         sw_if_index_set = 1;
6091       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6092         sw_if_index_set = 1;
6093       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6094         {
6095           random_mac = 0;
6096         }
6097       else if (unformat (i, "random-mac"))
6098         random_mac = 1;
6099       else if (unformat (i, "tapname %s", &tap_name))
6100         name_set = 1;
6101       else
6102         break;
6103     }
6104
6105   if (sw_if_index_set == 0)
6106     {
6107       errmsg ("missing vpp interface name");
6108       return -99;
6109     }
6110   if (name_set == 0)
6111     {
6112       errmsg ("missing tap name");
6113       return -99;
6114     }
6115   if (vec_len (tap_name) > 63)
6116     {
6117       errmsg ("tap name too long");
6118     }
6119   vec_add1 (tap_name, 0);
6120
6121   /* Construct the API message */
6122   M (TAP_MODIFY, mp);
6123
6124   mp->use_random_mac = random_mac;
6125   mp->sw_if_index = ntohl (sw_if_index);
6126   clib_memcpy (mp->mac_address, mac_address, 6);
6127   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6128   vec_free (tap_name);
6129
6130   /* send it... */
6131   S (mp);
6132
6133   /* Wait for a reply... */
6134   W (ret);
6135   return ret;
6136 }
6137
6138 static int
6139 api_tap_delete (vat_main_t * vam)
6140 {
6141   unformat_input_t *i = vam->input;
6142   vl_api_tap_delete_t *mp;
6143   u32 sw_if_index = ~0;
6144   u8 sw_if_index_set = 0;
6145   int ret;
6146
6147   /* Parse args required to build the message */
6148   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6149     {
6150       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6151         sw_if_index_set = 1;
6152       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6153         sw_if_index_set = 1;
6154       else
6155         break;
6156     }
6157
6158   if (sw_if_index_set == 0)
6159     {
6160       errmsg ("missing vpp interface name");
6161       return -99;
6162     }
6163
6164   /* Construct the API message */
6165   M (TAP_DELETE, mp);
6166
6167   mp->sw_if_index = ntohl (sw_if_index);
6168
6169   /* send it... */
6170   S (mp);
6171
6172   /* Wait for a reply... */
6173   W (ret);
6174   return ret;
6175 }
6176
6177 static int
6178 api_ip_add_del_route (vat_main_t * vam)
6179 {
6180   unformat_input_t *i = vam->input;
6181   vl_api_ip_add_del_route_t *mp;
6182   u32 sw_if_index = ~0, vrf_id = 0;
6183   u8 is_ipv6 = 0;
6184   u8 is_local = 0, is_drop = 0;
6185   u8 is_unreach = 0, is_prohibit = 0;
6186   u8 create_vrf_if_needed = 0;
6187   u8 is_add = 1;
6188   u32 next_hop_weight = 1;
6189   u8 not_last = 0;
6190   u8 is_multipath = 0;
6191   u8 address_set = 0;
6192   u8 address_length_set = 0;
6193   u32 next_hop_table_id = 0;
6194   u32 resolve_attempts = 0;
6195   u32 dst_address_length = 0;
6196   u8 next_hop_set = 0;
6197   ip4_address_t v4_dst_address, v4_next_hop_address;
6198   ip6_address_t v6_dst_address, v6_next_hop_address;
6199   int count = 1;
6200   int j;
6201   f64 before = 0;
6202   u32 random_add_del = 0;
6203   u32 *random_vector = 0;
6204   uword *random_hash;
6205   u32 random_seed = 0xdeaddabe;
6206   u32 classify_table_index = ~0;
6207   u8 is_classify = 0;
6208   u8 resolve_host = 0, resolve_attached = 0;
6209   mpls_label_t *next_hop_out_label_stack = NULL;
6210   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6211   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6212
6213   /* Parse args required to build the message */
6214   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6215     {
6216       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6217         ;
6218       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6219         ;
6220       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6221         {
6222           address_set = 1;
6223           is_ipv6 = 0;
6224         }
6225       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6226         {
6227           address_set = 1;
6228           is_ipv6 = 1;
6229         }
6230       else if (unformat (i, "/%d", &dst_address_length))
6231         {
6232           address_length_set = 1;
6233         }
6234
6235       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6236                                          &v4_next_hop_address))
6237         {
6238           next_hop_set = 1;
6239         }
6240       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6241                                          &v6_next_hop_address))
6242         {
6243           next_hop_set = 1;
6244         }
6245       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6246         ;
6247       else if (unformat (i, "weight %d", &next_hop_weight))
6248         ;
6249       else if (unformat (i, "drop"))
6250         {
6251           is_drop = 1;
6252         }
6253       else if (unformat (i, "null-send-unreach"))
6254         {
6255           is_unreach = 1;
6256         }
6257       else if (unformat (i, "null-send-prohibit"))
6258         {
6259           is_prohibit = 1;
6260         }
6261       else if (unformat (i, "local"))
6262         {
6263           is_local = 1;
6264         }
6265       else if (unformat (i, "classify %d", &classify_table_index))
6266         {
6267           is_classify = 1;
6268         }
6269       else if (unformat (i, "del"))
6270         is_add = 0;
6271       else if (unformat (i, "add"))
6272         is_add = 1;
6273       else if (unformat (i, "not-last"))
6274         not_last = 1;
6275       else if (unformat (i, "resolve-via-host"))
6276         resolve_host = 1;
6277       else if (unformat (i, "resolve-via-attached"))
6278         resolve_attached = 1;
6279       else if (unformat (i, "multipath"))
6280         is_multipath = 1;
6281       else if (unformat (i, "vrf %d", &vrf_id))
6282         ;
6283       else if (unformat (i, "create-vrf"))
6284         create_vrf_if_needed = 1;
6285       else if (unformat (i, "count %d", &count))
6286         ;
6287       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6288         ;
6289       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6290         ;
6291       else if (unformat (i, "out-label %d", &next_hop_out_label))
6292         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6293       else if (unformat (i, "via-label %d", &next_hop_via_label))
6294         ;
6295       else if (unformat (i, "random"))
6296         random_add_del = 1;
6297       else if (unformat (i, "seed %d", &random_seed))
6298         ;
6299       else
6300         {
6301           clib_warning ("parse error '%U'", format_unformat_error, i);
6302           return -99;
6303         }
6304     }
6305
6306   if (!next_hop_set && !is_drop && !is_local &&
6307       !is_classify && !is_unreach && !is_prohibit &&
6308       MPLS_LABEL_INVALID == next_hop_via_label)
6309     {
6310       errmsg
6311         ("next hop / local / drop / unreach / prohibit / classify not set");
6312       return -99;
6313     }
6314
6315   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6316     {
6317       errmsg ("next hop and next-hop via label set");
6318       return -99;
6319     }
6320   if (address_set == 0)
6321     {
6322       errmsg ("missing addresses");
6323       return -99;
6324     }
6325
6326   if (address_length_set == 0)
6327     {
6328       errmsg ("missing address length");
6329       return -99;
6330     }
6331
6332   /* Generate a pile of unique, random routes */
6333   if (random_add_del)
6334     {
6335       u32 this_random_address;
6336       random_hash = hash_create (count, sizeof (uword));
6337
6338       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6339       for (j = 0; j <= count; j++)
6340         {
6341           do
6342             {
6343               this_random_address = random_u32 (&random_seed);
6344               this_random_address =
6345                 clib_host_to_net_u32 (this_random_address);
6346             }
6347           while (hash_get (random_hash, this_random_address));
6348           vec_add1 (random_vector, this_random_address);
6349           hash_set (random_hash, this_random_address, 1);
6350         }
6351       hash_free (random_hash);
6352       v4_dst_address.as_u32 = random_vector[0];
6353     }
6354
6355   if (count > 1)
6356     {
6357       /* Turn on async mode */
6358       vam->async_mode = 1;
6359       vam->async_errors = 0;
6360       before = vat_time_now (vam);
6361     }
6362
6363   for (j = 0; j < count; j++)
6364     {
6365       /* Construct the API message */
6366       M2 (IP_ADD_DEL_ROUTE, mp,
6367           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6368
6369       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6370       mp->table_id = ntohl (vrf_id);
6371       mp->create_vrf_if_needed = create_vrf_if_needed;
6372
6373       mp->is_add = is_add;
6374       mp->is_drop = is_drop;
6375       mp->is_unreach = is_unreach;
6376       mp->is_prohibit = is_prohibit;
6377       mp->is_ipv6 = is_ipv6;
6378       mp->is_local = is_local;
6379       mp->is_classify = is_classify;
6380       mp->is_multipath = is_multipath;
6381       mp->is_resolve_host = resolve_host;
6382       mp->is_resolve_attached = resolve_attached;
6383       mp->not_last = not_last;
6384       mp->next_hop_weight = next_hop_weight;
6385       mp->dst_address_length = dst_address_length;
6386       mp->next_hop_table_id = ntohl (next_hop_table_id);
6387       mp->classify_table_index = ntohl (classify_table_index);
6388       mp->next_hop_via_label = ntohl (next_hop_via_label);
6389       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6390       if (0 != mp->next_hop_n_out_labels)
6391         {
6392           memcpy (mp->next_hop_out_label_stack,
6393                   next_hop_out_label_stack,
6394                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6395           vec_free (next_hop_out_label_stack);
6396         }
6397
6398       if (is_ipv6)
6399         {
6400           clib_memcpy (mp->dst_address, &v6_dst_address,
6401                        sizeof (v6_dst_address));
6402           if (next_hop_set)
6403             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6404                          sizeof (v6_next_hop_address));
6405           increment_v6_address (&v6_dst_address);
6406         }
6407       else
6408         {
6409           clib_memcpy (mp->dst_address, &v4_dst_address,
6410                        sizeof (v4_dst_address));
6411           if (next_hop_set)
6412             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6413                          sizeof (v4_next_hop_address));
6414           if (random_add_del)
6415             v4_dst_address.as_u32 = random_vector[j + 1];
6416           else
6417             increment_v4_address (&v4_dst_address);
6418         }
6419       /* send it... */
6420       S (mp);
6421       /* If we receive SIGTERM, stop now... */
6422       if (vam->do_exit)
6423         break;
6424     }
6425
6426   /* When testing multiple add/del ops, use a control-ping to sync */
6427   if (count > 1)
6428     {
6429       vl_api_control_ping_t *mp_ping;
6430       f64 after;
6431       f64 timeout;
6432
6433       /* Shut off async mode */
6434       vam->async_mode = 0;
6435
6436       M (CONTROL_PING, mp_ping);
6437       S (mp_ping);
6438
6439       timeout = vat_time_now (vam) + 1.0;
6440       while (vat_time_now (vam) < timeout)
6441         if (vam->result_ready == 1)
6442           goto out;
6443       vam->retval = -99;
6444
6445     out:
6446       if (vam->retval == -99)
6447         errmsg ("timeout");
6448
6449       if (vam->async_errors > 0)
6450         {
6451           errmsg ("%d asynchronous errors", vam->async_errors);
6452           vam->retval = -98;
6453         }
6454       vam->async_errors = 0;
6455       after = vat_time_now (vam);
6456
6457       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6458       if (j > 0)
6459         count = j;
6460
6461       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6462              count, after - before, count / (after - before));
6463     }
6464   else
6465     {
6466       int ret;
6467
6468       /* Wait for a reply... */
6469       W (ret);
6470       return ret;
6471     }
6472
6473   /* Return the good/bad news */
6474   return (vam->retval);
6475 }
6476
6477 static int
6478 api_ip_mroute_add_del (vat_main_t * vam)
6479 {
6480   unformat_input_t *i = vam->input;
6481   vl_api_ip_mroute_add_del_t *mp;
6482   u32 sw_if_index = ~0, vrf_id = 0;
6483   u8 is_ipv6 = 0;
6484   u8 is_local = 0;
6485   u8 create_vrf_if_needed = 0;
6486   u8 is_add = 1;
6487   u8 address_set = 0;
6488   u32 grp_address_length = 0;
6489   ip4_address_t v4_grp_address, v4_src_address;
6490   ip6_address_t v6_grp_address, v6_src_address;
6491   mfib_itf_flags_t iflags = 0;
6492   mfib_entry_flags_t eflags = 0;
6493   int ret;
6494
6495   /* Parse args required to build the message */
6496   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6497     {
6498       if (unformat (i, "sw_if_index %d", &sw_if_index))
6499         ;
6500       else if (unformat (i, "%U %U",
6501                          unformat_ip4_address, &v4_src_address,
6502                          unformat_ip4_address, &v4_grp_address))
6503         {
6504           grp_address_length = 64;
6505           address_set = 1;
6506           is_ipv6 = 0;
6507         }
6508       else if (unformat (i, "%U %U",
6509                          unformat_ip6_address, &v6_src_address,
6510                          unformat_ip6_address, &v6_grp_address))
6511         {
6512           grp_address_length = 256;
6513           address_set = 1;
6514           is_ipv6 = 1;
6515         }
6516       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
6517         {
6518           memset (&v4_src_address, 0, sizeof (v4_src_address));
6519           grp_address_length = 32;
6520           address_set = 1;
6521           is_ipv6 = 0;
6522         }
6523       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
6524         {
6525           memset (&v6_src_address, 0, sizeof (v6_src_address));
6526           grp_address_length = 128;
6527           address_set = 1;
6528           is_ipv6 = 1;
6529         }
6530       else if (unformat (i, "/%d", &grp_address_length))
6531         ;
6532       else if (unformat (i, "local"))
6533         {
6534           is_local = 1;
6535         }
6536       else if (unformat (i, "del"))
6537         is_add = 0;
6538       else if (unformat (i, "add"))
6539         is_add = 1;
6540       else if (unformat (i, "vrf %d", &vrf_id))
6541         ;
6542       else if (unformat (i, "create-vrf"))
6543         create_vrf_if_needed = 1;
6544       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
6545         ;
6546       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6547         ;
6548       else
6549         {
6550           clib_warning ("parse error '%U'", format_unformat_error, i);
6551           return -99;
6552         }
6553     }
6554
6555   if (address_set == 0)
6556     {
6557       errmsg ("missing addresses\n");
6558       return -99;
6559     }
6560
6561   /* Construct the API message */
6562   M (IP_MROUTE_ADD_DEL, mp);
6563
6564   mp->next_hop_sw_if_index = ntohl (sw_if_index);
6565   mp->table_id = ntohl (vrf_id);
6566   mp->create_vrf_if_needed = create_vrf_if_needed;
6567
6568   mp->is_add = is_add;
6569   mp->is_ipv6 = is_ipv6;
6570   mp->is_local = is_local;
6571   mp->itf_flags = ntohl (iflags);
6572   mp->entry_flags = ntohl (eflags);
6573   mp->grp_address_length = grp_address_length;
6574   mp->grp_address_length = ntohs (mp->grp_address_length);
6575
6576   if (is_ipv6)
6577     {
6578       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
6579       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
6580     }
6581   else
6582     {
6583       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
6584       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
6585
6586     }
6587
6588   /* send it... */
6589   S (mp);
6590   /* Wait for a reply... */
6591   W (ret);
6592   return ret;
6593 }
6594
6595 static int
6596 api_mpls_route_add_del (vat_main_t * vam)
6597 {
6598   unformat_input_t *i = vam->input;
6599   vl_api_mpls_route_add_del_t *mp;
6600   u32 sw_if_index = ~0, table_id = 0;
6601   u8 create_table_if_needed = 0;
6602   u8 is_add = 1;
6603   u32 next_hop_weight = 1;
6604   u8 is_multipath = 0;
6605   u32 next_hop_table_id = 0;
6606   u8 next_hop_set = 0;
6607   ip4_address_t v4_next_hop_address = {
6608     .as_u32 = 0,
6609   };
6610   ip6_address_t v6_next_hop_address = { {0} };
6611   int count = 1;
6612   int j;
6613   f64 before = 0;
6614   u32 classify_table_index = ~0;
6615   u8 is_classify = 0;
6616   u8 resolve_host = 0, resolve_attached = 0;
6617   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6618   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6619   mpls_label_t *next_hop_out_label_stack = NULL;
6620   mpls_label_t local_label = MPLS_LABEL_INVALID;
6621   u8 is_eos = 0;
6622   u8 next_hop_proto_is_ip4 = 1;
6623
6624   /* Parse args required to build the message */
6625   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6626     {
6627       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6628         ;
6629       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6630         ;
6631       else if (unformat (i, "%d", &local_label))
6632         ;
6633       else if (unformat (i, "eos"))
6634         is_eos = 1;
6635       else if (unformat (i, "non-eos"))
6636         is_eos = 0;
6637       else if (unformat (i, "via %U", unformat_ip4_address,
6638                          &v4_next_hop_address))
6639         {
6640           next_hop_set = 1;
6641           next_hop_proto_is_ip4 = 1;
6642         }
6643       else if (unformat (i, "via %U", unformat_ip6_address,
6644                          &v6_next_hop_address))
6645         {
6646           next_hop_set = 1;
6647           next_hop_proto_is_ip4 = 0;
6648         }
6649       else if (unformat (i, "weight %d", &next_hop_weight))
6650         ;
6651       else if (unformat (i, "create-table"))
6652         create_table_if_needed = 1;
6653       else if (unformat (i, "classify %d", &classify_table_index))
6654         {
6655           is_classify = 1;
6656         }
6657       else if (unformat (i, "del"))
6658         is_add = 0;
6659       else if (unformat (i, "add"))
6660         is_add = 1;
6661       else if (unformat (i, "resolve-via-host"))
6662         resolve_host = 1;
6663       else if (unformat (i, "resolve-via-attached"))
6664         resolve_attached = 1;
6665       else if (unformat (i, "multipath"))
6666         is_multipath = 1;
6667       else if (unformat (i, "count %d", &count))
6668         ;
6669       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6670         {
6671           next_hop_set = 1;
6672           next_hop_proto_is_ip4 = 1;
6673         }
6674       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6675         {
6676           next_hop_set = 1;
6677           next_hop_proto_is_ip4 = 0;
6678         }
6679       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6680         ;
6681       else if (unformat (i, "via-label %d", &next_hop_via_label))
6682         ;
6683       else if (unformat (i, "out-label %d", &next_hop_out_label))
6684         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6685       else
6686         {
6687           clib_warning ("parse error '%U'", format_unformat_error, i);
6688           return -99;
6689         }
6690     }
6691
6692   if (!next_hop_set && !is_classify)
6693     {
6694       errmsg ("next hop / classify not set");
6695       return -99;
6696     }
6697
6698   if (MPLS_LABEL_INVALID == local_label)
6699     {
6700       errmsg ("missing label");
6701       return -99;
6702     }
6703
6704   if (count > 1)
6705     {
6706       /* Turn on async mode */
6707       vam->async_mode = 1;
6708       vam->async_errors = 0;
6709       before = vat_time_now (vam);
6710     }
6711
6712   for (j = 0; j < count; j++)
6713     {
6714       /* Construct the API message */
6715       M2 (MPLS_ROUTE_ADD_DEL, mp,
6716           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6717
6718       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6719       mp->mr_table_id = ntohl (table_id);
6720       mp->mr_create_table_if_needed = create_table_if_needed;
6721
6722       mp->mr_is_add = is_add;
6723       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6724       mp->mr_is_classify = is_classify;
6725       mp->mr_is_multipath = is_multipath;
6726       mp->mr_is_resolve_host = resolve_host;
6727       mp->mr_is_resolve_attached = resolve_attached;
6728       mp->mr_next_hop_weight = next_hop_weight;
6729       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6730       mp->mr_classify_table_index = ntohl (classify_table_index);
6731       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
6732       mp->mr_label = ntohl (local_label);
6733       mp->mr_eos = is_eos;
6734
6735       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6736       if (0 != mp->mr_next_hop_n_out_labels)
6737         {
6738           memcpy (mp->mr_next_hop_out_label_stack,
6739                   next_hop_out_label_stack,
6740                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6741           vec_free (next_hop_out_label_stack);
6742         }
6743
6744       if (next_hop_set)
6745         {
6746           if (next_hop_proto_is_ip4)
6747             {
6748               clib_memcpy (mp->mr_next_hop,
6749                            &v4_next_hop_address,
6750                            sizeof (v4_next_hop_address));
6751             }
6752           else
6753             {
6754               clib_memcpy (mp->mr_next_hop,
6755                            &v6_next_hop_address,
6756                            sizeof (v6_next_hop_address));
6757             }
6758         }
6759       local_label++;
6760
6761       /* send it... */
6762       S (mp);
6763       /* If we receive SIGTERM, stop now... */
6764       if (vam->do_exit)
6765         break;
6766     }
6767
6768   /* When testing multiple add/del ops, use a control-ping to sync */
6769   if (count > 1)
6770     {
6771       vl_api_control_ping_t *mp_ping;
6772       f64 after;
6773       f64 timeout;
6774
6775       /* Shut off async mode */
6776       vam->async_mode = 0;
6777
6778       M (CONTROL_PING, mp_ping);
6779       S (mp_ping);
6780
6781       timeout = vat_time_now (vam) + 1.0;
6782       while (vat_time_now (vam) < timeout)
6783         if (vam->result_ready == 1)
6784           goto out;
6785       vam->retval = -99;
6786
6787     out:
6788       if (vam->retval == -99)
6789         errmsg ("timeout");
6790
6791       if (vam->async_errors > 0)
6792         {
6793           errmsg ("%d asynchronous errors", vam->async_errors);
6794           vam->retval = -98;
6795         }
6796       vam->async_errors = 0;
6797       after = vat_time_now (vam);
6798
6799       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6800       if (j > 0)
6801         count = j;
6802
6803       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6804              count, after - before, count / (after - before));
6805     }
6806   else
6807     {
6808       int ret;
6809
6810       /* Wait for a reply... */
6811       W (ret);
6812       return ret;
6813     }
6814
6815   /* Return the good/bad news */
6816   return (vam->retval);
6817 }
6818
6819 static int
6820 api_mpls_ip_bind_unbind (vat_main_t * vam)
6821 {
6822   unformat_input_t *i = vam->input;
6823   vl_api_mpls_ip_bind_unbind_t *mp;
6824   u32 ip_table_id = 0;
6825   u8 create_table_if_needed = 0;
6826   u8 is_bind = 1;
6827   u8 is_ip4 = 1;
6828   ip4_address_t v4_address;
6829   ip6_address_t v6_address;
6830   u32 address_length;
6831   u8 address_set = 0;
6832   mpls_label_t local_label = MPLS_LABEL_INVALID;
6833   int ret;
6834
6835   /* Parse args required to build the message */
6836   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6837     {
6838       if (unformat (i, "%U/%d", unformat_ip4_address,
6839                     &v4_address, &address_length))
6840         {
6841           is_ip4 = 1;
6842           address_set = 1;
6843         }
6844       else if (unformat (i, "%U/%d", unformat_ip6_address,
6845                          &v6_address, &address_length))
6846         {
6847           is_ip4 = 0;
6848           address_set = 1;
6849         }
6850       else if (unformat (i, "%d", &local_label))
6851         ;
6852       else if (unformat (i, "create-table"))
6853         create_table_if_needed = 1;
6854       else if (unformat (i, "table-id %d", &ip_table_id))
6855         ;
6856       else if (unformat (i, "unbind"))
6857         is_bind = 0;
6858       else if (unformat (i, "bind"))
6859         is_bind = 1;
6860       else
6861         {
6862           clib_warning ("parse error '%U'", format_unformat_error, i);
6863           return -99;
6864         }
6865     }
6866
6867   if (!address_set)
6868     {
6869       errmsg ("IP addres not set");
6870       return -99;
6871     }
6872
6873   if (MPLS_LABEL_INVALID == local_label)
6874     {
6875       errmsg ("missing label");
6876       return -99;
6877     }
6878
6879   /* Construct the API message */
6880   M (MPLS_IP_BIND_UNBIND, mp);
6881
6882   mp->mb_create_table_if_needed = create_table_if_needed;
6883   mp->mb_is_bind = is_bind;
6884   mp->mb_is_ip4 = is_ip4;
6885   mp->mb_ip_table_id = ntohl (ip_table_id);
6886   mp->mb_mpls_table_id = 0;
6887   mp->mb_label = ntohl (local_label);
6888   mp->mb_address_length = address_length;
6889
6890   if (is_ip4)
6891     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
6892   else
6893     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
6894
6895   /* send it... */
6896   S (mp);
6897
6898   /* Wait for a reply... */
6899   W (ret);
6900   return ret;
6901 }
6902
6903 static int
6904 api_proxy_arp_add_del (vat_main_t * vam)
6905 {
6906   unformat_input_t *i = vam->input;
6907   vl_api_proxy_arp_add_del_t *mp;
6908   u32 vrf_id = 0;
6909   u8 is_add = 1;
6910   ip4_address_t lo, hi;
6911   u8 range_set = 0;
6912   int ret;
6913
6914   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6915     {
6916       if (unformat (i, "vrf %d", &vrf_id))
6917         ;
6918       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
6919                          unformat_ip4_address, &hi))
6920         range_set = 1;
6921       else if (unformat (i, "del"))
6922         is_add = 0;
6923       else
6924         {
6925           clib_warning ("parse error '%U'", format_unformat_error, i);
6926           return -99;
6927         }
6928     }
6929
6930   if (range_set == 0)
6931     {
6932       errmsg ("address range not set");
6933       return -99;
6934     }
6935
6936   M (PROXY_ARP_ADD_DEL, mp);
6937
6938   mp->vrf_id = ntohl (vrf_id);
6939   mp->is_add = is_add;
6940   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
6941   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
6942
6943   S (mp);
6944   W (ret);
6945   return ret;
6946 }
6947
6948 static int
6949 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
6950 {
6951   unformat_input_t *i = vam->input;
6952   vl_api_proxy_arp_intfc_enable_disable_t *mp;
6953   u32 sw_if_index;
6954   u8 enable = 1;
6955   u8 sw_if_index_set = 0;
6956   int ret;
6957
6958   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6959     {
6960       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6961         sw_if_index_set = 1;
6962       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6963         sw_if_index_set = 1;
6964       else if (unformat (i, "enable"))
6965         enable = 1;
6966       else if (unformat (i, "disable"))
6967         enable = 0;
6968       else
6969         {
6970           clib_warning ("parse error '%U'", format_unformat_error, i);
6971           return -99;
6972         }
6973     }
6974
6975   if (sw_if_index_set == 0)
6976     {
6977       errmsg ("missing interface name or sw_if_index");
6978       return -99;
6979     }
6980
6981   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
6982
6983   mp->sw_if_index = ntohl (sw_if_index);
6984   mp->enable_disable = enable;
6985
6986   S (mp);
6987   W (ret);
6988   return ret;
6989 }
6990
6991 static int
6992 api_mpls_tunnel_add_del (vat_main_t * vam)
6993 {
6994   unformat_input_t *i = vam->input;
6995   vl_api_mpls_tunnel_add_del_t *mp;
6996
6997   u8 is_add = 1;
6998   u8 l2_only = 0;
6999   u32 sw_if_index = ~0;
7000   u32 next_hop_sw_if_index = ~0;
7001   u32 next_hop_proto_is_ip4 = 1;
7002
7003   u32 next_hop_table_id = 0;
7004   ip4_address_t v4_next_hop_address = {
7005     .as_u32 = 0,
7006   };
7007   ip6_address_t v6_next_hop_address = { {0} };
7008   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
7009   int ret;
7010
7011   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7012     {
7013       if (unformat (i, "add"))
7014         is_add = 1;
7015       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7016         is_add = 0;
7017       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7018         ;
7019       else if (unformat (i, "via %U",
7020                          unformat_ip4_address, &v4_next_hop_address))
7021         {
7022           next_hop_proto_is_ip4 = 1;
7023         }
7024       else if (unformat (i, "via %U",
7025                          unformat_ip6_address, &v6_next_hop_address))
7026         {
7027           next_hop_proto_is_ip4 = 0;
7028         }
7029       else if (unformat (i, "l2-only"))
7030         l2_only = 1;
7031       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7032         ;
7033       else if (unformat (i, "out-label %d", &next_hop_out_label))
7034         vec_add1 (labels, ntohl (next_hop_out_label));
7035       else
7036         {
7037           clib_warning ("parse error '%U'", format_unformat_error, i);
7038           return -99;
7039         }
7040     }
7041
7042   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
7043
7044   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
7045   mp->mt_sw_if_index = ntohl (sw_if_index);
7046   mp->mt_is_add = is_add;
7047   mp->mt_l2_only = l2_only;
7048   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
7049   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7050
7051   mp->mt_next_hop_n_out_labels = vec_len (labels);
7052
7053   if (0 != mp->mt_next_hop_n_out_labels)
7054     {
7055       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7056                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7057       vec_free (labels);
7058     }
7059
7060   if (next_hop_proto_is_ip4)
7061     {
7062       clib_memcpy (mp->mt_next_hop,
7063                    &v4_next_hop_address, sizeof (v4_next_hop_address));
7064     }
7065   else
7066     {
7067       clib_memcpy (mp->mt_next_hop,
7068                    &v6_next_hop_address, sizeof (v6_next_hop_address));
7069     }
7070
7071   S (mp);
7072   W (ret);
7073   return ret;
7074 }
7075
7076 static int
7077 api_sw_interface_set_unnumbered (vat_main_t * vam)
7078 {
7079   unformat_input_t *i = vam->input;
7080   vl_api_sw_interface_set_unnumbered_t *mp;
7081   u32 sw_if_index;
7082   u32 unnum_sw_index = ~0;
7083   u8 is_add = 1;
7084   u8 sw_if_index_set = 0;
7085   int ret;
7086
7087   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7088     {
7089       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7090         sw_if_index_set = 1;
7091       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7092         sw_if_index_set = 1;
7093       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7094         ;
7095       else if (unformat (i, "del"))
7096         is_add = 0;
7097       else
7098         {
7099           clib_warning ("parse error '%U'", format_unformat_error, i);
7100           return -99;
7101         }
7102     }
7103
7104   if (sw_if_index_set == 0)
7105     {
7106       errmsg ("missing interface name or sw_if_index");
7107       return -99;
7108     }
7109
7110   M (SW_INTERFACE_SET_UNNUMBERED, mp);
7111
7112   mp->sw_if_index = ntohl (sw_if_index);
7113   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7114   mp->is_add = is_add;
7115
7116   S (mp);
7117   W (ret);
7118   return ret;
7119 }
7120
7121 static int
7122 api_ip_neighbor_add_del (vat_main_t * vam)
7123 {
7124   unformat_input_t *i = vam->input;
7125   vl_api_ip_neighbor_add_del_t *mp;
7126   u32 sw_if_index;
7127   u8 sw_if_index_set = 0;
7128   u8 is_add = 1;
7129   u8 is_static = 0;
7130   u8 mac_address[6];
7131   u8 mac_set = 0;
7132   u8 v4_address_set = 0;
7133   u8 v6_address_set = 0;
7134   ip4_address_t v4address;
7135   ip6_address_t v6address;
7136   int ret;
7137
7138   memset (mac_address, 0, sizeof (mac_address));
7139
7140   /* Parse args required to build the message */
7141   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7142     {
7143       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7144         {
7145           mac_set = 1;
7146         }
7147       else if (unformat (i, "del"))
7148         is_add = 0;
7149       else
7150         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7151         sw_if_index_set = 1;
7152       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7153         sw_if_index_set = 1;
7154       else if (unformat (i, "is_static"))
7155         is_static = 1;
7156       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
7157         v4_address_set = 1;
7158       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
7159         v6_address_set = 1;
7160       else
7161         {
7162           clib_warning ("parse error '%U'", format_unformat_error, i);
7163           return -99;
7164         }
7165     }
7166
7167   if (sw_if_index_set == 0)
7168     {
7169       errmsg ("missing interface name or sw_if_index");
7170       return -99;
7171     }
7172   if (v4_address_set && v6_address_set)
7173     {
7174       errmsg ("both v4 and v6 addresses set");
7175       return -99;
7176     }
7177   if (!v4_address_set && !v6_address_set)
7178     {
7179       errmsg ("no address set");
7180       return -99;
7181     }
7182
7183   /* Construct the API message */
7184   M (IP_NEIGHBOR_ADD_DEL, mp);
7185
7186   mp->sw_if_index = ntohl (sw_if_index);
7187   mp->is_add = is_add;
7188   mp->is_static = is_static;
7189   if (mac_set)
7190     clib_memcpy (mp->mac_address, mac_address, 6);
7191   if (v6_address_set)
7192     {
7193       mp->is_ipv6 = 1;
7194       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
7195     }
7196   else
7197     {
7198       /* mp->is_ipv6 = 0; via memset in M macro above */
7199       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
7200     }
7201
7202   /* send it... */
7203   S (mp);
7204
7205   /* Wait for a reply, return good/bad news  */
7206   W (ret);
7207   return ret;
7208 }
7209
7210 static int
7211 api_reset_vrf (vat_main_t * vam)
7212 {
7213   unformat_input_t *i = vam->input;
7214   vl_api_reset_vrf_t *mp;
7215   u32 vrf_id = 0;
7216   u8 is_ipv6 = 0;
7217   u8 vrf_id_set = 0;
7218   int ret;
7219
7220   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7221     {
7222       if (unformat (i, "vrf %d", &vrf_id))
7223         vrf_id_set = 1;
7224       else if (unformat (i, "ipv6"))
7225         is_ipv6 = 1;
7226       else
7227         {
7228           clib_warning ("parse error '%U'", format_unformat_error, i);
7229           return -99;
7230         }
7231     }
7232
7233   if (vrf_id_set == 0)
7234     {
7235       errmsg ("missing vrf id");
7236       return -99;
7237     }
7238
7239   M (RESET_VRF, mp);
7240
7241   mp->vrf_id = ntohl (vrf_id);
7242   mp->is_ipv6 = is_ipv6;
7243
7244   S (mp);
7245   W (ret);
7246   return ret;
7247 }
7248
7249 static int
7250 api_create_vlan_subif (vat_main_t * vam)
7251 {
7252   unformat_input_t *i = vam->input;
7253   vl_api_create_vlan_subif_t *mp;
7254   u32 sw_if_index;
7255   u8 sw_if_index_set = 0;
7256   u32 vlan_id;
7257   u8 vlan_id_set = 0;
7258   int ret;
7259
7260   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7261     {
7262       if (unformat (i, "sw_if_index %d", &sw_if_index))
7263         sw_if_index_set = 1;
7264       else
7265         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7266         sw_if_index_set = 1;
7267       else if (unformat (i, "vlan %d", &vlan_id))
7268         vlan_id_set = 1;
7269       else
7270         {
7271           clib_warning ("parse error '%U'", format_unformat_error, i);
7272           return -99;
7273         }
7274     }
7275
7276   if (sw_if_index_set == 0)
7277     {
7278       errmsg ("missing interface name or sw_if_index");
7279       return -99;
7280     }
7281
7282   if (vlan_id_set == 0)
7283     {
7284       errmsg ("missing vlan_id");
7285       return -99;
7286     }
7287   M (CREATE_VLAN_SUBIF, mp);
7288
7289   mp->sw_if_index = ntohl (sw_if_index);
7290   mp->vlan_id = ntohl (vlan_id);
7291
7292   S (mp);
7293   W (ret);
7294   return ret;
7295 }
7296
7297 #define foreach_create_subif_bit                \
7298 _(no_tags)                                      \
7299 _(one_tag)                                      \
7300 _(two_tags)                                     \
7301 _(dot1ad)                                       \
7302 _(exact_match)                                  \
7303 _(default_sub)                                  \
7304 _(outer_vlan_id_any)                            \
7305 _(inner_vlan_id_any)
7306
7307 static int
7308 api_create_subif (vat_main_t * vam)
7309 {
7310   unformat_input_t *i = vam->input;
7311   vl_api_create_subif_t *mp;
7312   u32 sw_if_index;
7313   u8 sw_if_index_set = 0;
7314   u32 sub_id;
7315   u8 sub_id_set = 0;
7316   u32 no_tags = 0;
7317   u32 one_tag = 0;
7318   u32 two_tags = 0;
7319   u32 dot1ad = 0;
7320   u32 exact_match = 0;
7321   u32 default_sub = 0;
7322   u32 outer_vlan_id_any = 0;
7323   u32 inner_vlan_id_any = 0;
7324   u32 tmp;
7325   u16 outer_vlan_id = 0;
7326   u16 inner_vlan_id = 0;
7327   int ret;
7328
7329   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7330     {
7331       if (unformat (i, "sw_if_index %d", &sw_if_index))
7332         sw_if_index_set = 1;
7333       else
7334         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7335         sw_if_index_set = 1;
7336       else if (unformat (i, "sub_id %d", &sub_id))
7337         sub_id_set = 1;
7338       else if (unformat (i, "outer_vlan_id %d", &tmp))
7339         outer_vlan_id = tmp;
7340       else if (unformat (i, "inner_vlan_id %d", &tmp))
7341         inner_vlan_id = tmp;
7342
7343 #define _(a) else if (unformat (i, #a)) a = 1 ;
7344       foreach_create_subif_bit
7345 #undef _
7346         else
7347         {
7348           clib_warning ("parse error '%U'", format_unformat_error, i);
7349           return -99;
7350         }
7351     }
7352
7353   if (sw_if_index_set == 0)
7354     {
7355       errmsg ("missing interface name or sw_if_index");
7356       return -99;
7357     }
7358
7359   if (sub_id_set == 0)
7360     {
7361       errmsg ("missing sub_id");
7362       return -99;
7363     }
7364   M (CREATE_SUBIF, mp);
7365
7366   mp->sw_if_index = ntohl (sw_if_index);
7367   mp->sub_id = ntohl (sub_id);
7368
7369 #define _(a) mp->a = a;
7370   foreach_create_subif_bit;
7371 #undef _
7372
7373   mp->outer_vlan_id = ntohs (outer_vlan_id);
7374   mp->inner_vlan_id = ntohs (inner_vlan_id);
7375
7376   S (mp);
7377   W (ret);
7378   return ret;
7379 }
7380
7381 static int
7382 api_oam_add_del (vat_main_t * vam)
7383 {
7384   unformat_input_t *i = vam->input;
7385   vl_api_oam_add_del_t *mp;
7386   u32 vrf_id = 0;
7387   u8 is_add = 1;
7388   ip4_address_t src, dst;
7389   u8 src_set = 0;
7390   u8 dst_set = 0;
7391   int ret;
7392
7393   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7394     {
7395       if (unformat (i, "vrf %d", &vrf_id))
7396         ;
7397       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7398         src_set = 1;
7399       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7400         dst_set = 1;
7401       else if (unformat (i, "del"))
7402         is_add = 0;
7403       else
7404         {
7405           clib_warning ("parse error '%U'", format_unformat_error, i);
7406           return -99;
7407         }
7408     }
7409
7410   if (src_set == 0)
7411     {
7412       errmsg ("missing src addr");
7413       return -99;
7414     }
7415
7416   if (dst_set == 0)
7417     {
7418       errmsg ("missing dst addr");
7419       return -99;
7420     }
7421
7422   M (OAM_ADD_DEL, mp);
7423
7424   mp->vrf_id = ntohl (vrf_id);
7425   mp->is_add = is_add;
7426   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7427   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7428
7429   S (mp);
7430   W (ret);
7431   return ret;
7432 }
7433
7434 static int
7435 api_reset_fib (vat_main_t * vam)
7436 {
7437   unformat_input_t *i = vam->input;
7438   vl_api_reset_fib_t *mp;
7439   u32 vrf_id = 0;
7440   u8 is_ipv6 = 0;
7441   u8 vrf_id_set = 0;
7442
7443   int ret;
7444   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7445     {
7446       if (unformat (i, "vrf %d", &vrf_id))
7447         vrf_id_set = 1;
7448       else if (unformat (i, "ipv6"))
7449         is_ipv6 = 1;
7450       else
7451         {
7452           clib_warning ("parse error '%U'", format_unformat_error, i);
7453           return -99;
7454         }
7455     }
7456
7457   if (vrf_id_set == 0)
7458     {
7459       errmsg ("missing vrf id");
7460       return -99;
7461     }
7462
7463   M (RESET_FIB, mp);
7464
7465   mp->vrf_id = ntohl (vrf_id);
7466   mp->is_ipv6 = is_ipv6;
7467
7468   S (mp);
7469   W (ret);
7470   return ret;
7471 }
7472
7473 static int
7474 api_dhcp_proxy_config (vat_main_t * vam)
7475 {
7476   unformat_input_t *i = vam->input;
7477   vl_api_dhcp_proxy_config_t *mp;
7478   u32 rx_vrf_id = 0;
7479   u32 server_vrf_id = 0;
7480   u8 is_add = 1;
7481   u8 v4_address_set = 0;
7482   u8 v6_address_set = 0;
7483   ip4_address_t v4address;
7484   ip6_address_t v6address;
7485   u8 v4_src_address_set = 0;
7486   u8 v6_src_address_set = 0;
7487   ip4_address_t v4srcaddress;
7488   ip6_address_t v6srcaddress;
7489   int ret;
7490
7491   /* Parse args required to build the message */
7492   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7493     {
7494       if (unformat (i, "del"))
7495         is_add = 0;
7496       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7497         ;
7498       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7499         ;
7500       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7501         v4_address_set = 1;
7502       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7503         v6_address_set = 1;
7504       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7505         v4_src_address_set = 1;
7506       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7507         v6_src_address_set = 1;
7508       else
7509         break;
7510     }
7511
7512   if (v4_address_set && v6_address_set)
7513     {
7514       errmsg ("both v4 and v6 server addresses set");
7515       return -99;
7516     }
7517   if (!v4_address_set && !v6_address_set)
7518     {
7519       errmsg ("no server addresses set");
7520       return -99;
7521     }
7522
7523   if (v4_src_address_set && v6_src_address_set)
7524     {
7525       errmsg ("both v4 and v6  src addresses set");
7526       return -99;
7527     }
7528   if (!v4_src_address_set && !v6_src_address_set)
7529     {
7530       errmsg ("no src addresses set");
7531       return -99;
7532     }
7533
7534   if (!(v4_src_address_set && v4_address_set) &&
7535       !(v6_src_address_set && v6_address_set))
7536     {
7537       errmsg ("no matching server and src addresses set");
7538       return -99;
7539     }
7540
7541   /* Construct the API message */
7542   M (DHCP_PROXY_CONFIG, mp);
7543
7544   mp->is_add = is_add;
7545   mp->rx_vrf_id = ntohl (rx_vrf_id);
7546   mp->server_vrf_id = ntohl (server_vrf_id);
7547   if (v6_address_set)
7548     {
7549       mp->is_ipv6 = 1;
7550       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7551       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7552     }
7553   else
7554     {
7555       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7556       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7557     }
7558
7559   /* send it... */
7560   S (mp);
7561
7562   /* Wait for a reply, return good/bad news  */
7563   W (ret);
7564   return ret;
7565 }
7566
7567 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
7568 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
7569
7570 static void
7571 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
7572 {
7573   vat_main_t *vam = &vat_main;
7574
7575   if (mp->is_ipv6)
7576     print (vam->ofp,
7577            "RX Table-ID %d, Server Table-ID %d, Server Address %U, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7578            ntohl (mp->rx_vrf_id),
7579            ntohl (mp->server_vrf_id),
7580            format_ip6_address, mp->dhcp_server,
7581            format_ip6_address, mp->dhcp_src_address,
7582            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7583   else
7584     print (vam->ofp,
7585            "RX Table-ID %d, Server Table-ID %d, Server Address %U, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7586            ntohl (mp->rx_vrf_id),
7587            ntohl (mp->server_vrf_id),
7588            format_ip4_address, mp->dhcp_server,
7589            format_ip4_address, mp->dhcp_src_address,
7590            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7591 }
7592
7593 static void vl_api_dhcp_proxy_details_t_handler_json
7594   (vl_api_dhcp_proxy_details_t * mp)
7595 {
7596   vat_main_t *vam = &vat_main;
7597   vat_json_node_t *node = NULL;
7598   struct in_addr ip4;
7599   struct in6_addr ip6;
7600
7601   if (VAT_JSON_ARRAY != vam->json_tree.type)
7602     {
7603       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7604       vat_json_init_array (&vam->json_tree);
7605     }
7606   node = vat_json_array_add (&vam->json_tree);
7607
7608   vat_json_init_object (node);
7609   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
7610   vat_json_object_add_uint (node, "server-table-id",
7611                             ntohl (mp->server_vrf_id));
7612   if (mp->is_ipv6)
7613     {
7614       clib_memcpy (&ip6, &mp->dhcp_server, sizeof (ip6));
7615       vat_json_object_add_ip6 (node, "server_address", ip6);
7616       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
7617       vat_json_object_add_ip6 (node, "src_address", ip6);
7618     }
7619   else
7620     {
7621       clib_memcpy (&ip4, &mp->dhcp_server, sizeof (ip4));
7622       vat_json_object_add_ip4 (node, "server_address", ip4);
7623       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
7624       vat_json_object_add_ip4 (node, "src_address", ip4);
7625     }
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
7630 static int
7631 api_dhcp_proxy_dump (vat_main_t * vam)
7632 {
7633   unformat_input_t *i = vam->input;
7634   vl_api_control_ping_t *mp_ping;
7635   vl_api_dhcp_proxy_dump_t *mp;
7636   u8 is_ipv6 = 0;
7637   int ret;
7638
7639   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7640     {
7641       if (unformat (i, "ipv6"))
7642         is_ipv6 = 1;
7643       else
7644         {
7645           clib_warning ("parse error '%U'", format_unformat_error, i);
7646           return -99;
7647         }
7648     }
7649
7650   M (DHCP_PROXY_DUMP, mp);
7651
7652   mp->is_ip6 = is_ipv6;
7653   S (mp);
7654
7655   /* Use a control ping for synchronization */
7656   M (CONTROL_PING, mp_ping);
7657   S (mp_ping);
7658
7659   W (ret);
7660   return ret;
7661 }
7662
7663 static int
7664 api_dhcp_proxy_set_vss (vat_main_t * vam)
7665 {
7666   unformat_input_t *i = vam->input;
7667   vl_api_dhcp_proxy_set_vss_t *mp;
7668   u8 is_ipv6 = 0;
7669   u8 is_add = 1;
7670   u32 tbl_id;
7671   u8 tbl_id_set = 0;
7672   u32 oui;
7673   u8 oui_set = 0;
7674   u32 fib_id;
7675   u8 fib_id_set = 0;
7676   int ret;
7677
7678   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7679     {
7680       if (unformat (i, "tbl_id %d", &tbl_id))
7681         tbl_id_set = 1;
7682       if (unformat (i, "fib_id %d", &fib_id))
7683         fib_id_set = 1;
7684       if (unformat (i, "oui %d", &oui))
7685         oui_set = 1;
7686       else if (unformat (i, "ipv6"))
7687         is_ipv6 = 1;
7688       else if (unformat (i, "del"))
7689         is_add = 0;
7690       else
7691         {
7692           clib_warning ("parse error '%U'", format_unformat_error, i);
7693           return -99;
7694         }
7695     }
7696
7697   if (tbl_id_set == 0)
7698     {
7699       errmsg ("missing tbl id");
7700       return -99;
7701     }
7702
7703   if (fib_id_set == 0)
7704     {
7705       errmsg ("missing fib id");
7706       return -99;
7707     }
7708   if (oui_set == 0)
7709     {
7710       errmsg ("missing oui");
7711       return -99;
7712     }
7713
7714   M (DHCP_PROXY_SET_VSS, mp);
7715   mp->tbl_id = ntohl (tbl_id);
7716   mp->fib_id = ntohl (fib_id);
7717   mp->oui = ntohl (oui);
7718   mp->is_ipv6 = is_ipv6;
7719   mp->is_add = is_add;
7720
7721   S (mp);
7722   W (ret);
7723   return ret;
7724 }
7725
7726 static int
7727 api_dhcp_client_config (vat_main_t * vam)
7728 {
7729   unformat_input_t *i = vam->input;
7730   vl_api_dhcp_client_config_t *mp;
7731   u32 sw_if_index;
7732   u8 sw_if_index_set = 0;
7733   u8 is_add = 1;
7734   u8 *hostname = 0;
7735   u8 disable_event = 0;
7736   int ret;
7737
7738   /* Parse args required to build the message */
7739   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7740     {
7741       if (unformat (i, "del"))
7742         is_add = 0;
7743       else
7744         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7745         sw_if_index_set = 1;
7746       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7747         sw_if_index_set = 1;
7748       else if (unformat (i, "hostname %s", &hostname))
7749         ;
7750       else if (unformat (i, "disable_event"))
7751         disable_event = 1;
7752       else
7753         break;
7754     }
7755
7756   if (sw_if_index_set == 0)
7757     {
7758       errmsg ("missing interface name or sw_if_index");
7759       return -99;
7760     }
7761
7762   if (vec_len (hostname) > 63)
7763     {
7764       errmsg ("hostname too long");
7765     }
7766   vec_add1 (hostname, 0);
7767
7768   /* Construct the API message */
7769   M (DHCP_CLIENT_CONFIG, mp);
7770
7771   mp->sw_if_index = ntohl (sw_if_index);
7772   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7773   vec_free (hostname);
7774   mp->is_add = is_add;
7775   mp->want_dhcp_event = disable_event ? 0 : 1;
7776   mp->pid = getpid ();
7777
7778   /* send it... */
7779   S (mp);
7780
7781   /* Wait for a reply, return good/bad news  */
7782   W (ret);
7783   return ret;
7784 }
7785
7786 static int
7787 api_set_ip_flow_hash (vat_main_t * vam)
7788 {
7789   unformat_input_t *i = vam->input;
7790   vl_api_set_ip_flow_hash_t *mp;
7791   u32 vrf_id = 0;
7792   u8 is_ipv6 = 0;
7793   u8 vrf_id_set = 0;
7794   u8 src = 0;
7795   u8 dst = 0;
7796   u8 sport = 0;
7797   u8 dport = 0;
7798   u8 proto = 0;
7799   u8 reverse = 0;
7800   int ret;
7801
7802   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7803     {
7804       if (unformat (i, "vrf %d", &vrf_id))
7805         vrf_id_set = 1;
7806       else if (unformat (i, "ipv6"))
7807         is_ipv6 = 1;
7808       else if (unformat (i, "src"))
7809         src = 1;
7810       else if (unformat (i, "dst"))
7811         dst = 1;
7812       else if (unformat (i, "sport"))
7813         sport = 1;
7814       else if (unformat (i, "dport"))
7815         dport = 1;
7816       else if (unformat (i, "proto"))
7817         proto = 1;
7818       else if (unformat (i, "reverse"))
7819         reverse = 1;
7820
7821       else
7822         {
7823           clib_warning ("parse error '%U'", format_unformat_error, i);
7824           return -99;
7825         }
7826     }
7827
7828   if (vrf_id_set == 0)
7829     {
7830       errmsg ("missing vrf id");
7831       return -99;
7832     }
7833
7834   M (SET_IP_FLOW_HASH, mp);
7835   mp->src = src;
7836   mp->dst = dst;
7837   mp->sport = sport;
7838   mp->dport = dport;
7839   mp->proto = proto;
7840   mp->reverse = reverse;
7841   mp->vrf_id = ntohl (vrf_id);
7842   mp->is_ipv6 = is_ipv6;
7843
7844   S (mp);
7845   W (ret);
7846   return ret;
7847 }
7848
7849 static int
7850 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7851 {
7852   unformat_input_t *i = vam->input;
7853   vl_api_sw_interface_ip6_enable_disable_t *mp;
7854   u32 sw_if_index;
7855   u8 sw_if_index_set = 0;
7856   u8 enable = 0;
7857   int ret;
7858
7859   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7860     {
7861       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7862         sw_if_index_set = 1;
7863       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7864         sw_if_index_set = 1;
7865       else if (unformat (i, "enable"))
7866         enable = 1;
7867       else if (unformat (i, "disable"))
7868         enable = 0;
7869       else
7870         {
7871           clib_warning ("parse error '%U'", format_unformat_error, i);
7872           return -99;
7873         }
7874     }
7875
7876   if (sw_if_index_set == 0)
7877     {
7878       errmsg ("missing interface name or sw_if_index");
7879       return -99;
7880     }
7881
7882   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
7883
7884   mp->sw_if_index = ntohl (sw_if_index);
7885   mp->enable = enable;
7886
7887   S (mp);
7888   W (ret);
7889   return ret;
7890 }
7891
7892 static int
7893 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7894 {
7895   unformat_input_t *i = vam->input;
7896   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7897   u32 sw_if_index;
7898   u8 sw_if_index_set = 0;
7899   u8 v6_address_set = 0;
7900   ip6_address_t v6address;
7901   int ret;
7902
7903   /* Parse args required to build the message */
7904   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7905     {
7906       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7907         sw_if_index_set = 1;
7908       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7909         sw_if_index_set = 1;
7910       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
7911         v6_address_set = 1;
7912       else
7913         break;
7914     }
7915
7916   if (sw_if_index_set == 0)
7917     {
7918       errmsg ("missing interface name or sw_if_index");
7919       return -99;
7920     }
7921   if (!v6_address_set)
7922     {
7923       errmsg ("no address set");
7924       return -99;
7925     }
7926
7927   /* Construct the API message */
7928   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
7929
7930   mp->sw_if_index = ntohl (sw_if_index);
7931   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7932
7933   /* send it... */
7934   S (mp);
7935
7936   /* Wait for a reply, return good/bad news  */
7937   W (ret);
7938   return ret;
7939 }
7940
7941
7942 static int
7943 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7944 {
7945   unformat_input_t *i = vam->input;
7946   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7947   u32 sw_if_index;
7948   u8 sw_if_index_set = 0;
7949   u32 address_length = 0;
7950   u8 v6_address_set = 0;
7951   ip6_address_t v6address;
7952   u8 use_default = 0;
7953   u8 no_advertise = 0;
7954   u8 off_link = 0;
7955   u8 no_autoconfig = 0;
7956   u8 no_onlink = 0;
7957   u8 is_no = 0;
7958   u32 val_lifetime = 0;
7959   u32 pref_lifetime = 0;
7960   int ret;
7961
7962   /* Parse args required to build the message */
7963   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7964     {
7965       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7966         sw_if_index_set = 1;
7967       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7968         sw_if_index_set = 1;
7969       else if (unformat (i, "%U/%d",
7970                          unformat_ip6_address, &v6address, &address_length))
7971         v6_address_set = 1;
7972       else if (unformat (i, "val_life %d", &val_lifetime))
7973         ;
7974       else if (unformat (i, "pref_life %d", &pref_lifetime))
7975         ;
7976       else if (unformat (i, "def"))
7977         use_default = 1;
7978       else if (unformat (i, "noadv"))
7979         no_advertise = 1;
7980       else if (unformat (i, "offl"))
7981         off_link = 1;
7982       else if (unformat (i, "noauto"))
7983         no_autoconfig = 1;
7984       else if (unformat (i, "nolink"))
7985         no_onlink = 1;
7986       else if (unformat (i, "isno"))
7987         is_no = 1;
7988       else
7989         {
7990           clib_warning ("parse error '%U'", format_unformat_error, i);
7991           return -99;
7992         }
7993     }
7994
7995   if (sw_if_index_set == 0)
7996     {
7997       errmsg ("missing interface name or sw_if_index");
7998       return -99;
7999     }
8000   if (!v6_address_set)
8001     {
8002       errmsg ("no address set");
8003       return -99;
8004     }
8005
8006   /* Construct the API message */
8007   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
8008
8009   mp->sw_if_index = ntohl (sw_if_index);
8010   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8011   mp->address_length = address_length;
8012   mp->use_default = use_default;
8013   mp->no_advertise = no_advertise;
8014   mp->off_link = off_link;
8015   mp->no_autoconfig = no_autoconfig;
8016   mp->no_onlink = no_onlink;
8017   mp->is_no = is_no;
8018   mp->val_lifetime = ntohl (val_lifetime);
8019   mp->pref_lifetime = ntohl (pref_lifetime);
8020
8021   /* send it... */
8022   S (mp);
8023
8024   /* Wait for a reply, return good/bad news  */
8025   W (ret);
8026   return ret;
8027 }
8028
8029 static int
8030 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
8031 {
8032   unformat_input_t *i = vam->input;
8033   vl_api_sw_interface_ip6nd_ra_config_t *mp;
8034   u32 sw_if_index;
8035   u8 sw_if_index_set = 0;
8036   u8 suppress = 0;
8037   u8 managed = 0;
8038   u8 other = 0;
8039   u8 ll_option = 0;
8040   u8 send_unicast = 0;
8041   u8 cease = 0;
8042   u8 is_no = 0;
8043   u8 default_router = 0;
8044   u32 max_interval = 0;
8045   u32 min_interval = 0;
8046   u32 lifetime = 0;
8047   u32 initial_count = 0;
8048   u32 initial_interval = 0;
8049   int ret;
8050
8051
8052   /* Parse args required to build the message */
8053   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8054     {
8055       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8056         sw_if_index_set = 1;
8057       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8058         sw_if_index_set = 1;
8059       else if (unformat (i, "maxint %d", &max_interval))
8060         ;
8061       else if (unformat (i, "minint %d", &min_interval))
8062         ;
8063       else if (unformat (i, "life %d", &lifetime))
8064         ;
8065       else if (unformat (i, "count %d", &initial_count))
8066         ;
8067       else if (unformat (i, "interval %d", &initial_interval))
8068         ;
8069       else if (unformat (i, "suppress") || unformat (i, "surpress"))
8070         suppress = 1;
8071       else if (unformat (i, "managed"))
8072         managed = 1;
8073       else if (unformat (i, "other"))
8074         other = 1;
8075       else if (unformat (i, "ll"))
8076         ll_option = 1;
8077       else if (unformat (i, "send"))
8078         send_unicast = 1;
8079       else if (unformat (i, "cease"))
8080         cease = 1;
8081       else if (unformat (i, "isno"))
8082         is_no = 1;
8083       else if (unformat (i, "def"))
8084         default_router = 1;
8085       else
8086         {
8087           clib_warning ("parse error '%U'", format_unformat_error, i);
8088           return -99;
8089         }
8090     }
8091
8092   if (sw_if_index_set == 0)
8093     {
8094       errmsg ("missing interface name or sw_if_index");
8095       return -99;
8096     }
8097
8098   /* Construct the API message */
8099   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
8100
8101   mp->sw_if_index = ntohl (sw_if_index);
8102   mp->max_interval = ntohl (max_interval);
8103   mp->min_interval = ntohl (min_interval);
8104   mp->lifetime = ntohl (lifetime);
8105   mp->initial_count = ntohl (initial_count);
8106   mp->initial_interval = ntohl (initial_interval);
8107   mp->suppress = suppress;
8108   mp->managed = managed;
8109   mp->other = other;
8110   mp->ll_option = ll_option;
8111   mp->send_unicast = send_unicast;
8112   mp->cease = cease;
8113   mp->is_no = is_no;
8114   mp->default_router = default_router;
8115
8116   /* send it... */
8117   S (mp);
8118
8119   /* Wait for a reply, return good/bad news  */
8120   W (ret);
8121   return ret;
8122 }
8123
8124 static int
8125 api_set_arp_neighbor_limit (vat_main_t * vam)
8126 {
8127   unformat_input_t *i = vam->input;
8128   vl_api_set_arp_neighbor_limit_t *mp;
8129   u32 arp_nbr_limit;
8130   u8 limit_set = 0;
8131   u8 is_ipv6 = 0;
8132   int ret;
8133
8134   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8135     {
8136       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
8137         limit_set = 1;
8138       else if (unformat (i, "ipv6"))
8139         is_ipv6 = 1;
8140       else
8141         {
8142           clib_warning ("parse error '%U'", format_unformat_error, i);
8143           return -99;
8144         }
8145     }
8146
8147   if (limit_set == 0)
8148     {
8149       errmsg ("missing limit value");
8150       return -99;
8151     }
8152
8153   M (SET_ARP_NEIGHBOR_LIMIT, mp);
8154
8155   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
8156   mp->is_ipv6 = is_ipv6;
8157
8158   S (mp);
8159   W (ret);
8160   return ret;
8161 }
8162
8163 static int
8164 api_l2_patch_add_del (vat_main_t * vam)
8165 {
8166   unformat_input_t *i = vam->input;
8167   vl_api_l2_patch_add_del_t *mp;
8168   u32 rx_sw_if_index;
8169   u8 rx_sw_if_index_set = 0;
8170   u32 tx_sw_if_index;
8171   u8 tx_sw_if_index_set = 0;
8172   u8 is_add = 1;
8173   int ret;
8174
8175   /* Parse args required to build the message */
8176   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8177     {
8178       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
8179         rx_sw_if_index_set = 1;
8180       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
8181         tx_sw_if_index_set = 1;
8182       else if (unformat (i, "rx"))
8183         {
8184           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8185             {
8186               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8187                             &rx_sw_if_index))
8188                 rx_sw_if_index_set = 1;
8189             }
8190           else
8191             break;
8192         }
8193       else if (unformat (i, "tx"))
8194         {
8195           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8196             {
8197               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8198                             &tx_sw_if_index))
8199                 tx_sw_if_index_set = 1;
8200             }
8201           else
8202             break;
8203         }
8204       else if (unformat (i, "del"))
8205         is_add = 0;
8206       else
8207         break;
8208     }
8209
8210   if (rx_sw_if_index_set == 0)
8211     {
8212       errmsg ("missing rx interface name or rx_sw_if_index");
8213       return -99;
8214     }
8215
8216   if (tx_sw_if_index_set == 0)
8217     {
8218       errmsg ("missing tx interface name or tx_sw_if_index");
8219       return -99;
8220     }
8221
8222   M (L2_PATCH_ADD_DEL, mp);
8223
8224   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
8225   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
8226   mp->is_add = is_add;
8227
8228   S (mp);
8229   W (ret);
8230   return ret;
8231 }
8232
8233 u8 is_del;
8234 u8 localsid_addr[16];
8235 u8 end_psp;
8236 u8 behavior;
8237 u32 sw_if_index;
8238 u32 vlan_index;
8239 u32 fib_table;
8240 u8 nh_addr[16];
8241
8242 static int
8243 api_sr_localsid_add_del (vat_main_t * vam)
8244 {
8245   unformat_input_t *i = vam->input;
8246   vl_api_sr_localsid_add_del_t *mp;
8247
8248   u8 is_del;
8249   ip6_address_t localsid;
8250   u8 end_psp = 0;
8251   u8 behavior = ~0;
8252   u32 sw_if_index;
8253   u32 fib_table = ~(u32) 0;
8254   ip6_address_t next_hop;
8255
8256   bool nexthop_set = 0;
8257
8258   int ret;
8259
8260   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8261     {
8262       if (unformat (i, "del"))
8263         is_del = 1;
8264       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
8265       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
8266         nexthop_set = 1;
8267       else if (unformat (i, "behavior %u", &behavior));
8268       else if (unformat (i, "sw_if_index %u", &sw_if_index));
8269       else if (unformat (i, "fib-table %u", &fib_table));
8270       else if (unformat (i, "end.psp %u", &behavior));
8271       else
8272         break;
8273     }
8274
8275   M (SR_LOCALSID_ADD_DEL, mp);
8276
8277   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
8278   if (nexthop_set)
8279     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
8280   mp->behavior = behavior;
8281   mp->sw_if_index = ntohl (sw_if_index);
8282   mp->fib_table = ntohl (fib_table);
8283   mp->end_psp = end_psp;
8284   mp->is_del = is_del;
8285
8286   S (mp);
8287   W (ret);
8288   return ret;
8289 }
8290
8291 static int
8292 api_ioam_enable (vat_main_t * vam)
8293 {
8294   unformat_input_t *input = vam->input;
8295   vl_api_ioam_enable_t *mp;
8296   u32 id = 0;
8297   int has_trace_option = 0;
8298   int has_pot_option = 0;
8299   int has_seqno_option = 0;
8300   int has_analyse_option = 0;
8301   int ret;
8302
8303   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8304     {
8305       if (unformat (input, "trace"))
8306         has_trace_option = 1;
8307       else if (unformat (input, "pot"))
8308         has_pot_option = 1;
8309       else if (unformat (input, "seqno"))
8310         has_seqno_option = 1;
8311       else if (unformat (input, "analyse"))
8312         has_analyse_option = 1;
8313       else
8314         break;
8315     }
8316   M (IOAM_ENABLE, mp);
8317   mp->id = htons (id);
8318   mp->seqno = has_seqno_option;
8319   mp->analyse = has_analyse_option;
8320   mp->pot_enable = has_pot_option;
8321   mp->trace_enable = has_trace_option;
8322
8323   S (mp);
8324   W (ret);
8325   return ret;
8326 }
8327
8328
8329 static int
8330 api_ioam_disable (vat_main_t * vam)
8331 {
8332   vl_api_ioam_disable_t *mp;
8333   int ret;
8334
8335   M (IOAM_DISABLE, mp);
8336   S (mp);
8337   W (ret);
8338   return ret;
8339 }
8340
8341 #define foreach_tcp_proto_field                 \
8342 _(src_port)                                     \
8343 _(dst_port)
8344
8345 #define foreach_udp_proto_field                 \
8346 _(src_port)                                     \
8347 _(dst_port)
8348
8349 #define foreach_ip4_proto_field                 \
8350 _(src_address)                                  \
8351 _(dst_address)                                  \
8352 _(tos)                                          \
8353 _(length)                                       \
8354 _(fragment_id)                                  \
8355 _(ttl)                                          \
8356 _(protocol)                                     \
8357 _(checksum)
8358
8359 typedef struct
8360 {
8361   u16 src_port, dst_port;
8362 } tcpudp_header_t;
8363
8364 #if VPP_API_TEST_BUILTIN == 0
8365 uword
8366 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8367 {
8368   u8 **maskp = va_arg (*args, u8 **);
8369   u8 *mask = 0;
8370   u8 found_something = 0;
8371   tcp_header_t *tcp;
8372
8373 #define _(a) u8 a=0;
8374   foreach_tcp_proto_field;
8375 #undef _
8376
8377   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8378     {
8379       if (0);
8380 #define _(a) else if (unformat (input, #a)) a=1;
8381       foreach_tcp_proto_field
8382 #undef _
8383         else
8384         break;
8385     }
8386
8387 #define _(a) found_something += a;
8388   foreach_tcp_proto_field;
8389 #undef _
8390
8391   if (found_something == 0)
8392     return 0;
8393
8394   vec_validate (mask, sizeof (*tcp) - 1);
8395
8396   tcp = (tcp_header_t *) mask;
8397
8398 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8399   foreach_tcp_proto_field;
8400 #undef _
8401
8402   *maskp = mask;
8403   return 1;
8404 }
8405
8406 uword
8407 unformat_udp_mask (unformat_input_t * input, va_list * args)
8408 {
8409   u8 **maskp = va_arg (*args, u8 **);
8410   u8 *mask = 0;
8411   u8 found_something = 0;
8412   udp_header_t *udp;
8413
8414 #define _(a) u8 a=0;
8415   foreach_udp_proto_field;
8416 #undef _
8417
8418   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8419     {
8420       if (0);
8421 #define _(a) else if (unformat (input, #a)) a=1;
8422       foreach_udp_proto_field
8423 #undef _
8424         else
8425         break;
8426     }
8427
8428 #define _(a) found_something += a;
8429   foreach_udp_proto_field;
8430 #undef _
8431
8432   if (found_something == 0)
8433     return 0;
8434
8435   vec_validate (mask, sizeof (*udp) - 1);
8436
8437   udp = (udp_header_t *) mask;
8438
8439 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8440   foreach_udp_proto_field;
8441 #undef _
8442
8443   *maskp = mask;
8444   return 1;
8445 }
8446
8447 uword
8448 unformat_l4_mask (unformat_input_t * input, va_list * args)
8449 {
8450   u8 **maskp = va_arg (*args, u8 **);
8451   u16 src_port = 0, dst_port = 0;
8452   tcpudp_header_t *tcpudp;
8453
8454   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8455     {
8456       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8457         return 1;
8458       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8459         return 1;
8460       else if (unformat (input, "src_port"))
8461         src_port = 0xFFFF;
8462       else if (unformat (input, "dst_port"))
8463         dst_port = 0xFFFF;
8464       else
8465         return 0;
8466     }
8467
8468   if (!src_port && !dst_port)
8469     return 0;
8470
8471   u8 *mask = 0;
8472   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8473
8474   tcpudp = (tcpudp_header_t *) mask;
8475   tcpudp->src_port = src_port;
8476   tcpudp->dst_port = dst_port;
8477
8478   *maskp = mask;
8479
8480   return 1;
8481 }
8482
8483 uword
8484 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8485 {
8486   u8 **maskp = va_arg (*args, u8 **);
8487   u8 *mask = 0;
8488   u8 found_something = 0;
8489   ip4_header_t *ip;
8490
8491 #define _(a) u8 a=0;
8492   foreach_ip4_proto_field;
8493 #undef _
8494   u8 version = 0;
8495   u8 hdr_length = 0;
8496
8497
8498   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8499     {
8500       if (unformat (input, "version"))
8501         version = 1;
8502       else if (unformat (input, "hdr_length"))
8503         hdr_length = 1;
8504       else if (unformat (input, "src"))
8505         src_address = 1;
8506       else if (unformat (input, "dst"))
8507         dst_address = 1;
8508       else if (unformat (input, "proto"))
8509         protocol = 1;
8510
8511 #define _(a) else if (unformat (input, #a)) a=1;
8512       foreach_ip4_proto_field
8513 #undef _
8514         else
8515         break;
8516     }
8517
8518 #define _(a) found_something += a;
8519   foreach_ip4_proto_field;
8520 #undef _
8521
8522   if (found_something == 0)
8523     return 0;
8524
8525   vec_validate (mask, sizeof (*ip) - 1);
8526
8527   ip = (ip4_header_t *) mask;
8528
8529 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8530   foreach_ip4_proto_field;
8531 #undef _
8532
8533   ip->ip_version_and_header_length = 0;
8534
8535   if (version)
8536     ip->ip_version_and_header_length |= 0xF0;
8537
8538   if (hdr_length)
8539     ip->ip_version_and_header_length |= 0x0F;
8540
8541   *maskp = mask;
8542   return 1;
8543 }
8544
8545 #define foreach_ip6_proto_field                 \
8546 _(src_address)                                  \
8547 _(dst_address)                                  \
8548 _(payload_length)                               \
8549 _(hop_limit)                                    \
8550 _(protocol)
8551
8552 uword
8553 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8554 {
8555   u8 **maskp = va_arg (*args, u8 **);
8556   u8 *mask = 0;
8557   u8 found_something = 0;
8558   ip6_header_t *ip;
8559   u32 ip_version_traffic_class_and_flow_label;
8560
8561 #define _(a) u8 a=0;
8562   foreach_ip6_proto_field;
8563 #undef _
8564   u8 version = 0;
8565   u8 traffic_class = 0;
8566   u8 flow_label = 0;
8567
8568   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8569     {
8570       if (unformat (input, "version"))
8571         version = 1;
8572       else if (unformat (input, "traffic-class"))
8573         traffic_class = 1;
8574       else if (unformat (input, "flow-label"))
8575         flow_label = 1;
8576       else if (unformat (input, "src"))
8577         src_address = 1;
8578       else if (unformat (input, "dst"))
8579         dst_address = 1;
8580       else if (unformat (input, "proto"))
8581         protocol = 1;
8582
8583 #define _(a) else if (unformat (input, #a)) a=1;
8584       foreach_ip6_proto_field
8585 #undef _
8586         else
8587         break;
8588     }
8589
8590 #define _(a) found_something += a;
8591   foreach_ip6_proto_field;
8592 #undef _
8593
8594   if (found_something == 0)
8595     return 0;
8596
8597   vec_validate (mask, sizeof (*ip) - 1);
8598
8599   ip = (ip6_header_t *) mask;
8600
8601 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8602   foreach_ip6_proto_field;
8603 #undef _
8604
8605   ip_version_traffic_class_and_flow_label = 0;
8606
8607   if (version)
8608     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8609
8610   if (traffic_class)
8611     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8612
8613   if (flow_label)
8614     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8615
8616   ip->ip_version_traffic_class_and_flow_label =
8617     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8618
8619   *maskp = mask;
8620   return 1;
8621 }
8622
8623 uword
8624 unformat_l3_mask (unformat_input_t * input, va_list * args)
8625 {
8626   u8 **maskp = va_arg (*args, u8 **);
8627
8628   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8629     {
8630       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8631         return 1;
8632       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8633         return 1;
8634       else
8635         break;
8636     }
8637   return 0;
8638 }
8639
8640 uword
8641 unformat_l2_mask (unformat_input_t * input, va_list * args)
8642 {
8643   u8 **maskp = va_arg (*args, u8 **);
8644   u8 *mask = 0;
8645   u8 src = 0;
8646   u8 dst = 0;
8647   u8 proto = 0;
8648   u8 tag1 = 0;
8649   u8 tag2 = 0;
8650   u8 ignore_tag1 = 0;
8651   u8 ignore_tag2 = 0;
8652   u8 cos1 = 0;
8653   u8 cos2 = 0;
8654   u8 dot1q = 0;
8655   u8 dot1ad = 0;
8656   int len = 14;
8657
8658   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8659     {
8660       if (unformat (input, "src"))
8661         src = 1;
8662       else if (unformat (input, "dst"))
8663         dst = 1;
8664       else if (unformat (input, "proto"))
8665         proto = 1;
8666       else if (unformat (input, "tag1"))
8667         tag1 = 1;
8668       else if (unformat (input, "tag2"))
8669         tag2 = 1;
8670       else if (unformat (input, "ignore-tag1"))
8671         ignore_tag1 = 1;
8672       else if (unformat (input, "ignore-tag2"))
8673         ignore_tag2 = 1;
8674       else if (unformat (input, "cos1"))
8675         cos1 = 1;
8676       else if (unformat (input, "cos2"))
8677         cos2 = 1;
8678       else if (unformat (input, "dot1q"))
8679         dot1q = 1;
8680       else if (unformat (input, "dot1ad"))
8681         dot1ad = 1;
8682       else
8683         break;
8684     }
8685   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8686        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8687     return 0;
8688
8689   if (tag1 || ignore_tag1 || cos1 || dot1q)
8690     len = 18;
8691   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8692     len = 22;
8693
8694   vec_validate (mask, len - 1);
8695
8696   if (dst)
8697     memset (mask, 0xff, 6);
8698
8699   if (src)
8700     memset (mask + 6, 0xff, 6);
8701
8702   if (tag2 || dot1ad)
8703     {
8704       /* inner vlan tag */
8705       if (tag2)
8706         {
8707           mask[19] = 0xff;
8708           mask[18] = 0x0f;
8709         }
8710       if (cos2)
8711         mask[18] |= 0xe0;
8712       if (proto)
8713         mask[21] = mask[20] = 0xff;
8714       if (tag1)
8715         {
8716           mask[15] = 0xff;
8717           mask[14] = 0x0f;
8718         }
8719       if (cos1)
8720         mask[14] |= 0xe0;
8721       *maskp = mask;
8722       return 1;
8723     }
8724   if (tag1 | dot1q)
8725     {
8726       if (tag1)
8727         {
8728           mask[15] = 0xff;
8729           mask[14] = 0x0f;
8730         }
8731       if (cos1)
8732         mask[14] |= 0xe0;
8733       if (proto)
8734         mask[16] = mask[17] = 0xff;
8735
8736       *maskp = mask;
8737       return 1;
8738     }
8739   if (cos2)
8740     mask[18] |= 0xe0;
8741   if (cos1)
8742     mask[14] |= 0xe0;
8743   if (proto)
8744     mask[12] = mask[13] = 0xff;
8745
8746   *maskp = mask;
8747   return 1;
8748 }
8749
8750 uword
8751 unformat_classify_mask (unformat_input_t * input, va_list * args)
8752 {
8753   u8 **maskp = va_arg (*args, u8 **);
8754   u32 *skipp = va_arg (*args, u32 *);
8755   u32 *matchp = va_arg (*args, u32 *);
8756   u32 match;
8757   u8 *mask = 0;
8758   u8 *l2 = 0;
8759   u8 *l3 = 0;
8760   u8 *l4 = 0;
8761   int i;
8762
8763   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8764     {
8765       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8766         ;
8767       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8768         ;
8769       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8770         ;
8771       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8772         ;
8773       else
8774         break;
8775     }
8776
8777   if (l4 && !l3)
8778     {
8779       vec_free (mask);
8780       vec_free (l2);
8781       vec_free (l4);
8782       return 0;
8783     }
8784
8785   if (mask || l2 || l3 || l4)
8786     {
8787       if (l2 || l3 || l4)
8788         {
8789           /* "With a free Ethernet header in every package" */
8790           if (l2 == 0)
8791             vec_validate (l2, 13);
8792           mask = l2;
8793           if (vec_len (l3))
8794             {
8795               vec_append (mask, l3);
8796               vec_free (l3);
8797             }
8798           if (vec_len (l4))
8799             {
8800               vec_append (mask, l4);
8801               vec_free (l4);
8802             }
8803         }
8804
8805       /* Scan forward looking for the first significant mask octet */
8806       for (i = 0; i < vec_len (mask); i++)
8807         if (mask[i])
8808           break;
8809
8810       /* compute (skip, match) params */
8811       *skipp = i / sizeof (u32x4);
8812       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8813
8814       /* Pad mask to an even multiple of the vector size */
8815       while (vec_len (mask) % sizeof (u32x4))
8816         vec_add1 (mask, 0);
8817
8818       match = vec_len (mask) / sizeof (u32x4);
8819
8820       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8821         {
8822           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8823           if (*tmp || *(tmp + 1))
8824             break;
8825           match--;
8826         }
8827       if (match == 0)
8828         clib_warning ("BUG: match 0");
8829
8830       _vec_len (mask) = match * sizeof (u32x4);
8831
8832       *matchp = match;
8833       *maskp = mask;
8834
8835       return 1;
8836     }
8837
8838   return 0;
8839 }
8840 #endif /* VPP_API_TEST_BUILTIN */
8841
8842 #define foreach_l2_next                         \
8843 _(drop, DROP)                                   \
8844 _(ethernet, ETHERNET_INPUT)                     \
8845 _(ip4, IP4_INPUT)                               \
8846 _(ip6, IP6_INPUT)
8847
8848 uword
8849 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8850 {
8851   u32 *miss_next_indexp = va_arg (*args, u32 *);
8852   u32 next_index = 0;
8853   u32 tmp;
8854
8855 #define _(n,N) \
8856   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8857   foreach_l2_next;
8858 #undef _
8859
8860   if (unformat (input, "%d", &tmp))
8861     {
8862       next_index = tmp;
8863       goto out;
8864     }
8865
8866   return 0;
8867
8868 out:
8869   *miss_next_indexp = next_index;
8870   return 1;
8871 }
8872
8873 #define foreach_ip_next                         \
8874 _(drop, DROP)                                   \
8875 _(local, LOCAL)                                 \
8876 _(rewrite, REWRITE)
8877
8878 uword
8879 api_unformat_ip_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 = IP_LOOKUP_NEXT_##N; goto out;}
8887   foreach_ip_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_acl_next                        \
8904 _(deny, DENY)
8905
8906 uword
8907 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
8908 {
8909   u32 *miss_next_indexp = va_arg (*args, u32 *);
8910   u32 next_index = 0;
8911   u32 tmp;
8912
8913 #define _(n,N) \
8914   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8915   foreach_acl_next;
8916 #undef _
8917
8918   if (unformat (input, "permit"))
8919     {
8920       next_index = ~0;
8921       goto out;
8922     }
8923   else if (unformat (input, "%d", &tmp))
8924     {
8925       next_index = tmp;
8926       goto out;
8927     }
8928
8929   return 0;
8930
8931 out:
8932   *miss_next_indexp = next_index;
8933   return 1;
8934 }
8935
8936 uword
8937 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8938 {
8939   u32 *r = va_arg (*args, u32 *);
8940
8941   if (unformat (input, "conform-color"))
8942     *r = POLICE_CONFORM;
8943   else if (unformat (input, "exceed-color"))
8944     *r = POLICE_EXCEED;
8945   else
8946     return 0;
8947
8948   return 1;
8949 }
8950
8951 static int
8952 api_classify_add_del_table (vat_main_t * vam)
8953 {
8954   unformat_input_t *i = vam->input;
8955   vl_api_classify_add_del_table_t *mp;
8956
8957   u32 nbuckets = 2;
8958   u32 skip = ~0;
8959   u32 match = ~0;
8960   int is_add = 1;
8961   int del_chain = 0;
8962   u32 table_index = ~0;
8963   u32 next_table_index = ~0;
8964   u32 miss_next_index = ~0;
8965   u32 memory_size = 32 << 20;
8966   u8 *mask = 0;
8967   u32 current_data_flag = 0;
8968   int current_data_offset = 0;
8969   int ret;
8970
8971   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8972     {
8973       if (unformat (i, "del"))
8974         is_add = 0;
8975       else if (unformat (i, "del-chain"))
8976         {
8977           is_add = 0;
8978           del_chain = 1;
8979         }
8980       else if (unformat (i, "buckets %d", &nbuckets))
8981         ;
8982       else if (unformat (i, "memory_size %d", &memory_size))
8983         ;
8984       else if (unformat (i, "skip %d", &skip))
8985         ;
8986       else if (unformat (i, "match %d", &match))
8987         ;
8988       else if (unformat (i, "table %d", &table_index))
8989         ;
8990       else if (unformat (i, "mask %U", unformat_classify_mask,
8991                          &mask, &skip, &match))
8992         ;
8993       else if (unformat (i, "next-table %d", &next_table_index))
8994         ;
8995       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
8996                          &miss_next_index))
8997         ;
8998       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8999                          &miss_next_index))
9000         ;
9001       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
9002                          &miss_next_index))
9003         ;
9004       else if (unformat (i, "current-data-flag %d", &current_data_flag))
9005         ;
9006       else if (unformat (i, "current-data-offset %d", &current_data_offset))
9007         ;
9008       else
9009         break;
9010     }
9011
9012   if (is_add && mask == 0)
9013     {
9014       errmsg ("Mask required");
9015       return -99;
9016     }
9017
9018   if (is_add && skip == ~0)
9019     {
9020       errmsg ("skip count required");
9021       return -99;
9022     }
9023
9024   if (is_add && match == ~0)
9025     {
9026       errmsg ("match count required");
9027       return -99;
9028     }
9029
9030   if (!is_add && table_index == ~0)
9031     {
9032       errmsg ("table index required for delete");
9033       return -99;
9034     }
9035
9036   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
9037
9038   mp->is_add = is_add;
9039   mp->del_chain = del_chain;
9040   mp->table_index = ntohl (table_index);
9041   mp->nbuckets = ntohl (nbuckets);
9042   mp->memory_size = ntohl (memory_size);
9043   mp->skip_n_vectors = ntohl (skip);
9044   mp->match_n_vectors = ntohl (match);
9045   mp->next_table_index = ntohl (next_table_index);
9046   mp->miss_next_index = ntohl (miss_next_index);
9047   mp->current_data_flag = ntohl (current_data_flag);
9048   mp->current_data_offset = ntohl (current_data_offset);
9049   clib_memcpy (mp->mask, mask, vec_len (mask));
9050
9051   vec_free (mask);
9052
9053   S (mp);
9054   W (ret);
9055   return ret;
9056 }
9057
9058 #if VPP_API_TEST_BUILTIN == 0
9059 uword
9060 unformat_l4_match (unformat_input_t * input, va_list * args)
9061 {
9062   u8 **matchp = va_arg (*args, u8 **);
9063
9064   u8 *proto_header = 0;
9065   int src_port = 0;
9066   int dst_port = 0;
9067
9068   tcpudp_header_t h;
9069
9070   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9071     {
9072       if (unformat (input, "src_port %d", &src_port))
9073         ;
9074       else if (unformat (input, "dst_port %d", &dst_port))
9075         ;
9076       else
9077         return 0;
9078     }
9079
9080   h.src_port = clib_host_to_net_u16 (src_port);
9081   h.dst_port = clib_host_to_net_u16 (dst_port);
9082   vec_validate (proto_header, sizeof (h) - 1);
9083   memcpy (proto_header, &h, sizeof (h));
9084
9085   *matchp = proto_header;
9086
9087   return 1;
9088 }
9089
9090 uword
9091 unformat_ip4_match (unformat_input_t * input, va_list * args)
9092 {
9093   u8 **matchp = va_arg (*args, u8 **);
9094   u8 *match = 0;
9095   ip4_header_t *ip;
9096   int version = 0;
9097   u32 version_val;
9098   int hdr_length = 0;
9099   u32 hdr_length_val;
9100   int src = 0, dst = 0;
9101   ip4_address_t src_val, dst_val;
9102   int proto = 0;
9103   u32 proto_val;
9104   int tos = 0;
9105   u32 tos_val;
9106   int length = 0;
9107   u32 length_val;
9108   int fragment_id = 0;
9109   u32 fragment_id_val;
9110   int ttl = 0;
9111   int ttl_val;
9112   int checksum = 0;
9113   u32 checksum_val;
9114
9115   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9116     {
9117       if (unformat (input, "version %d", &version_val))
9118         version = 1;
9119       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9120         hdr_length = 1;
9121       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9122         src = 1;
9123       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9124         dst = 1;
9125       else if (unformat (input, "proto %d", &proto_val))
9126         proto = 1;
9127       else if (unformat (input, "tos %d", &tos_val))
9128         tos = 1;
9129       else if (unformat (input, "length %d", &length_val))
9130         length = 1;
9131       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9132         fragment_id = 1;
9133       else if (unformat (input, "ttl %d", &ttl_val))
9134         ttl = 1;
9135       else if (unformat (input, "checksum %d", &checksum_val))
9136         checksum = 1;
9137       else
9138         break;
9139     }
9140
9141   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9142       + ttl + checksum == 0)
9143     return 0;
9144
9145   /*
9146    * Aligned because we use the real comparison functions
9147    */
9148   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9149
9150   ip = (ip4_header_t *) match;
9151
9152   /* These are realistically matched in practice */
9153   if (src)
9154     ip->src_address.as_u32 = src_val.as_u32;
9155
9156   if (dst)
9157     ip->dst_address.as_u32 = dst_val.as_u32;
9158
9159   if (proto)
9160     ip->protocol = proto_val;
9161
9162
9163   /* These are not, but they're included for completeness */
9164   if (version)
9165     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9166
9167   if (hdr_length)
9168     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9169
9170   if (tos)
9171     ip->tos = tos_val;
9172
9173   if (length)
9174     ip->length = clib_host_to_net_u16 (length_val);
9175
9176   if (ttl)
9177     ip->ttl = ttl_val;
9178
9179   if (checksum)
9180     ip->checksum = clib_host_to_net_u16 (checksum_val);
9181
9182   *matchp = match;
9183   return 1;
9184 }
9185
9186 uword
9187 unformat_ip6_match (unformat_input_t * input, va_list * args)
9188 {
9189   u8 **matchp = va_arg (*args, u8 **);
9190   u8 *match = 0;
9191   ip6_header_t *ip;
9192   int version = 0;
9193   u32 version_val;
9194   u8 traffic_class = 0;
9195   u32 traffic_class_val = 0;
9196   u8 flow_label = 0;
9197   u8 flow_label_val;
9198   int src = 0, dst = 0;
9199   ip6_address_t src_val, dst_val;
9200   int proto = 0;
9201   u32 proto_val;
9202   int payload_length = 0;
9203   u32 payload_length_val;
9204   int hop_limit = 0;
9205   int hop_limit_val;
9206   u32 ip_version_traffic_class_and_flow_label;
9207
9208   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9209     {
9210       if (unformat (input, "version %d", &version_val))
9211         version = 1;
9212       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9213         traffic_class = 1;
9214       else if (unformat (input, "flow_label %d", &flow_label_val))
9215         flow_label = 1;
9216       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9217         src = 1;
9218       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9219         dst = 1;
9220       else if (unformat (input, "proto %d", &proto_val))
9221         proto = 1;
9222       else if (unformat (input, "payload_length %d", &payload_length_val))
9223         payload_length = 1;
9224       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9225         hop_limit = 1;
9226       else
9227         break;
9228     }
9229
9230   if (version + traffic_class + flow_label + src + dst + proto +
9231       payload_length + hop_limit == 0)
9232     return 0;
9233
9234   /*
9235    * Aligned because we use the real comparison functions
9236    */
9237   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9238
9239   ip = (ip6_header_t *) match;
9240
9241   if (src)
9242     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9243
9244   if (dst)
9245     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9246
9247   if (proto)
9248     ip->protocol = proto_val;
9249
9250   ip_version_traffic_class_and_flow_label = 0;
9251
9252   if (version)
9253     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9254
9255   if (traffic_class)
9256     ip_version_traffic_class_and_flow_label |=
9257       (traffic_class_val & 0xFF) << 20;
9258
9259   if (flow_label)
9260     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9261
9262   ip->ip_version_traffic_class_and_flow_label =
9263     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9264
9265   if (payload_length)
9266     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9267
9268   if (hop_limit)
9269     ip->hop_limit = hop_limit_val;
9270
9271   *matchp = match;
9272   return 1;
9273 }
9274
9275 uword
9276 unformat_l3_match (unformat_input_t * input, va_list * args)
9277 {
9278   u8 **matchp = va_arg (*args, u8 **);
9279
9280   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9281     {
9282       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9283         return 1;
9284       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9285         return 1;
9286       else
9287         break;
9288     }
9289   return 0;
9290 }
9291
9292 uword
9293 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9294 {
9295   u8 *tagp = va_arg (*args, u8 *);
9296   u32 tag;
9297
9298   if (unformat (input, "%d", &tag))
9299     {
9300       tagp[0] = (tag >> 8) & 0x0F;
9301       tagp[1] = tag & 0xFF;
9302       return 1;
9303     }
9304
9305   return 0;
9306 }
9307
9308 uword
9309 unformat_l2_match (unformat_input_t * input, va_list * args)
9310 {
9311   u8 **matchp = va_arg (*args, u8 **);
9312   u8 *match = 0;
9313   u8 src = 0;
9314   u8 src_val[6];
9315   u8 dst = 0;
9316   u8 dst_val[6];
9317   u8 proto = 0;
9318   u16 proto_val;
9319   u8 tag1 = 0;
9320   u8 tag1_val[2];
9321   u8 tag2 = 0;
9322   u8 tag2_val[2];
9323   int len = 14;
9324   u8 ignore_tag1 = 0;
9325   u8 ignore_tag2 = 0;
9326   u8 cos1 = 0;
9327   u8 cos2 = 0;
9328   u32 cos1_val = 0;
9329   u32 cos2_val = 0;
9330
9331   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9332     {
9333       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9334         src = 1;
9335       else
9336         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9337         dst = 1;
9338       else if (unformat (input, "proto %U",
9339                          unformat_ethernet_type_host_byte_order, &proto_val))
9340         proto = 1;
9341       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9342         tag1 = 1;
9343       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9344         tag2 = 1;
9345       else if (unformat (input, "ignore-tag1"))
9346         ignore_tag1 = 1;
9347       else if (unformat (input, "ignore-tag2"))
9348         ignore_tag2 = 1;
9349       else if (unformat (input, "cos1 %d", &cos1_val))
9350         cos1 = 1;
9351       else if (unformat (input, "cos2 %d", &cos2_val))
9352         cos2 = 1;
9353       else
9354         break;
9355     }
9356   if ((src + dst + proto + tag1 + tag2 +
9357        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9358     return 0;
9359
9360   if (tag1 || ignore_tag1 || cos1)
9361     len = 18;
9362   if (tag2 || ignore_tag2 || cos2)
9363     len = 22;
9364
9365   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9366
9367   if (dst)
9368     clib_memcpy (match, dst_val, 6);
9369
9370   if (src)
9371     clib_memcpy (match + 6, src_val, 6);
9372
9373   if (tag2)
9374     {
9375       /* inner vlan tag */
9376       match[19] = tag2_val[1];
9377       match[18] = tag2_val[0];
9378       if (cos2)
9379         match[18] |= (cos2_val & 0x7) << 5;
9380       if (proto)
9381         {
9382           match[21] = proto_val & 0xff;
9383           match[20] = proto_val >> 8;
9384         }
9385       if (tag1)
9386         {
9387           match[15] = tag1_val[1];
9388           match[14] = tag1_val[0];
9389         }
9390       if (cos1)
9391         match[14] |= (cos1_val & 0x7) << 5;
9392       *matchp = match;
9393       return 1;
9394     }
9395   if (tag1)
9396     {
9397       match[15] = tag1_val[1];
9398       match[14] = tag1_val[0];
9399       if (proto)
9400         {
9401           match[17] = proto_val & 0xff;
9402           match[16] = proto_val >> 8;
9403         }
9404       if (cos1)
9405         match[14] |= (cos1_val & 0x7) << 5;
9406
9407       *matchp = match;
9408       return 1;
9409     }
9410   if (cos2)
9411     match[18] |= (cos2_val & 0x7) << 5;
9412   if (cos1)
9413     match[14] |= (cos1_val & 0x7) << 5;
9414   if (proto)
9415     {
9416       match[13] = proto_val & 0xff;
9417       match[12] = proto_val >> 8;
9418     }
9419
9420   *matchp = match;
9421   return 1;
9422 }
9423 #endif
9424
9425 uword
9426 api_unformat_classify_match (unformat_input_t * input, va_list * args)
9427 {
9428   u8 **matchp = va_arg (*args, u8 **);
9429   u32 skip_n_vectors = va_arg (*args, u32);
9430   u32 match_n_vectors = va_arg (*args, u32);
9431
9432   u8 *match = 0;
9433   u8 *l2 = 0;
9434   u8 *l3 = 0;
9435   u8 *l4 = 0;
9436
9437   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9438     {
9439       if (unformat (input, "hex %U", unformat_hex_string, &match))
9440         ;
9441       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9442         ;
9443       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9444         ;
9445       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9446         ;
9447       else
9448         break;
9449     }
9450
9451   if (l4 && !l3)
9452     {
9453       vec_free (match);
9454       vec_free (l2);
9455       vec_free (l4);
9456       return 0;
9457     }
9458
9459   if (match || l2 || l3 || l4)
9460     {
9461       if (l2 || l3 || l4)
9462         {
9463           /* "Win a free Ethernet header in every packet" */
9464           if (l2 == 0)
9465             vec_validate_aligned (l2, 13, sizeof (u32x4));
9466           match = l2;
9467           if (vec_len (l3))
9468             {
9469               vec_append_aligned (match, l3, sizeof (u32x4));
9470               vec_free (l3);
9471             }
9472           if (vec_len (l4))
9473             {
9474               vec_append_aligned (match, l4, sizeof (u32x4));
9475               vec_free (l4);
9476             }
9477         }
9478
9479       /* Make sure the vector is big enough even if key is all 0's */
9480       vec_validate_aligned
9481         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9482          sizeof (u32x4));
9483
9484       /* Set size, include skipped vectors */
9485       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9486
9487       *matchp = match;
9488
9489       return 1;
9490     }
9491
9492   return 0;
9493 }
9494
9495 static int
9496 api_classify_add_del_session (vat_main_t * vam)
9497 {
9498   unformat_input_t *i = vam->input;
9499   vl_api_classify_add_del_session_t *mp;
9500   int is_add = 1;
9501   u32 table_index = ~0;
9502   u32 hit_next_index = ~0;
9503   u32 opaque_index = ~0;
9504   u8 *match = 0;
9505   i32 advance = 0;
9506   u32 skip_n_vectors = 0;
9507   u32 match_n_vectors = 0;
9508   u32 action = 0;
9509   u32 metadata = 0;
9510   int ret;
9511
9512   /*
9513    * Warning: you have to supply skip_n and match_n
9514    * because the API client cant simply look at the classify
9515    * table object.
9516    */
9517
9518   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9519     {
9520       if (unformat (i, "del"))
9521         is_add = 0;
9522       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
9523                          &hit_next_index))
9524         ;
9525       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9526                          &hit_next_index))
9527         ;
9528       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
9529                          &hit_next_index))
9530         ;
9531       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9532         ;
9533       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9534         ;
9535       else if (unformat (i, "opaque-index %d", &opaque_index))
9536         ;
9537       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9538         ;
9539       else if (unformat (i, "match_n %d", &match_n_vectors))
9540         ;
9541       else if (unformat (i, "match %U", api_unformat_classify_match,
9542                          &match, skip_n_vectors, match_n_vectors))
9543         ;
9544       else if (unformat (i, "advance %d", &advance))
9545         ;
9546       else if (unformat (i, "table-index %d", &table_index))
9547         ;
9548       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9549         action = 1;
9550       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9551         action = 2;
9552       else if (unformat (i, "action %d", &action))
9553         ;
9554       else if (unformat (i, "metadata %d", &metadata))
9555         ;
9556       else
9557         break;
9558     }
9559
9560   if (table_index == ~0)
9561     {
9562       errmsg ("Table index required");
9563       return -99;
9564     }
9565
9566   if (is_add && match == 0)
9567     {
9568       errmsg ("Match value required");
9569       return -99;
9570     }
9571
9572   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
9573
9574   mp->is_add = is_add;
9575   mp->table_index = ntohl (table_index);
9576   mp->hit_next_index = ntohl (hit_next_index);
9577   mp->opaque_index = ntohl (opaque_index);
9578   mp->advance = ntohl (advance);
9579   mp->action = action;
9580   mp->metadata = ntohl (metadata);
9581   clib_memcpy (mp->match, match, vec_len (match));
9582   vec_free (match);
9583
9584   S (mp);
9585   W (ret);
9586   return ret;
9587 }
9588
9589 static int
9590 api_classify_set_interface_ip_table (vat_main_t * vam)
9591 {
9592   unformat_input_t *i = vam->input;
9593   vl_api_classify_set_interface_ip_table_t *mp;
9594   u32 sw_if_index;
9595   int sw_if_index_set;
9596   u32 table_index = ~0;
9597   u8 is_ipv6 = 0;
9598   int ret;
9599
9600   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9601     {
9602       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9603         sw_if_index_set = 1;
9604       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9605         sw_if_index_set = 1;
9606       else if (unformat (i, "table %d", &table_index))
9607         ;
9608       else
9609         {
9610           clib_warning ("parse error '%U'", format_unformat_error, i);
9611           return -99;
9612         }
9613     }
9614
9615   if (sw_if_index_set == 0)
9616     {
9617       errmsg ("missing interface name or sw_if_index");
9618       return -99;
9619     }
9620
9621
9622   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
9623
9624   mp->sw_if_index = ntohl (sw_if_index);
9625   mp->table_index = ntohl (table_index);
9626   mp->is_ipv6 = is_ipv6;
9627
9628   S (mp);
9629   W (ret);
9630   return ret;
9631 }
9632
9633 static int
9634 api_classify_set_interface_l2_tables (vat_main_t * vam)
9635 {
9636   unformat_input_t *i = vam->input;
9637   vl_api_classify_set_interface_l2_tables_t *mp;
9638   u32 sw_if_index;
9639   int sw_if_index_set;
9640   u32 ip4_table_index = ~0;
9641   u32 ip6_table_index = ~0;
9642   u32 other_table_index = ~0;
9643   u32 is_input = 1;
9644   int ret;
9645
9646   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9647     {
9648       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9649         sw_if_index_set = 1;
9650       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9651         sw_if_index_set = 1;
9652       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9653         ;
9654       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9655         ;
9656       else if (unformat (i, "other-table %d", &other_table_index))
9657         ;
9658       else if (unformat (i, "is-input %d", &is_input))
9659         ;
9660       else
9661         {
9662           clib_warning ("parse error '%U'", format_unformat_error, i);
9663           return -99;
9664         }
9665     }
9666
9667   if (sw_if_index_set == 0)
9668     {
9669       errmsg ("missing interface name or sw_if_index");
9670       return -99;
9671     }
9672
9673
9674   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
9675
9676   mp->sw_if_index = ntohl (sw_if_index);
9677   mp->ip4_table_index = ntohl (ip4_table_index);
9678   mp->ip6_table_index = ntohl (ip6_table_index);
9679   mp->other_table_index = ntohl (other_table_index);
9680   mp->is_input = (u8) is_input;
9681
9682   S (mp);
9683   W (ret);
9684   return ret;
9685 }
9686
9687 static int
9688 api_set_ipfix_exporter (vat_main_t * vam)
9689 {
9690   unformat_input_t *i = vam->input;
9691   vl_api_set_ipfix_exporter_t *mp;
9692   ip4_address_t collector_address;
9693   u8 collector_address_set = 0;
9694   u32 collector_port = ~0;
9695   ip4_address_t src_address;
9696   u8 src_address_set = 0;
9697   u32 vrf_id = ~0;
9698   u32 path_mtu = ~0;
9699   u32 template_interval = ~0;
9700   u8 udp_checksum = 0;
9701   int ret;
9702
9703   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9704     {
9705       if (unformat (i, "collector_address %U", unformat_ip4_address,
9706                     &collector_address))
9707         collector_address_set = 1;
9708       else if (unformat (i, "collector_port %d", &collector_port))
9709         ;
9710       else if (unformat (i, "src_address %U", unformat_ip4_address,
9711                          &src_address))
9712         src_address_set = 1;
9713       else if (unformat (i, "vrf_id %d", &vrf_id))
9714         ;
9715       else if (unformat (i, "path_mtu %d", &path_mtu))
9716         ;
9717       else if (unformat (i, "template_interval %d", &template_interval))
9718         ;
9719       else if (unformat (i, "udp_checksum"))
9720         udp_checksum = 1;
9721       else
9722         break;
9723     }
9724
9725   if (collector_address_set == 0)
9726     {
9727       errmsg ("collector_address required");
9728       return -99;
9729     }
9730
9731   if (src_address_set == 0)
9732     {
9733       errmsg ("src_address required");
9734       return -99;
9735     }
9736
9737   M (SET_IPFIX_EXPORTER, mp);
9738
9739   memcpy (mp->collector_address, collector_address.data,
9740           sizeof (collector_address.data));
9741   mp->collector_port = htons ((u16) collector_port);
9742   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9743   mp->vrf_id = htonl (vrf_id);
9744   mp->path_mtu = htonl (path_mtu);
9745   mp->template_interval = htonl (template_interval);
9746   mp->udp_checksum = udp_checksum;
9747
9748   S (mp);
9749   W (ret);
9750   return ret;
9751 }
9752
9753 static int
9754 api_set_ipfix_classify_stream (vat_main_t * vam)
9755 {
9756   unformat_input_t *i = vam->input;
9757   vl_api_set_ipfix_classify_stream_t *mp;
9758   u32 domain_id = 0;
9759   u32 src_port = UDP_DST_PORT_ipfix;
9760   int ret;
9761
9762   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9763     {
9764       if (unformat (i, "domain %d", &domain_id))
9765         ;
9766       else if (unformat (i, "src_port %d", &src_port))
9767         ;
9768       else
9769         {
9770           errmsg ("unknown input `%U'", format_unformat_error, i);
9771           return -99;
9772         }
9773     }
9774
9775   M (SET_IPFIX_CLASSIFY_STREAM, mp);
9776
9777   mp->domain_id = htonl (domain_id);
9778   mp->src_port = htons ((u16) src_port);
9779
9780   S (mp);
9781   W (ret);
9782   return ret;
9783 }
9784
9785 static int
9786 api_ipfix_classify_table_add_del (vat_main_t * vam)
9787 {
9788   unformat_input_t *i = vam->input;
9789   vl_api_ipfix_classify_table_add_del_t *mp;
9790   int is_add = -1;
9791   u32 classify_table_index = ~0;
9792   u8 ip_version = 0;
9793   u8 transport_protocol = 255;
9794   int ret;
9795
9796   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9797     {
9798       if (unformat (i, "add"))
9799         is_add = 1;
9800       else if (unformat (i, "del"))
9801         is_add = 0;
9802       else if (unformat (i, "table %d", &classify_table_index))
9803         ;
9804       else if (unformat (i, "ip4"))
9805         ip_version = 4;
9806       else if (unformat (i, "ip6"))
9807         ip_version = 6;
9808       else if (unformat (i, "tcp"))
9809         transport_protocol = 6;
9810       else if (unformat (i, "udp"))
9811         transport_protocol = 17;
9812       else
9813         {
9814           errmsg ("unknown input `%U'", format_unformat_error, i);
9815           return -99;
9816         }
9817     }
9818
9819   if (is_add == -1)
9820     {
9821       errmsg ("expecting: add|del");
9822       return -99;
9823     }
9824   if (classify_table_index == ~0)
9825     {
9826       errmsg ("classifier table not specified");
9827       return -99;
9828     }
9829   if (ip_version == 0)
9830     {
9831       errmsg ("IP version not specified");
9832       return -99;
9833     }
9834
9835   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
9836
9837   mp->is_add = is_add;
9838   mp->table_id = htonl (classify_table_index);
9839   mp->ip_version = ip_version;
9840   mp->transport_protocol = transport_protocol;
9841
9842   S (mp);
9843   W (ret);
9844   return ret;
9845 }
9846
9847 static int
9848 api_get_node_index (vat_main_t * vam)
9849 {
9850   unformat_input_t *i = vam->input;
9851   vl_api_get_node_index_t *mp;
9852   u8 *name = 0;
9853   int ret;
9854
9855   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9856     {
9857       if (unformat (i, "node %s", &name))
9858         ;
9859       else
9860         break;
9861     }
9862   if (name == 0)
9863     {
9864       errmsg ("node name required");
9865       return -99;
9866     }
9867   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9868     {
9869       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9870       return -99;
9871     }
9872
9873   M (GET_NODE_INDEX, mp);
9874   clib_memcpy (mp->node_name, name, vec_len (name));
9875   vec_free (name);
9876
9877   S (mp);
9878   W (ret);
9879   return ret;
9880 }
9881
9882 static int
9883 api_get_next_index (vat_main_t * vam)
9884 {
9885   unformat_input_t *i = vam->input;
9886   vl_api_get_next_index_t *mp;
9887   u8 *node_name = 0, *next_node_name = 0;
9888   int ret;
9889
9890   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9891     {
9892       if (unformat (i, "node-name %s", &node_name))
9893         ;
9894       else if (unformat (i, "next-node-name %s", &next_node_name))
9895         break;
9896     }
9897
9898   if (node_name == 0)
9899     {
9900       errmsg ("node name required");
9901       return -99;
9902     }
9903   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9904     {
9905       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9906       return -99;
9907     }
9908
9909   if (next_node_name == 0)
9910     {
9911       errmsg ("next node name required");
9912       return -99;
9913     }
9914   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9915     {
9916       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
9917       return -99;
9918     }
9919
9920   M (GET_NEXT_INDEX, mp);
9921   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9922   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9923   vec_free (node_name);
9924   vec_free (next_node_name);
9925
9926   S (mp);
9927   W (ret);
9928   return ret;
9929 }
9930
9931 static int
9932 api_add_node_next (vat_main_t * vam)
9933 {
9934   unformat_input_t *i = vam->input;
9935   vl_api_add_node_next_t *mp;
9936   u8 *name = 0;
9937   u8 *next = 0;
9938   int ret;
9939
9940   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9941     {
9942       if (unformat (i, "node %s", &name))
9943         ;
9944       else if (unformat (i, "next %s", &next))
9945         ;
9946       else
9947         break;
9948     }
9949   if (name == 0)
9950     {
9951       errmsg ("node name required");
9952       return -99;
9953     }
9954   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9955     {
9956       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9957       return -99;
9958     }
9959   if (next == 0)
9960     {
9961       errmsg ("next node required");
9962       return -99;
9963     }
9964   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9965     {
9966       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
9967       return -99;
9968     }
9969
9970   M (ADD_NODE_NEXT, mp);
9971   clib_memcpy (mp->node_name, name, vec_len (name));
9972   clib_memcpy (mp->next_name, next, vec_len (next));
9973   vec_free (name);
9974   vec_free (next);
9975
9976   S (mp);
9977   W (ret);
9978   return ret;
9979 }
9980
9981 static int
9982 api_l2tpv3_create_tunnel (vat_main_t * vam)
9983 {
9984   unformat_input_t *i = vam->input;
9985   ip6_address_t client_address, our_address;
9986   int client_address_set = 0;
9987   int our_address_set = 0;
9988   u32 local_session_id = 0;
9989   u32 remote_session_id = 0;
9990   u64 local_cookie = 0;
9991   u64 remote_cookie = 0;
9992   u8 l2_sublayer_present = 0;
9993   vl_api_l2tpv3_create_tunnel_t *mp;
9994   int ret;
9995
9996   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9997     {
9998       if (unformat (i, "client_address %U", unformat_ip6_address,
9999                     &client_address))
10000         client_address_set = 1;
10001       else if (unformat (i, "our_address %U", unformat_ip6_address,
10002                          &our_address))
10003         our_address_set = 1;
10004       else if (unformat (i, "local_session_id %d", &local_session_id))
10005         ;
10006       else if (unformat (i, "remote_session_id %d", &remote_session_id))
10007         ;
10008       else if (unformat (i, "local_cookie %lld", &local_cookie))
10009         ;
10010       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10011         ;
10012       else if (unformat (i, "l2-sublayer-present"))
10013         l2_sublayer_present = 1;
10014       else
10015         break;
10016     }
10017
10018   if (client_address_set == 0)
10019     {
10020       errmsg ("client_address required");
10021       return -99;
10022     }
10023
10024   if (our_address_set == 0)
10025     {
10026       errmsg ("our_address required");
10027       return -99;
10028     }
10029
10030   M (L2TPV3_CREATE_TUNNEL, mp);
10031
10032   clib_memcpy (mp->client_address, client_address.as_u8,
10033                sizeof (mp->client_address));
10034
10035   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10036
10037   mp->local_session_id = ntohl (local_session_id);
10038   mp->remote_session_id = ntohl (remote_session_id);
10039   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10040   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10041   mp->l2_sublayer_present = l2_sublayer_present;
10042   mp->is_ipv6 = 1;
10043
10044   S (mp);
10045   W (ret);
10046   return ret;
10047 }
10048
10049 static int
10050 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10051 {
10052   unformat_input_t *i = vam->input;
10053   u32 sw_if_index;
10054   u8 sw_if_index_set = 0;
10055   u64 new_local_cookie = 0;
10056   u64 new_remote_cookie = 0;
10057   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10058   int ret;
10059
10060   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10061     {
10062       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10063         sw_if_index_set = 1;
10064       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10065         sw_if_index_set = 1;
10066       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10067         ;
10068       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10069         ;
10070       else
10071         break;
10072     }
10073
10074   if (sw_if_index_set == 0)
10075     {
10076       errmsg ("missing interface name or sw_if_index");
10077       return -99;
10078     }
10079
10080   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
10081
10082   mp->sw_if_index = ntohl (sw_if_index);
10083   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10084   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10085
10086   S (mp);
10087   W (ret);
10088   return ret;
10089 }
10090
10091 static int
10092 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10093 {
10094   unformat_input_t *i = vam->input;
10095   vl_api_l2tpv3_interface_enable_disable_t *mp;
10096   u32 sw_if_index;
10097   u8 sw_if_index_set = 0;
10098   u8 enable_disable = 1;
10099   int ret;
10100
10101   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10102     {
10103       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10104         sw_if_index_set = 1;
10105       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10106         sw_if_index_set = 1;
10107       else if (unformat (i, "enable"))
10108         enable_disable = 1;
10109       else if (unformat (i, "disable"))
10110         enable_disable = 0;
10111       else
10112         break;
10113     }
10114
10115   if (sw_if_index_set == 0)
10116     {
10117       errmsg ("missing interface name or sw_if_index");
10118       return -99;
10119     }
10120
10121   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
10122
10123   mp->sw_if_index = ntohl (sw_if_index);
10124   mp->enable_disable = enable_disable;
10125
10126   S (mp);
10127   W (ret);
10128   return ret;
10129 }
10130
10131 static int
10132 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10133 {
10134   unformat_input_t *i = vam->input;
10135   vl_api_l2tpv3_set_lookup_key_t *mp;
10136   u8 key = ~0;
10137   int ret;
10138
10139   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10140     {
10141       if (unformat (i, "lookup_v6_src"))
10142         key = L2T_LOOKUP_SRC_ADDRESS;
10143       else if (unformat (i, "lookup_v6_dst"))
10144         key = L2T_LOOKUP_DST_ADDRESS;
10145       else if (unformat (i, "lookup_session_id"))
10146         key = L2T_LOOKUP_SESSION_ID;
10147       else
10148         break;
10149     }
10150
10151   if (key == (u8) ~ 0)
10152     {
10153       errmsg ("l2tp session lookup key unset");
10154       return -99;
10155     }
10156
10157   M (L2TPV3_SET_LOOKUP_KEY, mp);
10158
10159   mp->key = key;
10160
10161   S (mp);
10162   W (ret);
10163   return ret;
10164 }
10165
10166 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10167   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10168 {
10169   vat_main_t *vam = &vat_main;
10170
10171   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10172          format_ip6_address, mp->our_address,
10173          format_ip6_address, mp->client_address,
10174          clib_net_to_host_u32 (mp->sw_if_index));
10175
10176   print (vam->ofp,
10177          "   local cookies %016llx %016llx remote cookie %016llx",
10178          clib_net_to_host_u64 (mp->local_cookie[0]),
10179          clib_net_to_host_u64 (mp->local_cookie[1]),
10180          clib_net_to_host_u64 (mp->remote_cookie));
10181
10182   print (vam->ofp, "   local session-id %d remote session-id %d",
10183          clib_net_to_host_u32 (mp->local_session_id),
10184          clib_net_to_host_u32 (mp->remote_session_id));
10185
10186   print (vam->ofp, "   l2 specific sublayer %s\n",
10187          mp->l2_sublayer_present ? "preset" : "absent");
10188
10189 }
10190
10191 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10192   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10193 {
10194   vat_main_t *vam = &vat_main;
10195   vat_json_node_t *node = NULL;
10196   struct in6_addr addr;
10197
10198   if (VAT_JSON_ARRAY != vam->json_tree.type)
10199     {
10200       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10201       vat_json_init_array (&vam->json_tree);
10202     }
10203   node = vat_json_array_add (&vam->json_tree);
10204
10205   vat_json_init_object (node);
10206
10207   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10208   vat_json_object_add_ip6 (node, "our_address", addr);
10209   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10210   vat_json_object_add_ip6 (node, "client_address", addr);
10211
10212   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10213   vat_json_init_array (lc);
10214   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10215   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10216   vat_json_object_add_uint (node, "remote_cookie",
10217                             clib_net_to_host_u64 (mp->remote_cookie));
10218
10219   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10220   vat_json_object_add_uint (node, "local_session_id",
10221                             clib_net_to_host_u32 (mp->local_session_id));
10222   vat_json_object_add_uint (node, "remote_session_id",
10223                             clib_net_to_host_u32 (mp->remote_session_id));
10224   vat_json_object_add_string_copy (node, "l2_sublayer",
10225                                    mp->l2_sublayer_present ? (u8 *) "present"
10226                                    : (u8 *) "absent");
10227 }
10228
10229 static int
10230 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10231 {
10232   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10233   vl_api_control_ping_t *mp_ping;
10234   int ret;
10235
10236   /* Get list of l2tpv3-tunnel interfaces */
10237   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
10238   S (mp);
10239
10240   /* Use a control ping for synchronization */
10241   M (CONTROL_PING, mp_ping);
10242   S (mp_ping);
10243
10244   W (ret);
10245   return ret;
10246 }
10247
10248
10249 static void vl_api_sw_interface_tap_details_t_handler
10250   (vl_api_sw_interface_tap_details_t * mp)
10251 {
10252   vat_main_t *vam = &vat_main;
10253
10254   print (vam->ofp, "%-16s %d",
10255          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10256 }
10257
10258 static void vl_api_sw_interface_tap_details_t_handler_json
10259   (vl_api_sw_interface_tap_details_t * mp)
10260 {
10261   vat_main_t *vam = &vat_main;
10262   vat_json_node_t *node = NULL;
10263
10264   if (VAT_JSON_ARRAY != vam->json_tree.type)
10265     {
10266       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10267       vat_json_init_array (&vam->json_tree);
10268     }
10269   node = vat_json_array_add (&vam->json_tree);
10270
10271   vat_json_init_object (node);
10272   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10273   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10274 }
10275
10276 static int
10277 api_sw_interface_tap_dump (vat_main_t * vam)
10278 {
10279   vl_api_sw_interface_tap_dump_t *mp;
10280   vl_api_control_ping_t *mp_ping;
10281   int ret;
10282
10283   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10284   /* Get list of tap interfaces */
10285   M (SW_INTERFACE_TAP_DUMP, mp);
10286   S (mp);
10287
10288   /* Use a control ping for synchronization */
10289   M (CONTROL_PING, mp_ping);
10290   S (mp_ping);
10291
10292   W (ret);
10293   return ret;
10294 }
10295
10296 static uword unformat_vxlan_decap_next
10297   (unformat_input_t * input, va_list * args)
10298 {
10299   u32 *result = va_arg (*args, u32 *);
10300   u32 tmp;
10301
10302   if (unformat (input, "l2"))
10303     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10304   else if (unformat (input, "%d", &tmp))
10305     *result = tmp;
10306   else
10307     return 0;
10308   return 1;
10309 }
10310
10311 static int
10312 api_vxlan_add_del_tunnel (vat_main_t * vam)
10313 {
10314   unformat_input_t *line_input = vam->input;
10315   vl_api_vxlan_add_del_tunnel_t *mp;
10316   ip46_address_t src, dst;
10317   u8 is_add = 1;
10318   u8 ipv4_set = 0, ipv6_set = 0;
10319   u8 src_set = 0;
10320   u8 dst_set = 0;
10321   u8 grp_set = 0;
10322   u32 mcast_sw_if_index = ~0;
10323   u32 encap_vrf_id = 0;
10324   u32 decap_next_index = ~0;
10325   u32 vni = 0;
10326   int ret;
10327
10328   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10329   memset (&src, 0, sizeof src);
10330   memset (&dst, 0, sizeof dst);
10331
10332   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10333     {
10334       if (unformat (line_input, "del"))
10335         is_add = 0;
10336       else
10337         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10338         {
10339           ipv4_set = 1;
10340           src_set = 1;
10341         }
10342       else
10343         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10344         {
10345           ipv4_set = 1;
10346           dst_set = 1;
10347         }
10348       else
10349         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10350         {
10351           ipv6_set = 1;
10352           src_set = 1;
10353         }
10354       else
10355         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10356         {
10357           ipv6_set = 1;
10358           dst_set = 1;
10359         }
10360       else if (unformat (line_input, "group %U %U",
10361                          unformat_ip4_address, &dst.ip4,
10362                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10363         {
10364           grp_set = dst_set = 1;
10365           ipv4_set = 1;
10366         }
10367       else if (unformat (line_input, "group %U",
10368                          unformat_ip4_address, &dst.ip4))
10369         {
10370           grp_set = dst_set = 1;
10371           ipv4_set = 1;
10372         }
10373       else if (unformat (line_input, "group %U %U",
10374                          unformat_ip6_address, &dst.ip6,
10375                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10376         {
10377           grp_set = dst_set = 1;
10378           ipv6_set = 1;
10379         }
10380       else if (unformat (line_input, "group %U",
10381                          unformat_ip6_address, &dst.ip6))
10382         {
10383           grp_set = dst_set = 1;
10384           ipv6_set = 1;
10385         }
10386       else
10387         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10388         ;
10389       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10390         ;
10391       else if (unformat (line_input, "decap-next %U",
10392                          unformat_vxlan_decap_next, &decap_next_index))
10393         ;
10394       else if (unformat (line_input, "vni %d", &vni))
10395         ;
10396       else
10397         {
10398           errmsg ("parse error '%U'", format_unformat_error, line_input);
10399           return -99;
10400         }
10401     }
10402
10403   if (src_set == 0)
10404     {
10405       errmsg ("tunnel src address not specified");
10406       return -99;
10407     }
10408   if (dst_set == 0)
10409     {
10410       errmsg ("tunnel dst address not specified");
10411       return -99;
10412     }
10413
10414   if (grp_set && !ip46_address_is_multicast (&dst))
10415     {
10416       errmsg ("tunnel group address not multicast");
10417       return -99;
10418     }
10419   if (grp_set && mcast_sw_if_index == ~0)
10420     {
10421       errmsg ("tunnel nonexistent multicast device");
10422       return -99;
10423     }
10424   if (grp_set == 0 && ip46_address_is_multicast (&dst))
10425     {
10426       errmsg ("tunnel dst address must be unicast");
10427       return -99;
10428     }
10429
10430
10431   if (ipv4_set && ipv6_set)
10432     {
10433       errmsg ("both IPv4 and IPv6 addresses specified");
10434       return -99;
10435     }
10436
10437   if ((vni == 0) || (vni >> 24))
10438     {
10439       errmsg ("vni not specified or out of range");
10440       return -99;
10441     }
10442
10443   M (VXLAN_ADD_DEL_TUNNEL, mp);
10444
10445   if (ipv6_set)
10446     {
10447       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10448       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10449     }
10450   else
10451     {
10452       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10453       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10454     }
10455   mp->encap_vrf_id = ntohl (encap_vrf_id);
10456   mp->decap_next_index = ntohl (decap_next_index);
10457   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10458   mp->vni = ntohl (vni);
10459   mp->is_add = is_add;
10460   mp->is_ipv6 = ipv6_set;
10461
10462   S (mp);
10463   W (ret);
10464   return ret;
10465 }
10466
10467 static void vl_api_vxlan_tunnel_details_t_handler
10468   (vl_api_vxlan_tunnel_details_t * mp)
10469 {
10470   vat_main_t *vam = &vat_main;
10471   ip46_address_t src, dst;
10472
10473   ip46_from_addr_buf (mp->is_ipv6, mp->src_address, &src);
10474   ip46_from_addr_buf (mp->is_ipv6, mp->dst_address, &dst);
10475
10476   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
10477          ntohl (mp->sw_if_index),
10478          format_ip46_address, &src, IP46_TYPE_ANY,
10479          format_ip46_address, &dst, IP46_TYPE_ANY,
10480          ntohl (mp->encap_vrf_id),
10481          ntohl (mp->decap_next_index), ntohl (mp->vni),
10482          ntohl (mp->mcast_sw_if_index));
10483 }
10484
10485 static void vl_api_vxlan_tunnel_details_t_handler_json
10486   (vl_api_vxlan_tunnel_details_t * mp)
10487 {
10488   vat_main_t *vam = &vat_main;
10489   vat_json_node_t *node = NULL;
10490
10491   if (VAT_JSON_ARRAY != vam->json_tree.type)
10492     {
10493       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10494       vat_json_init_array (&vam->json_tree);
10495     }
10496   node = vat_json_array_add (&vam->json_tree);
10497
10498   vat_json_init_object (node);
10499   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10500   if (mp->is_ipv6)
10501     {
10502       struct in6_addr ip6;
10503
10504       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10505       vat_json_object_add_ip6 (node, "src_address", ip6);
10506       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10507       vat_json_object_add_ip6 (node, "dst_address", ip6);
10508     }
10509   else
10510     {
10511       struct in_addr ip4;
10512
10513       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10514       vat_json_object_add_ip4 (node, "src_address", ip4);
10515       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10516       vat_json_object_add_ip4 (node, "dst_address", ip4);
10517     }
10518   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10519   vat_json_object_add_uint (node, "decap_next_index",
10520                             ntohl (mp->decap_next_index));
10521   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10522   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10523   vat_json_object_add_uint (node, "mcast_sw_if_index",
10524                             ntohl (mp->mcast_sw_if_index));
10525 }
10526
10527 static int
10528 api_vxlan_tunnel_dump (vat_main_t * vam)
10529 {
10530   unformat_input_t *i = vam->input;
10531   vl_api_vxlan_tunnel_dump_t *mp;
10532   vl_api_control_ping_t *mp_ping;
10533   u32 sw_if_index;
10534   u8 sw_if_index_set = 0;
10535   int ret;
10536
10537   /* Parse args required to build the message */
10538   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10539     {
10540       if (unformat (i, "sw_if_index %d", &sw_if_index))
10541         sw_if_index_set = 1;
10542       else
10543         break;
10544     }
10545
10546   if (sw_if_index_set == 0)
10547     {
10548       sw_if_index = ~0;
10549     }
10550
10551   if (!vam->json_output)
10552     {
10553       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
10554              "sw_if_index", "src_address", "dst_address",
10555              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
10556     }
10557
10558   /* Get list of vxlan-tunnel interfaces */
10559   M (VXLAN_TUNNEL_DUMP, mp);
10560
10561   mp->sw_if_index = htonl (sw_if_index);
10562
10563   S (mp);
10564
10565   /* Use a control ping for synchronization */
10566   M (CONTROL_PING, mp_ping);
10567   S (mp_ping);
10568
10569   W (ret);
10570   return ret;
10571 }
10572
10573 static int
10574 api_gre_add_del_tunnel (vat_main_t * vam)
10575 {
10576   unformat_input_t *line_input = vam->input;
10577   vl_api_gre_add_del_tunnel_t *mp;
10578   ip4_address_t src4, dst4;
10579   u8 is_add = 1;
10580   u8 teb = 0;
10581   u8 src_set = 0;
10582   u8 dst_set = 0;
10583   u32 outer_fib_id = 0;
10584   int ret;
10585
10586   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10587     {
10588       if (unformat (line_input, "del"))
10589         is_add = 0;
10590       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10591         src_set = 1;
10592       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10593         dst_set = 1;
10594       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10595         ;
10596       else if (unformat (line_input, "teb"))
10597         teb = 1;
10598       else
10599         {
10600           errmsg ("parse error '%U'", format_unformat_error, line_input);
10601           return -99;
10602         }
10603     }
10604
10605   if (src_set == 0)
10606     {
10607       errmsg ("tunnel src address not specified");
10608       return -99;
10609     }
10610   if (dst_set == 0)
10611     {
10612       errmsg ("tunnel dst address not specified");
10613       return -99;
10614     }
10615
10616
10617   M (GRE_ADD_DEL_TUNNEL, mp);
10618
10619   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10620   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10621   mp->outer_fib_id = ntohl (outer_fib_id);
10622   mp->is_add = is_add;
10623   mp->teb = teb;
10624
10625   S (mp);
10626   W (ret);
10627   return ret;
10628 }
10629
10630 static void vl_api_gre_tunnel_details_t_handler
10631   (vl_api_gre_tunnel_details_t * mp)
10632 {
10633   vat_main_t *vam = &vat_main;
10634
10635   print (vam->ofp, "%11d%15U%15U%6d%14d",
10636          ntohl (mp->sw_if_index),
10637          format_ip4_address, &mp->src_address,
10638          format_ip4_address, &mp->dst_address,
10639          mp->teb, ntohl (mp->outer_fib_id));
10640 }
10641
10642 static void vl_api_gre_tunnel_details_t_handler_json
10643   (vl_api_gre_tunnel_details_t * mp)
10644 {
10645   vat_main_t *vam = &vat_main;
10646   vat_json_node_t *node = NULL;
10647   struct in_addr ip4;
10648
10649   if (VAT_JSON_ARRAY != vam->json_tree.type)
10650     {
10651       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10652       vat_json_init_array (&vam->json_tree);
10653     }
10654   node = vat_json_array_add (&vam->json_tree);
10655
10656   vat_json_init_object (node);
10657   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10658   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10659   vat_json_object_add_ip4 (node, "src_address", ip4);
10660   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10661   vat_json_object_add_ip4 (node, "dst_address", ip4);
10662   vat_json_object_add_uint (node, "teb", mp->teb);
10663   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10664 }
10665
10666 static int
10667 api_gre_tunnel_dump (vat_main_t * vam)
10668 {
10669   unformat_input_t *i = vam->input;
10670   vl_api_gre_tunnel_dump_t *mp;
10671   vl_api_control_ping_t *mp_ping;
10672   u32 sw_if_index;
10673   u8 sw_if_index_set = 0;
10674   int ret;
10675
10676   /* Parse args required to build the message */
10677   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10678     {
10679       if (unformat (i, "sw_if_index %d", &sw_if_index))
10680         sw_if_index_set = 1;
10681       else
10682         break;
10683     }
10684
10685   if (sw_if_index_set == 0)
10686     {
10687       sw_if_index = ~0;
10688     }
10689
10690   if (!vam->json_output)
10691     {
10692       print (vam->ofp, "%11s%15s%15s%6s%14s",
10693              "sw_if_index", "src_address", "dst_address", "teb",
10694              "outer_fib_id");
10695     }
10696
10697   /* Get list of gre-tunnel interfaces */
10698   M (GRE_TUNNEL_DUMP, mp);
10699
10700   mp->sw_if_index = htonl (sw_if_index);
10701
10702   S (mp);
10703
10704   /* Use a control ping for synchronization */
10705   M (CONTROL_PING, mp_ping);
10706   S (mp_ping);
10707
10708   W (ret);
10709   return ret;
10710 }
10711
10712 static int
10713 api_l2_fib_clear_table (vat_main_t * vam)
10714 {
10715 //  unformat_input_t * i = vam->input;
10716   vl_api_l2_fib_clear_table_t *mp;
10717   int ret;
10718
10719   M (L2_FIB_CLEAR_TABLE, mp);
10720
10721   S (mp);
10722   W (ret);
10723   return ret;
10724 }
10725
10726 static int
10727 api_l2_interface_efp_filter (vat_main_t * vam)
10728 {
10729   unformat_input_t *i = vam->input;
10730   vl_api_l2_interface_efp_filter_t *mp;
10731   u32 sw_if_index;
10732   u8 enable = 1;
10733   u8 sw_if_index_set = 0;
10734   int ret;
10735
10736   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10737     {
10738       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10739         sw_if_index_set = 1;
10740       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10741         sw_if_index_set = 1;
10742       else if (unformat (i, "enable"))
10743         enable = 1;
10744       else if (unformat (i, "disable"))
10745         enable = 0;
10746       else
10747         {
10748           clib_warning ("parse error '%U'", format_unformat_error, i);
10749           return -99;
10750         }
10751     }
10752
10753   if (sw_if_index_set == 0)
10754     {
10755       errmsg ("missing sw_if_index");
10756       return -99;
10757     }
10758
10759   M (L2_INTERFACE_EFP_FILTER, mp);
10760
10761   mp->sw_if_index = ntohl (sw_if_index);
10762   mp->enable_disable = enable;
10763
10764   S (mp);
10765   W (ret);
10766   return ret;
10767 }
10768
10769 #define foreach_vtr_op                          \
10770 _("disable",  L2_VTR_DISABLED)                  \
10771 _("push-1",  L2_VTR_PUSH_1)                     \
10772 _("push-2",  L2_VTR_PUSH_2)                     \
10773 _("pop-1",  L2_VTR_POP_1)                       \
10774 _("pop-2",  L2_VTR_POP_2)                       \
10775 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10776 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10777 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10778 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10779
10780 static int
10781 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10782 {
10783   unformat_input_t *i = vam->input;
10784   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10785   u32 sw_if_index;
10786   u8 sw_if_index_set = 0;
10787   u8 vtr_op_set = 0;
10788   u32 vtr_op = 0;
10789   u32 push_dot1q = 1;
10790   u32 tag1 = ~0;
10791   u32 tag2 = ~0;
10792   int ret;
10793
10794   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10795     {
10796       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10797         sw_if_index_set = 1;
10798       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10799         sw_if_index_set = 1;
10800       else if (unformat (i, "vtr_op %d", &vtr_op))
10801         vtr_op_set = 1;
10802 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
10803       foreach_vtr_op
10804 #undef _
10805         else if (unformat (i, "push_dot1q %d", &push_dot1q))
10806         ;
10807       else if (unformat (i, "tag1 %d", &tag1))
10808         ;
10809       else if (unformat (i, "tag2 %d", &tag2))
10810         ;
10811       else
10812         {
10813           clib_warning ("parse error '%U'", format_unformat_error, i);
10814           return -99;
10815         }
10816     }
10817
10818   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
10819     {
10820       errmsg ("missing vtr operation or sw_if_index");
10821       return -99;
10822     }
10823
10824   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
10825   mp->sw_if_index = ntohl (sw_if_index);
10826   mp->vtr_op = ntohl (vtr_op);
10827   mp->push_dot1q = ntohl (push_dot1q);
10828   mp->tag1 = ntohl (tag1);
10829   mp->tag2 = ntohl (tag2);
10830
10831   S (mp);
10832   W (ret);
10833   return ret;
10834 }
10835
10836 static int
10837 api_create_vhost_user_if (vat_main_t * vam)
10838 {
10839   unformat_input_t *i = vam->input;
10840   vl_api_create_vhost_user_if_t *mp;
10841   u8 *file_name;
10842   u8 is_server = 0;
10843   u8 file_name_set = 0;
10844   u32 custom_dev_instance = ~0;
10845   u8 hwaddr[6];
10846   u8 use_custom_mac = 0;
10847   u8 *tag = 0;
10848   int ret;
10849
10850   /* Shut up coverity */
10851   memset (hwaddr, 0, sizeof (hwaddr));
10852
10853   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10854     {
10855       if (unformat (i, "socket %s", &file_name))
10856         {
10857           file_name_set = 1;
10858         }
10859       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10860         ;
10861       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10862         use_custom_mac = 1;
10863       else if (unformat (i, "server"))
10864         is_server = 1;
10865       else if (unformat (i, "tag %s", &tag))
10866         ;
10867       else
10868         break;
10869     }
10870
10871   if (file_name_set == 0)
10872     {
10873       errmsg ("missing socket file name");
10874       return -99;
10875     }
10876
10877   if (vec_len (file_name) > 255)
10878     {
10879       errmsg ("socket file name too long");
10880       return -99;
10881     }
10882   vec_add1 (file_name, 0);
10883
10884   M (CREATE_VHOST_USER_IF, mp);
10885
10886   mp->is_server = is_server;
10887   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10888   vec_free (file_name);
10889   if (custom_dev_instance != ~0)
10890     {
10891       mp->renumber = 1;
10892       mp->custom_dev_instance = ntohl (custom_dev_instance);
10893     }
10894   mp->use_custom_mac = use_custom_mac;
10895   clib_memcpy (mp->mac_address, hwaddr, 6);
10896   if (tag)
10897     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
10898   vec_free (tag);
10899
10900   S (mp);
10901   W (ret);
10902   return ret;
10903 }
10904
10905 static int
10906 api_modify_vhost_user_if (vat_main_t * vam)
10907 {
10908   unformat_input_t *i = vam->input;
10909   vl_api_modify_vhost_user_if_t *mp;
10910   u8 *file_name;
10911   u8 is_server = 0;
10912   u8 file_name_set = 0;
10913   u32 custom_dev_instance = ~0;
10914   u8 sw_if_index_set = 0;
10915   u32 sw_if_index = (u32) ~ 0;
10916   int ret;
10917
10918   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10919     {
10920       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10921         sw_if_index_set = 1;
10922       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10923         sw_if_index_set = 1;
10924       else if (unformat (i, "socket %s", &file_name))
10925         {
10926           file_name_set = 1;
10927         }
10928       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10929         ;
10930       else if (unformat (i, "server"))
10931         is_server = 1;
10932       else
10933         break;
10934     }
10935
10936   if (sw_if_index_set == 0)
10937     {
10938       errmsg ("missing sw_if_index or interface name");
10939       return -99;
10940     }
10941
10942   if (file_name_set == 0)
10943     {
10944       errmsg ("missing socket file name");
10945       return -99;
10946     }
10947
10948   if (vec_len (file_name) > 255)
10949     {
10950       errmsg ("socket file name too long");
10951       return -99;
10952     }
10953   vec_add1 (file_name, 0);
10954
10955   M (MODIFY_VHOST_USER_IF, mp);
10956
10957   mp->sw_if_index = ntohl (sw_if_index);
10958   mp->is_server = is_server;
10959   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10960   vec_free (file_name);
10961   if (custom_dev_instance != ~0)
10962     {
10963       mp->renumber = 1;
10964       mp->custom_dev_instance = ntohl (custom_dev_instance);
10965     }
10966
10967   S (mp);
10968   W (ret);
10969   return ret;
10970 }
10971
10972 static int
10973 api_delete_vhost_user_if (vat_main_t * vam)
10974 {
10975   unformat_input_t *i = vam->input;
10976   vl_api_delete_vhost_user_if_t *mp;
10977   u32 sw_if_index = ~0;
10978   u8 sw_if_index_set = 0;
10979   int ret;
10980
10981   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10982     {
10983       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10984         sw_if_index_set = 1;
10985       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10986         sw_if_index_set = 1;
10987       else
10988         break;
10989     }
10990
10991   if (sw_if_index_set == 0)
10992     {
10993       errmsg ("missing sw_if_index or interface name");
10994       return -99;
10995     }
10996
10997
10998   M (DELETE_VHOST_USER_IF, mp);
10999
11000   mp->sw_if_index = ntohl (sw_if_index);
11001
11002   S (mp);
11003   W (ret);
11004   return ret;
11005 }
11006
11007 static void vl_api_sw_interface_vhost_user_details_t_handler
11008   (vl_api_sw_interface_vhost_user_details_t * mp)
11009 {
11010   vat_main_t *vam = &vat_main;
11011
11012   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
11013          (char *) mp->interface_name,
11014          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11015          clib_net_to_host_u64 (mp->features), mp->is_server,
11016          ntohl (mp->num_regions), (char *) mp->sock_filename);
11017   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
11018 }
11019
11020 static void vl_api_sw_interface_vhost_user_details_t_handler_json
11021   (vl_api_sw_interface_vhost_user_details_t * mp)
11022 {
11023   vat_main_t *vam = &vat_main;
11024   vat_json_node_t *node = NULL;
11025
11026   if (VAT_JSON_ARRAY != vam->json_tree.type)
11027     {
11028       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11029       vat_json_init_array (&vam->json_tree);
11030     }
11031   node = vat_json_array_add (&vam->json_tree);
11032
11033   vat_json_init_object (node);
11034   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11035   vat_json_object_add_string_copy (node, "interface_name",
11036                                    mp->interface_name);
11037   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11038                             ntohl (mp->virtio_net_hdr_sz));
11039   vat_json_object_add_uint (node, "features",
11040                             clib_net_to_host_u64 (mp->features));
11041   vat_json_object_add_uint (node, "is_server", mp->is_server);
11042   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11043   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11044   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11045 }
11046
11047 static int
11048 api_sw_interface_vhost_user_dump (vat_main_t * vam)
11049 {
11050   vl_api_sw_interface_vhost_user_dump_t *mp;
11051   vl_api_control_ping_t *mp_ping;
11052   int ret;
11053   print (vam->ofp,
11054          "Interface name           idx hdr_sz features server regions filename");
11055
11056   /* Get list of vhost-user interfaces */
11057   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
11058   S (mp);
11059
11060   /* Use a control ping for synchronization */
11061   M (CONTROL_PING, mp_ping);
11062   S (mp_ping);
11063
11064   W (ret);
11065   return ret;
11066 }
11067
11068 static int
11069 api_show_version (vat_main_t * vam)
11070 {
11071   vl_api_show_version_t *mp;
11072   int ret;
11073
11074   M (SHOW_VERSION, mp);
11075
11076   S (mp);
11077   W (ret);
11078   return ret;
11079 }
11080
11081
11082 static int
11083 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11084 {
11085   unformat_input_t *line_input = vam->input;
11086   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11087   ip4_address_t local4, remote4;
11088   ip6_address_t local6, remote6;
11089   u8 is_add = 1;
11090   u8 ipv4_set = 0, ipv6_set = 0;
11091   u8 local_set = 0;
11092   u8 remote_set = 0;
11093   u32 encap_vrf_id = 0;
11094   u32 decap_vrf_id = 0;
11095   u8 protocol = ~0;
11096   u32 vni;
11097   u8 vni_set = 0;
11098   int ret;
11099
11100   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11101     {
11102       if (unformat (line_input, "del"))
11103         is_add = 0;
11104       else if (unformat (line_input, "local %U",
11105                          unformat_ip4_address, &local4))
11106         {
11107           local_set = 1;
11108           ipv4_set = 1;
11109         }
11110       else if (unformat (line_input, "remote %U",
11111                          unformat_ip4_address, &remote4))
11112         {
11113           remote_set = 1;
11114           ipv4_set = 1;
11115         }
11116       else if (unformat (line_input, "local %U",
11117                          unformat_ip6_address, &local6))
11118         {
11119           local_set = 1;
11120           ipv6_set = 1;
11121         }
11122       else if (unformat (line_input, "remote %U",
11123                          unformat_ip6_address, &remote6))
11124         {
11125           remote_set = 1;
11126           ipv6_set = 1;
11127         }
11128       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11129         ;
11130       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11131         ;
11132       else if (unformat (line_input, "vni %d", &vni))
11133         vni_set = 1;
11134       else if (unformat (line_input, "next-ip4"))
11135         protocol = 1;
11136       else if (unformat (line_input, "next-ip6"))
11137         protocol = 2;
11138       else if (unformat (line_input, "next-ethernet"))
11139         protocol = 3;
11140       else if (unformat (line_input, "next-nsh"))
11141         protocol = 4;
11142       else
11143         {
11144           errmsg ("parse error '%U'", format_unformat_error, line_input);
11145           return -99;
11146         }
11147     }
11148
11149   if (local_set == 0)
11150     {
11151       errmsg ("tunnel local address not specified");
11152       return -99;
11153     }
11154   if (remote_set == 0)
11155     {
11156       errmsg ("tunnel remote address not specified");
11157       return -99;
11158     }
11159   if (ipv4_set && ipv6_set)
11160     {
11161       errmsg ("both IPv4 and IPv6 addresses specified");
11162       return -99;
11163     }
11164
11165   if (vni_set == 0)
11166     {
11167       errmsg ("vni not specified");
11168       return -99;
11169     }
11170
11171   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
11172
11173
11174   if (ipv6_set)
11175     {
11176       clib_memcpy (&mp->local, &local6, sizeof (local6));
11177       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11178     }
11179   else
11180     {
11181       clib_memcpy (&mp->local, &local4, sizeof (local4));
11182       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11183     }
11184
11185   mp->encap_vrf_id = ntohl (encap_vrf_id);
11186   mp->decap_vrf_id = ntohl (decap_vrf_id);
11187   mp->protocol = protocol;
11188   mp->vni = ntohl (vni);
11189   mp->is_add = is_add;
11190   mp->is_ipv6 = ipv6_set;
11191
11192   S (mp);
11193   W (ret);
11194   return ret;
11195 }
11196
11197 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11198   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11199 {
11200   vat_main_t *vam = &vat_main;
11201
11202   print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11203          ntohl (mp->sw_if_index),
11204          format_ip46_address, &(mp->local[0]),
11205          format_ip46_address, &(mp->remote[0]),
11206          ntohl (mp->vni),
11207          ntohl (mp->protocol),
11208          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11209 }
11210
11211 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11212   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11213 {
11214   vat_main_t *vam = &vat_main;
11215   vat_json_node_t *node = NULL;
11216   struct in_addr ip4;
11217   struct in6_addr ip6;
11218
11219   if (VAT_JSON_ARRAY != vam->json_tree.type)
11220     {
11221       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11222       vat_json_init_array (&vam->json_tree);
11223     }
11224   node = vat_json_array_add (&vam->json_tree);
11225
11226   vat_json_init_object (node);
11227   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11228   if (mp->is_ipv6)
11229     {
11230       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11231       vat_json_object_add_ip6 (node, "local", ip6);
11232       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11233       vat_json_object_add_ip6 (node, "remote", ip6);
11234     }
11235   else
11236     {
11237       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11238       vat_json_object_add_ip4 (node, "local", ip4);
11239       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11240       vat_json_object_add_ip4 (node, "remote", ip4);
11241     }
11242   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11243   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11244   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11245   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11246   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11247 }
11248
11249 static int
11250 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11251 {
11252   unformat_input_t *i = vam->input;
11253   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11254   vl_api_control_ping_t *mp_ping;
11255   u32 sw_if_index;
11256   u8 sw_if_index_set = 0;
11257   int ret;
11258
11259   /* Parse args required to build the message */
11260   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11261     {
11262       if (unformat (i, "sw_if_index %d", &sw_if_index))
11263         sw_if_index_set = 1;
11264       else
11265         break;
11266     }
11267
11268   if (sw_if_index_set == 0)
11269     {
11270       sw_if_index = ~0;
11271     }
11272
11273   if (!vam->json_output)
11274     {
11275       print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11276              "sw_if_index", "local", "remote", "vni",
11277              "protocol", "encap_vrf_id", "decap_vrf_id");
11278     }
11279
11280   /* Get list of vxlan-tunnel interfaces */
11281   M (VXLAN_GPE_TUNNEL_DUMP, mp);
11282
11283   mp->sw_if_index = htonl (sw_if_index);
11284
11285   S (mp);
11286
11287   /* Use a control ping for synchronization */
11288   M (CONTROL_PING, mp_ping);
11289   S (mp_ping);
11290
11291   W (ret);
11292   return ret;
11293 }
11294
11295 u8 *
11296 format_l2_fib_mac_address (u8 * s, va_list * args)
11297 {
11298   u8 *a = va_arg (*args, u8 *);
11299
11300   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11301                  a[2], a[3], a[4], a[5], a[6], a[7]);
11302 }
11303
11304 static void vl_api_l2_fib_table_entry_t_handler
11305   (vl_api_l2_fib_table_entry_t * mp)
11306 {
11307   vat_main_t *vam = &vat_main;
11308
11309   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11310          "       %d       %d     %d",
11311          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11312          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11313          mp->bvi_mac);
11314 }
11315
11316 static void vl_api_l2_fib_table_entry_t_handler_json
11317   (vl_api_l2_fib_table_entry_t * mp)
11318 {
11319   vat_main_t *vam = &vat_main;
11320   vat_json_node_t *node = NULL;
11321
11322   if (VAT_JSON_ARRAY != vam->json_tree.type)
11323     {
11324       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11325       vat_json_init_array (&vam->json_tree);
11326     }
11327   node = vat_json_array_add (&vam->json_tree);
11328
11329   vat_json_init_object (node);
11330   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11331   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11332   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11333   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11334   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11335   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11336 }
11337
11338 static int
11339 api_l2_fib_table_dump (vat_main_t * vam)
11340 {
11341   unformat_input_t *i = vam->input;
11342   vl_api_l2_fib_table_dump_t *mp;
11343   vl_api_control_ping_t *mp_ping;
11344   u32 bd_id;
11345   u8 bd_id_set = 0;
11346   int ret;
11347
11348   /* Parse args required to build the message */
11349   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11350     {
11351       if (unformat (i, "bd_id %d", &bd_id))
11352         bd_id_set = 1;
11353       else
11354         break;
11355     }
11356
11357   if (bd_id_set == 0)
11358     {
11359       errmsg ("missing bridge domain");
11360       return -99;
11361     }
11362
11363   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
11364
11365   /* Get list of l2 fib entries */
11366   M (L2_FIB_TABLE_DUMP, mp);
11367
11368   mp->bd_id = ntohl (bd_id);
11369   S (mp);
11370
11371   /* Use a control ping for synchronization */
11372   M (CONTROL_PING, mp_ping);
11373   S (mp_ping);
11374
11375   W (ret);
11376   return ret;
11377 }
11378
11379
11380 static int
11381 api_interface_name_renumber (vat_main_t * vam)
11382 {
11383   unformat_input_t *line_input = vam->input;
11384   vl_api_interface_name_renumber_t *mp;
11385   u32 sw_if_index = ~0;
11386   u32 new_show_dev_instance = ~0;
11387   int ret;
11388
11389   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11390     {
11391       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
11392                     &sw_if_index))
11393         ;
11394       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11395         ;
11396       else if (unformat (line_input, "new_show_dev_instance %d",
11397                          &new_show_dev_instance))
11398         ;
11399       else
11400         break;
11401     }
11402
11403   if (sw_if_index == ~0)
11404     {
11405       errmsg ("missing interface name or sw_if_index");
11406       return -99;
11407     }
11408
11409   if (new_show_dev_instance == ~0)
11410     {
11411       errmsg ("missing new_show_dev_instance");
11412       return -99;
11413     }
11414
11415   M (INTERFACE_NAME_RENUMBER, mp);
11416
11417   mp->sw_if_index = ntohl (sw_if_index);
11418   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11419
11420   S (mp);
11421   W (ret);
11422   return ret;
11423 }
11424
11425 static int
11426 api_want_ip4_arp_events (vat_main_t * vam)
11427 {
11428   unformat_input_t *line_input = vam->input;
11429   vl_api_want_ip4_arp_events_t *mp;
11430   ip4_address_t address;
11431   int address_set = 0;
11432   u32 enable_disable = 1;
11433   int ret;
11434
11435   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11436     {
11437       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11438         address_set = 1;
11439       else if (unformat (line_input, "del"))
11440         enable_disable = 0;
11441       else
11442         break;
11443     }
11444
11445   if (address_set == 0)
11446     {
11447       errmsg ("missing addresses");
11448       return -99;
11449     }
11450
11451   M (WANT_IP4_ARP_EVENTS, mp);
11452   mp->enable_disable = enable_disable;
11453   mp->pid = getpid ();
11454   mp->address = address.as_u32;
11455
11456   S (mp);
11457   W (ret);
11458   return ret;
11459 }
11460
11461 static int
11462 api_want_ip6_nd_events (vat_main_t * vam)
11463 {
11464   unformat_input_t *line_input = vam->input;
11465   vl_api_want_ip6_nd_events_t *mp;
11466   ip6_address_t address;
11467   int address_set = 0;
11468   u32 enable_disable = 1;
11469   int ret;
11470
11471   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11472     {
11473       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11474         address_set = 1;
11475       else if (unformat (line_input, "del"))
11476         enable_disable = 0;
11477       else
11478         break;
11479     }
11480
11481   if (address_set == 0)
11482     {
11483       errmsg ("missing addresses");
11484       return -99;
11485     }
11486
11487   M (WANT_IP6_ND_EVENTS, mp);
11488   mp->enable_disable = enable_disable;
11489   mp->pid = getpid ();
11490   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11491
11492   S (mp);
11493   W (ret);
11494   return ret;
11495 }
11496
11497 static int
11498 api_input_acl_set_interface (vat_main_t * vam)
11499 {
11500   unformat_input_t *i = vam->input;
11501   vl_api_input_acl_set_interface_t *mp;
11502   u32 sw_if_index;
11503   int sw_if_index_set;
11504   u32 ip4_table_index = ~0;
11505   u32 ip6_table_index = ~0;
11506   u32 l2_table_index = ~0;
11507   u8 is_add = 1;
11508   int ret;
11509
11510   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11511     {
11512       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11513         sw_if_index_set = 1;
11514       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11515         sw_if_index_set = 1;
11516       else if (unformat (i, "del"))
11517         is_add = 0;
11518       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11519         ;
11520       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11521         ;
11522       else if (unformat (i, "l2-table %d", &l2_table_index))
11523         ;
11524       else
11525         {
11526           clib_warning ("parse error '%U'", format_unformat_error, i);
11527           return -99;
11528         }
11529     }
11530
11531   if (sw_if_index_set == 0)
11532     {
11533       errmsg ("missing interface name or sw_if_index");
11534       return -99;
11535     }
11536
11537   M (INPUT_ACL_SET_INTERFACE, mp);
11538
11539   mp->sw_if_index = ntohl (sw_if_index);
11540   mp->ip4_table_index = ntohl (ip4_table_index);
11541   mp->ip6_table_index = ntohl (ip6_table_index);
11542   mp->l2_table_index = ntohl (l2_table_index);
11543   mp->is_add = is_add;
11544
11545   S (mp);
11546   W (ret);
11547   return ret;
11548 }
11549
11550 static int
11551 api_ip_address_dump (vat_main_t * vam)
11552 {
11553   unformat_input_t *i = vam->input;
11554   vl_api_ip_address_dump_t *mp;
11555   vl_api_control_ping_t *mp_ping;
11556   u32 sw_if_index = ~0;
11557   u8 sw_if_index_set = 0;
11558   u8 ipv4_set = 0;
11559   u8 ipv6_set = 0;
11560   int ret;
11561
11562   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11563     {
11564       if (unformat (i, "sw_if_index %d", &sw_if_index))
11565         sw_if_index_set = 1;
11566       else
11567         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11568         sw_if_index_set = 1;
11569       else if (unformat (i, "ipv4"))
11570         ipv4_set = 1;
11571       else if (unformat (i, "ipv6"))
11572         ipv6_set = 1;
11573       else
11574         break;
11575     }
11576
11577   if (ipv4_set && ipv6_set)
11578     {
11579       errmsg ("ipv4 and ipv6 flags cannot be both set");
11580       return -99;
11581     }
11582
11583   if ((!ipv4_set) && (!ipv6_set))
11584     {
11585       errmsg ("no ipv4 nor ipv6 flag set");
11586       return -99;
11587     }
11588
11589   if (sw_if_index_set == 0)
11590     {
11591       errmsg ("missing interface name or sw_if_index");
11592       return -99;
11593     }
11594
11595   vam->current_sw_if_index = sw_if_index;
11596   vam->is_ipv6 = ipv6_set;
11597
11598   M (IP_ADDRESS_DUMP, mp);
11599   mp->sw_if_index = ntohl (sw_if_index);
11600   mp->is_ipv6 = ipv6_set;
11601   S (mp);
11602
11603   /* Use a control ping for synchronization */
11604   M (CONTROL_PING, mp_ping);
11605   S (mp_ping);
11606
11607   W (ret);
11608   return ret;
11609 }
11610
11611 static int
11612 api_ip_dump (vat_main_t * vam)
11613 {
11614   vl_api_ip_dump_t *mp;
11615   vl_api_control_ping_t *mp_ping;
11616   unformat_input_t *in = vam->input;
11617   int ipv4_set = 0;
11618   int ipv6_set = 0;
11619   int is_ipv6;
11620   int i;
11621   int ret;
11622
11623   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11624     {
11625       if (unformat (in, "ipv4"))
11626         ipv4_set = 1;
11627       else if (unformat (in, "ipv6"))
11628         ipv6_set = 1;
11629       else
11630         break;
11631     }
11632
11633   if (ipv4_set && ipv6_set)
11634     {
11635       errmsg ("ipv4 and ipv6 flags cannot be both set");
11636       return -99;
11637     }
11638
11639   if ((!ipv4_set) && (!ipv6_set))
11640     {
11641       errmsg ("no ipv4 nor ipv6 flag set");
11642       return -99;
11643     }
11644
11645   is_ipv6 = ipv6_set;
11646   vam->is_ipv6 = is_ipv6;
11647
11648   /* free old data */
11649   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11650     {
11651       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11652     }
11653   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11654
11655   M (IP_DUMP, mp);
11656   mp->is_ipv6 = ipv6_set;
11657   S (mp);
11658
11659   /* Use a control ping for synchronization */
11660   M (CONTROL_PING, mp_ping);
11661   S (mp_ping);
11662
11663   W (ret);
11664   return ret;
11665 }
11666
11667 static int
11668 api_ipsec_spd_add_del (vat_main_t * vam)
11669 {
11670   unformat_input_t *i = vam->input;
11671   vl_api_ipsec_spd_add_del_t *mp;
11672   u32 spd_id = ~0;
11673   u8 is_add = 1;
11674   int ret;
11675
11676   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11677     {
11678       if (unformat (i, "spd_id %d", &spd_id))
11679         ;
11680       else if (unformat (i, "del"))
11681         is_add = 0;
11682       else
11683         {
11684           clib_warning ("parse error '%U'", format_unformat_error, i);
11685           return -99;
11686         }
11687     }
11688   if (spd_id == ~0)
11689     {
11690       errmsg ("spd_id must be set");
11691       return -99;
11692     }
11693
11694   M (IPSEC_SPD_ADD_DEL, mp);
11695
11696   mp->spd_id = ntohl (spd_id);
11697   mp->is_add = is_add;
11698
11699   S (mp);
11700   W (ret);
11701   return ret;
11702 }
11703
11704 static int
11705 api_ipsec_interface_add_del_spd (vat_main_t * vam)
11706 {
11707   unformat_input_t *i = vam->input;
11708   vl_api_ipsec_interface_add_del_spd_t *mp;
11709   u32 sw_if_index;
11710   u8 sw_if_index_set = 0;
11711   u32 spd_id = (u32) ~ 0;
11712   u8 is_add = 1;
11713   int ret;
11714
11715   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11716     {
11717       if (unformat (i, "del"))
11718         is_add = 0;
11719       else if (unformat (i, "spd_id %d", &spd_id))
11720         ;
11721       else
11722         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11723         sw_if_index_set = 1;
11724       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11725         sw_if_index_set = 1;
11726       else
11727         {
11728           clib_warning ("parse error '%U'", format_unformat_error, i);
11729           return -99;
11730         }
11731
11732     }
11733
11734   if (spd_id == (u32) ~ 0)
11735     {
11736       errmsg ("spd_id must be set");
11737       return -99;
11738     }
11739
11740   if (sw_if_index_set == 0)
11741     {
11742       errmsg ("missing interface name or sw_if_index");
11743       return -99;
11744     }
11745
11746   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
11747
11748   mp->spd_id = ntohl (spd_id);
11749   mp->sw_if_index = ntohl (sw_if_index);
11750   mp->is_add = is_add;
11751
11752   S (mp);
11753   W (ret);
11754   return ret;
11755 }
11756
11757 static int
11758 api_ipsec_spd_add_del_entry (vat_main_t * vam)
11759 {
11760   unformat_input_t *i = vam->input;
11761   vl_api_ipsec_spd_add_del_entry_t *mp;
11762   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11763   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11764   i32 priority = 0;
11765   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11766   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11767   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11768   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11769   int ret;
11770
11771   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11772   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11773   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11774   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11775   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11776   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11777
11778   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11779     {
11780       if (unformat (i, "del"))
11781         is_add = 0;
11782       if (unformat (i, "outbound"))
11783         is_outbound = 1;
11784       if (unformat (i, "inbound"))
11785         is_outbound = 0;
11786       else if (unformat (i, "spd_id %d", &spd_id))
11787         ;
11788       else if (unformat (i, "sa_id %d", &sa_id))
11789         ;
11790       else if (unformat (i, "priority %d", &priority))
11791         ;
11792       else if (unformat (i, "protocol %d", &protocol))
11793         ;
11794       else if (unformat (i, "lport_start %d", &lport_start))
11795         ;
11796       else if (unformat (i, "lport_stop %d", &lport_stop))
11797         ;
11798       else if (unformat (i, "rport_start %d", &rport_start))
11799         ;
11800       else if (unformat (i, "rport_stop %d", &rport_stop))
11801         ;
11802       else
11803         if (unformat
11804             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
11805         {
11806           is_ipv6 = 0;
11807           is_ip_any = 0;
11808         }
11809       else
11810         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
11811         {
11812           is_ipv6 = 0;
11813           is_ip_any = 0;
11814         }
11815       else
11816         if (unformat
11817             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
11818         {
11819           is_ipv6 = 0;
11820           is_ip_any = 0;
11821         }
11822       else
11823         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11824         {
11825           is_ipv6 = 0;
11826           is_ip_any = 0;
11827         }
11828       else
11829         if (unformat
11830             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11831         {
11832           is_ipv6 = 1;
11833           is_ip_any = 0;
11834         }
11835       else
11836         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11837         {
11838           is_ipv6 = 1;
11839           is_ip_any = 0;
11840         }
11841       else
11842         if (unformat
11843             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11844         {
11845           is_ipv6 = 1;
11846           is_ip_any = 0;
11847         }
11848       else
11849         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11850         {
11851           is_ipv6 = 1;
11852           is_ip_any = 0;
11853         }
11854       else
11855         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11856         {
11857           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11858             {
11859               clib_warning ("unsupported action: 'resolve'");
11860               return -99;
11861             }
11862         }
11863       else
11864         {
11865           clib_warning ("parse error '%U'", format_unformat_error, i);
11866           return -99;
11867         }
11868
11869     }
11870
11871   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
11872
11873   mp->spd_id = ntohl (spd_id);
11874   mp->priority = ntohl (priority);
11875   mp->is_outbound = is_outbound;
11876
11877   mp->is_ipv6 = is_ipv6;
11878   if (is_ipv6 || is_ip_any)
11879     {
11880       clib_memcpy (mp->remote_address_start, &raddr6_start,
11881                    sizeof (ip6_address_t));
11882       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
11883                    sizeof (ip6_address_t));
11884       clib_memcpy (mp->local_address_start, &laddr6_start,
11885                    sizeof (ip6_address_t));
11886       clib_memcpy (mp->local_address_stop, &laddr6_stop,
11887                    sizeof (ip6_address_t));
11888     }
11889   else
11890     {
11891       clib_memcpy (mp->remote_address_start, &raddr4_start,
11892                    sizeof (ip4_address_t));
11893       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
11894                    sizeof (ip4_address_t));
11895       clib_memcpy (mp->local_address_start, &laddr4_start,
11896                    sizeof (ip4_address_t));
11897       clib_memcpy (mp->local_address_stop, &laddr4_stop,
11898                    sizeof (ip4_address_t));
11899     }
11900   mp->protocol = (u8) protocol;
11901   mp->local_port_start = ntohs ((u16) lport_start);
11902   mp->local_port_stop = ntohs ((u16) lport_stop);
11903   mp->remote_port_start = ntohs ((u16) rport_start);
11904   mp->remote_port_stop = ntohs ((u16) rport_stop);
11905   mp->policy = (u8) policy;
11906   mp->sa_id = ntohl (sa_id);
11907   mp->is_add = is_add;
11908   mp->is_ip_any = is_ip_any;
11909   S (mp);
11910   W (ret);
11911   return ret;
11912 }
11913
11914 static int
11915 api_ipsec_sad_add_del_entry (vat_main_t * vam)
11916 {
11917   unformat_input_t *i = vam->input;
11918   vl_api_ipsec_sad_add_del_entry_t *mp;
11919   u32 sad_id = 0, spi = 0;
11920   u8 *ck = 0, *ik = 0;
11921   u8 is_add = 1;
11922
11923   u8 protocol = IPSEC_PROTOCOL_AH;
11924   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
11925   u32 crypto_alg = 0, integ_alg = 0;
11926   ip4_address_t tun_src4;
11927   ip4_address_t tun_dst4;
11928   ip6_address_t tun_src6;
11929   ip6_address_t tun_dst6;
11930   int ret;
11931
11932   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11933     {
11934       if (unformat (i, "del"))
11935         is_add = 0;
11936       else if (unformat (i, "sad_id %d", &sad_id))
11937         ;
11938       else if (unformat (i, "spi %d", &spi))
11939         ;
11940       else if (unformat (i, "esp"))
11941         protocol = IPSEC_PROTOCOL_ESP;
11942       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
11943         {
11944           is_tunnel = 1;
11945           is_tunnel_ipv6 = 0;
11946         }
11947       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
11948         {
11949           is_tunnel = 1;
11950           is_tunnel_ipv6 = 0;
11951         }
11952       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
11953         {
11954           is_tunnel = 1;
11955           is_tunnel_ipv6 = 1;
11956         }
11957       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
11958         {
11959           is_tunnel = 1;
11960           is_tunnel_ipv6 = 1;
11961         }
11962       else
11963         if (unformat
11964             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
11965         {
11966           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
11967               crypto_alg >= IPSEC_CRYPTO_N_ALG)
11968             {
11969               clib_warning ("unsupported crypto-alg: '%U'",
11970                             format_ipsec_crypto_alg, crypto_alg);
11971               return -99;
11972             }
11973         }
11974       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11975         ;
11976       else
11977         if (unformat
11978             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
11979         {
11980           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
11981               integ_alg >= IPSEC_INTEG_N_ALG)
11982             {
11983               clib_warning ("unsupported integ-alg: '%U'",
11984                             format_ipsec_integ_alg, integ_alg);
11985               return -99;
11986             }
11987         }
11988       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11989         ;
11990       else
11991         {
11992           clib_warning ("parse error '%U'", format_unformat_error, i);
11993           return -99;
11994         }
11995
11996     }
11997
11998   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
11999
12000   mp->sad_id = ntohl (sad_id);
12001   mp->is_add = is_add;
12002   mp->protocol = protocol;
12003   mp->spi = ntohl (spi);
12004   mp->is_tunnel = is_tunnel;
12005   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12006   mp->crypto_algorithm = crypto_alg;
12007   mp->integrity_algorithm = integ_alg;
12008   mp->crypto_key_length = vec_len (ck);
12009   mp->integrity_key_length = vec_len (ik);
12010
12011   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12012     mp->crypto_key_length = sizeof (mp->crypto_key);
12013
12014   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12015     mp->integrity_key_length = sizeof (mp->integrity_key);
12016
12017   if (ck)
12018     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12019   if (ik)
12020     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12021
12022   if (is_tunnel)
12023     {
12024       if (is_tunnel_ipv6)
12025         {
12026           clib_memcpy (mp->tunnel_src_address, &tun_src6,
12027                        sizeof (ip6_address_t));
12028           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12029                        sizeof (ip6_address_t));
12030         }
12031       else
12032         {
12033           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12034                        sizeof (ip4_address_t));
12035           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12036                        sizeof (ip4_address_t));
12037         }
12038     }
12039
12040   S (mp);
12041   W (ret);
12042   return ret;
12043 }
12044
12045 static int
12046 api_ipsec_sa_set_key (vat_main_t * vam)
12047 {
12048   unformat_input_t *i = vam->input;
12049   vl_api_ipsec_sa_set_key_t *mp;
12050   u32 sa_id;
12051   u8 *ck = 0, *ik = 0;
12052   int ret;
12053
12054   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12055     {
12056       if (unformat (i, "sa_id %d", &sa_id))
12057         ;
12058       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12059         ;
12060       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12061         ;
12062       else
12063         {
12064           clib_warning ("parse error '%U'", format_unformat_error, i);
12065           return -99;
12066         }
12067     }
12068
12069   M (IPSEC_SA_SET_KEY, mp);
12070
12071   mp->sa_id = ntohl (sa_id);
12072   mp->crypto_key_length = vec_len (ck);
12073   mp->integrity_key_length = vec_len (ik);
12074
12075   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12076     mp->crypto_key_length = sizeof (mp->crypto_key);
12077
12078   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12079     mp->integrity_key_length = sizeof (mp->integrity_key);
12080
12081   if (ck)
12082     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12083   if (ik)
12084     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12085
12086   S (mp);
12087   W (ret);
12088   return ret;
12089 }
12090
12091 static int
12092 api_ikev2_profile_add_del (vat_main_t * vam)
12093 {
12094   unformat_input_t *i = vam->input;
12095   vl_api_ikev2_profile_add_del_t *mp;
12096   u8 is_add = 1;
12097   u8 *name = 0;
12098   int ret;
12099
12100   const char *valid_chars = "a-zA-Z0-9_";
12101
12102   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12103     {
12104       if (unformat (i, "del"))
12105         is_add = 0;
12106       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12107         vec_add1 (name, 0);
12108       else
12109         {
12110           errmsg ("parse error '%U'", format_unformat_error, i);
12111           return -99;
12112         }
12113     }
12114
12115   if (!vec_len (name))
12116     {
12117       errmsg ("profile name must be specified");
12118       return -99;
12119     }
12120
12121   if (vec_len (name) > 64)
12122     {
12123       errmsg ("profile name too long");
12124       return -99;
12125     }
12126
12127   M (IKEV2_PROFILE_ADD_DEL, mp);
12128
12129   clib_memcpy (mp->name, name, vec_len (name));
12130   mp->is_add = is_add;
12131   vec_free (name);
12132
12133   S (mp);
12134   W (ret);
12135   return ret;
12136 }
12137
12138 static int
12139 api_ikev2_profile_set_auth (vat_main_t * vam)
12140 {
12141   unformat_input_t *i = vam->input;
12142   vl_api_ikev2_profile_set_auth_t *mp;
12143   u8 *name = 0;
12144   u8 *data = 0;
12145   u32 auth_method = 0;
12146   u8 is_hex = 0;
12147   int ret;
12148
12149   const char *valid_chars = "a-zA-Z0-9_";
12150
12151   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12152     {
12153       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12154         vec_add1 (name, 0);
12155       else if (unformat (i, "auth_method %U",
12156                          unformat_ikev2_auth_method, &auth_method))
12157         ;
12158       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12159         is_hex = 1;
12160       else if (unformat (i, "auth_data %v", &data))
12161         ;
12162       else
12163         {
12164           errmsg ("parse error '%U'", format_unformat_error, i);
12165           return -99;
12166         }
12167     }
12168
12169   if (!vec_len (name))
12170     {
12171       errmsg ("profile name must be specified");
12172       return -99;
12173     }
12174
12175   if (vec_len (name) > 64)
12176     {
12177       errmsg ("profile name too long");
12178       return -99;
12179     }
12180
12181   if (!vec_len (data))
12182     {
12183       errmsg ("auth_data must be specified");
12184       return -99;
12185     }
12186
12187   if (!auth_method)
12188     {
12189       errmsg ("auth_method must be specified");
12190       return -99;
12191     }
12192
12193   M (IKEV2_PROFILE_SET_AUTH, mp);
12194
12195   mp->is_hex = is_hex;
12196   mp->auth_method = (u8) auth_method;
12197   mp->data_len = vec_len (data);
12198   clib_memcpy (mp->name, name, vec_len (name));
12199   clib_memcpy (mp->data, data, vec_len (data));
12200   vec_free (name);
12201   vec_free (data);
12202
12203   S (mp);
12204   W (ret);
12205   return ret;
12206 }
12207
12208 static int
12209 api_ikev2_profile_set_id (vat_main_t * vam)
12210 {
12211   unformat_input_t *i = vam->input;
12212   vl_api_ikev2_profile_set_id_t *mp;
12213   u8 *name = 0;
12214   u8 *data = 0;
12215   u8 is_local = 0;
12216   u32 id_type = 0;
12217   ip4_address_t ip4;
12218   int ret;
12219
12220   const char *valid_chars = "a-zA-Z0-9_";
12221
12222   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12223     {
12224       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12225         vec_add1 (name, 0);
12226       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12227         ;
12228       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12229         {
12230           data = vec_new (u8, 4);
12231           clib_memcpy (data, ip4.as_u8, 4);
12232         }
12233       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12234         ;
12235       else if (unformat (i, "id_data %v", &data))
12236         ;
12237       else if (unformat (i, "local"))
12238         is_local = 1;
12239       else if (unformat (i, "remote"))
12240         is_local = 0;
12241       else
12242         {
12243           errmsg ("parse error '%U'", format_unformat_error, i);
12244           return -99;
12245         }
12246     }
12247
12248   if (!vec_len (name))
12249     {
12250       errmsg ("profile name must be specified");
12251       return -99;
12252     }
12253
12254   if (vec_len (name) > 64)
12255     {
12256       errmsg ("profile name too long");
12257       return -99;
12258     }
12259
12260   if (!vec_len (data))
12261     {
12262       errmsg ("id_data must be specified");
12263       return -99;
12264     }
12265
12266   if (!id_type)
12267     {
12268       errmsg ("id_type must be specified");
12269       return -99;
12270     }
12271
12272   M (IKEV2_PROFILE_SET_ID, mp);
12273
12274   mp->is_local = is_local;
12275   mp->id_type = (u8) id_type;
12276   mp->data_len = vec_len (data);
12277   clib_memcpy (mp->name, name, vec_len (name));
12278   clib_memcpy (mp->data, data, vec_len (data));
12279   vec_free (name);
12280   vec_free (data);
12281
12282   S (mp);
12283   W (ret);
12284   return ret;
12285 }
12286
12287 static int
12288 api_ikev2_profile_set_ts (vat_main_t * vam)
12289 {
12290   unformat_input_t *i = vam->input;
12291   vl_api_ikev2_profile_set_ts_t *mp;
12292   u8 *name = 0;
12293   u8 is_local = 0;
12294   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12295   ip4_address_t start_addr, end_addr;
12296
12297   const char *valid_chars = "a-zA-Z0-9_";
12298   int ret;
12299
12300   start_addr.as_u32 = 0;
12301   end_addr.as_u32 = (u32) ~ 0;
12302
12303   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12304     {
12305       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12306         vec_add1 (name, 0);
12307       else if (unformat (i, "protocol %d", &proto))
12308         ;
12309       else if (unformat (i, "start_port %d", &start_port))
12310         ;
12311       else if (unformat (i, "end_port %d", &end_port))
12312         ;
12313       else
12314         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12315         ;
12316       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12317         ;
12318       else if (unformat (i, "local"))
12319         is_local = 1;
12320       else if (unformat (i, "remote"))
12321         is_local = 0;
12322       else
12323         {
12324           errmsg ("parse error '%U'", format_unformat_error, i);
12325           return -99;
12326         }
12327     }
12328
12329   if (!vec_len (name))
12330     {
12331       errmsg ("profile name must be specified");
12332       return -99;
12333     }
12334
12335   if (vec_len (name) > 64)
12336     {
12337       errmsg ("profile name too long");
12338       return -99;
12339     }
12340
12341   M (IKEV2_PROFILE_SET_TS, mp);
12342
12343   mp->is_local = is_local;
12344   mp->proto = (u8) proto;
12345   mp->start_port = (u16) start_port;
12346   mp->end_port = (u16) end_port;
12347   mp->start_addr = start_addr.as_u32;
12348   mp->end_addr = end_addr.as_u32;
12349   clib_memcpy (mp->name, name, vec_len (name));
12350   vec_free (name);
12351
12352   S (mp);
12353   W (ret);
12354   return ret;
12355 }
12356
12357 static int
12358 api_ikev2_set_local_key (vat_main_t * vam)
12359 {
12360   unformat_input_t *i = vam->input;
12361   vl_api_ikev2_set_local_key_t *mp;
12362   u8 *file = 0;
12363   int ret;
12364
12365   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12366     {
12367       if (unformat (i, "file %v", &file))
12368         vec_add1 (file, 0);
12369       else
12370         {
12371           errmsg ("parse error '%U'", format_unformat_error, i);
12372           return -99;
12373         }
12374     }
12375
12376   if (!vec_len (file))
12377     {
12378       errmsg ("RSA key file must be specified");
12379       return -99;
12380     }
12381
12382   if (vec_len (file) > 256)
12383     {
12384       errmsg ("file name too long");
12385       return -99;
12386     }
12387
12388   M (IKEV2_SET_LOCAL_KEY, mp);
12389
12390   clib_memcpy (mp->key_file, file, vec_len (file));
12391   vec_free (file);
12392
12393   S (mp);
12394   W (ret);
12395   return ret;
12396 }
12397
12398 static int
12399 api_ikev2_set_responder (vat_main_t * vam)
12400 {
12401   unformat_input_t *i = vam->input;
12402   vl_api_ikev2_set_responder_t *mp;
12403   int ret;
12404   u8 *name = 0;
12405   u32 sw_if_index = ~0;
12406   ip4_address_t address;
12407
12408   const char *valid_chars = "a-zA-Z0-9_";
12409
12410   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12411     {
12412       if (unformat
12413           (i, "%U interface %d address %U", unformat_token, valid_chars,
12414            &name, &sw_if_index, unformat_ip4_address, &address))
12415         vec_add1 (name, 0);
12416       else
12417         {
12418           errmsg ("parse error '%U'", format_unformat_error, i);
12419           return -99;
12420         }
12421     }
12422
12423   if (!vec_len (name))
12424     {
12425       errmsg ("profile name must be specified");
12426       return -99;
12427     }
12428
12429   if (vec_len (name) > 64)
12430     {
12431       errmsg ("profile name too long");
12432       return -99;
12433     }
12434
12435   M (IKEV2_SET_RESPONDER, mp);
12436
12437   clib_memcpy (mp->name, name, vec_len (name));
12438   vec_free (name);
12439
12440   mp->sw_if_index = sw_if_index;
12441   clib_memcpy (mp->address, &address, sizeof (address));
12442
12443   S (mp);
12444   W (ret);
12445   return ret;
12446 }
12447
12448 static int
12449 api_ikev2_set_ike_transforms (vat_main_t * vam)
12450 {
12451   unformat_input_t *i = vam->input;
12452   vl_api_ikev2_set_ike_transforms_t *mp;
12453   int ret;
12454   u8 *name = 0;
12455   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
12456
12457   const char *valid_chars = "a-zA-Z0-9_";
12458
12459   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12460     {
12461       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
12462                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
12463         vec_add1 (name, 0);
12464       else
12465         {
12466           errmsg ("parse error '%U'", format_unformat_error, i);
12467           return -99;
12468         }
12469     }
12470
12471   if (!vec_len (name))
12472     {
12473       errmsg ("profile name must be specified");
12474       return -99;
12475     }
12476
12477   if (vec_len (name) > 64)
12478     {
12479       errmsg ("profile name too long");
12480       return -99;
12481     }
12482
12483   M (IKEV2_SET_IKE_TRANSFORMS, mp);
12484
12485   clib_memcpy (mp->name, name, vec_len (name));
12486   vec_free (name);
12487   mp->crypto_alg = crypto_alg;
12488   mp->crypto_key_size = crypto_key_size;
12489   mp->integ_alg = integ_alg;
12490   mp->dh_group = dh_group;
12491
12492   S (mp);
12493   W (ret);
12494   return ret;
12495 }
12496
12497
12498 static int
12499 api_ikev2_set_esp_transforms (vat_main_t * vam)
12500 {
12501   unformat_input_t *i = vam->input;
12502   vl_api_ikev2_set_esp_transforms_t *mp;
12503   int ret;
12504   u8 *name = 0;
12505   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
12506
12507   const char *valid_chars = "a-zA-Z0-9_";
12508
12509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12510     {
12511       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
12512                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
12513         vec_add1 (name, 0);
12514       else
12515         {
12516           errmsg ("parse error '%U'", format_unformat_error, i);
12517           return -99;
12518         }
12519     }
12520
12521   if (!vec_len (name))
12522     {
12523       errmsg ("profile name must be specified");
12524       return -99;
12525     }
12526
12527   if (vec_len (name) > 64)
12528     {
12529       errmsg ("profile name too long");
12530       return -99;
12531     }
12532
12533   M (IKEV2_SET_ESP_TRANSFORMS, mp);
12534
12535   clib_memcpy (mp->name, name, vec_len (name));
12536   vec_free (name);
12537   mp->crypto_alg = crypto_alg;
12538   mp->crypto_key_size = crypto_key_size;
12539   mp->integ_alg = integ_alg;
12540   mp->dh_group = dh_group;
12541
12542   S (mp);
12543   W (ret);
12544   return ret;
12545 }
12546
12547 static int
12548 api_ikev2_set_sa_lifetime (vat_main_t * vam)
12549 {
12550   unformat_input_t *i = vam->input;
12551   vl_api_ikev2_set_sa_lifetime_t *mp;
12552   int ret;
12553   u8 *name = 0;
12554   u64 lifetime, lifetime_maxdata;
12555   u32 lifetime_jitter, handover;
12556
12557   const char *valid_chars = "a-zA-Z0-9_";
12558
12559   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12560     {
12561       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
12562                     &lifetime, &lifetime_jitter, &handover,
12563                     &lifetime_maxdata))
12564         vec_add1 (name, 0);
12565       else
12566         {
12567           errmsg ("parse error '%U'", format_unformat_error, i);
12568           return -99;
12569         }
12570     }
12571
12572   if (!vec_len (name))
12573     {
12574       errmsg ("profile name must be specified");
12575       return -99;
12576     }
12577
12578   if (vec_len (name) > 64)
12579     {
12580       errmsg ("profile name too long");
12581       return -99;
12582     }
12583
12584   M (IKEV2_SET_SA_LIFETIME, mp);
12585
12586   clib_memcpy (mp->name, name, vec_len (name));
12587   vec_free (name);
12588   mp->lifetime = lifetime;
12589   mp->lifetime_jitter = lifetime_jitter;
12590   mp->handover = handover;
12591   mp->lifetime_maxdata = lifetime_maxdata;
12592
12593   S (mp);
12594   W (ret);
12595   return ret;
12596 }
12597
12598 static int
12599 api_ikev2_initiate_sa_init (vat_main_t * vam)
12600 {
12601   unformat_input_t *i = vam->input;
12602   vl_api_ikev2_initiate_sa_init_t *mp;
12603   int ret;
12604   u8 *name = 0;
12605
12606   const char *valid_chars = "a-zA-Z0-9_";
12607
12608   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12609     {
12610       if (unformat (i, "%U", unformat_token, valid_chars, &name))
12611         vec_add1 (name, 0);
12612       else
12613         {
12614           errmsg ("parse error '%U'", format_unformat_error, i);
12615           return -99;
12616         }
12617     }
12618
12619   if (!vec_len (name))
12620     {
12621       errmsg ("profile name must be specified");
12622       return -99;
12623     }
12624
12625   if (vec_len (name) > 64)
12626     {
12627       errmsg ("profile name too long");
12628       return -99;
12629     }
12630
12631   M (IKEV2_INITIATE_SA_INIT, mp);
12632
12633   clib_memcpy (mp->name, name, vec_len (name));
12634   vec_free (name);
12635
12636   S (mp);
12637   W (ret);
12638   return ret;
12639 }
12640
12641 static int
12642 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
12643 {
12644   unformat_input_t *i = vam->input;
12645   vl_api_ikev2_initiate_del_ike_sa_t *mp;
12646   int ret;
12647   u64 ispi;
12648
12649
12650   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12651     {
12652       if (unformat (i, "%lx", &ispi))
12653         ;
12654       else
12655         {
12656           errmsg ("parse error '%U'", format_unformat_error, i);
12657           return -99;
12658         }
12659     }
12660
12661   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
12662
12663   mp->ispi = ispi;
12664
12665   S (mp);
12666   W (ret);
12667   return ret;
12668 }
12669
12670 static int
12671 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
12672 {
12673   unformat_input_t *i = vam->input;
12674   vl_api_ikev2_initiate_del_child_sa_t *mp;
12675   int ret;
12676   u32 ispi;
12677
12678
12679   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12680     {
12681       if (unformat (i, "%x", &ispi))
12682         ;
12683       else
12684         {
12685           errmsg ("parse error '%U'", format_unformat_error, i);
12686           return -99;
12687         }
12688     }
12689
12690   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
12691
12692   mp->ispi = ispi;
12693
12694   S (mp);
12695   W (ret);
12696   return ret;
12697 }
12698
12699 static int
12700 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
12701 {
12702   unformat_input_t *i = vam->input;
12703   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
12704   int ret;
12705   u32 ispi;
12706
12707
12708   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12709     {
12710       if (unformat (i, "%x", &ispi))
12711         ;
12712       else
12713         {
12714           errmsg ("parse error '%U'", format_unformat_error, i);
12715           return -99;
12716         }
12717     }
12718
12719   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
12720
12721   mp->ispi = ispi;
12722
12723   S (mp);
12724   W (ret);
12725   return ret;
12726 }
12727
12728 /*
12729  * MAP
12730  */
12731 static int
12732 api_map_add_domain (vat_main_t * vam)
12733 {
12734   unformat_input_t *i = vam->input;
12735   vl_api_map_add_domain_t *mp;
12736
12737   ip4_address_t ip4_prefix;
12738   ip6_address_t ip6_prefix;
12739   ip6_address_t ip6_src;
12740   u32 num_m_args = 0;
12741   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12742     0, psid_length = 0;
12743   u8 is_translation = 0;
12744   u32 mtu = 0;
12745   u32 ip6_src_len = 128;
12746   int ret;
12747
12748   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12749     {
12750       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12751                     &ip4_prefix, &ip4_prefix_len))
12752         num_m_args++;
12753       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12754                          &ip6_prefix, &ip6_prefix_len))
12755         num_m_args++;
12756       else
12757         if (unformat
12758             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12759              &ip6_src_len))
12760         num_m_args++;
12761       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12762         num_m_args++;
12763       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12764         num_m_args++;
12765       else if (unformat (i, "psid-offset %d", &psid_offset))
12766         num_m_args++;
12767       else if (unformat (i, "psid-len %d", &psid_length))
12768         num_m_args++;
12769       else if (unformat (i, "mtu %d", &mtu))
12770         num_m_args++;
12771       else if (unformat (i, "map-t"))
12772         is_translation = 1;
12773       else
12774         {
12775           clib_warning ("parse error '%U'", format_unformat_error, i);
12776           return -99;
12777         }
12778     }
12779
12780   if (num_m_args < 3)
12781     {
12782       errmsg ("mandatory argument(s) missing");
12783       return -99;
12784     }
12785
12786   /* Construct the API message */
12787   M (MAP_ADD_DOMAIN, mp);
12788
12789   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12790   mp->ip4_prefix_len = ip4_prefix_len;
12791
12792   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12793   mp->ip6_prefix_len = ip6_prefix_len;
12794
12795   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12796   mp->ip6_src_prefix_len = ip6_src_len;
12797
12798   mp->ea_bits_len = ea_bits_len;
12799   mp->psid_offset = psid_offset;
12800   mp->psid_length = psid_length;
12801   mp->is_translation = is_translation;
12802   mp->mtu = htons (mtu);
12803
12804   /* send it... */
12805   S (mp);
12806
12807   /* Wait for a reply, return good/bad news  */
12808   W (ret);
12809   return ret;
12810 }
12811
12812 static int
12813 api_map_del_domain (vat_main_t * vam)
12814 {
12815   unformat_input_t *i = vam->input;
12816   vl_api_map_del_domain_t *mp;
12817
12818   u32 num_m_args = 0;
12819   u32 index;
12820   int ret;
12821
12822   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12823     {
12824       if (unformat (i, "index %d", &index))
12825         num_m_args++;
12826       else
12827         {
12828           clib_warning ("parse error '%U'", format_unformat_error, i);
12829           return -99;
12830         }
12831     }
12832
12833   if (num_m_args != 1)
12834     {
12835       errmsg ("mandatory argument(s) missing");
12836       return -99;
12837     }
12838
12839   /* Construct the API message */
12840   M (MAP_DEL_DOMAIN, mp);
12841
12842   mp->index = ntohl (index);
12843
12844   /* send it... */
12845   S (mp);
12846
12847   /* Wait for a reply, return good/bad news  */
12848   W (ret);
12849   return ret;
12850 }
12851
12852 static int
12853 api_map_add_del_rule (vat_main_t * vam)
12854 {
12855   unformat_input_t *i = vam->input;
12856   vl_api_map_add_del_rule_t *mp;
12857   u8 is_add = 1;
12858   ip6_address_t ip6_dst;
12859   u32 num_m_args = 0, index, psid = 0;
12860   int ret;
12861
12862   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12863     {
12864       if (unformat (i, "index %d", &index))
12865         num_m_args++;
12866       else if (unformat (i, "psid %d", &psid))
12867         num_m_args++;
12868       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12869         num_m_args++;
12870       else if (unformat (i, "del"))
12871         {
12872           is_add = 0;
12873         }
12874       else
12875         {
12876           clib_warning ("parse error '%U'", format_unformat_error, i);
12877           return -99;
12878         }
12879     }
12880
12881   /* Construct the API message */
12882   M (MAP_ADD_DEL_RULE, mp);
12883
12884   mp->index = ntohl (index);
12885   mp->is_add = is_add;
12886   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12887   mp->psid = ntohs (psid);
12888
12889   /* send it... */
12890   S (mp);
12891
12892   /* Wait for a reply, return good/bad news  */
12893   W (ret);
12894   return ret;
12895 }
12896
12897 static int
12898 api_map_domain_dump (vat_main_t * vam)
12899 {
12900   vl_api_map_domain_dump_t *mp;
12901   vl_api_control_ping_t *mp_ping;
12902   int ret;
12903
12904   /* Construct the API message */
12905   M (MAP_DOMAIN_DUMP, mp);
12906
12907   /* send it... */
12908   S (mp);
12909
12910   /* Use a control ping for synchronization */
12911   M (CONTROL_PING, mp_ping);
12912   S (mp_ping);
12913
12914   W (ret);
12915   return ret;
12916 }
12917
12918 static int
12919 api_map_rule_dump (vat_main_t * vam)
12920 {
12921   unformat_input_t *i = vam->input;
12922   vl_api_map_rule_dump_t *mp;
12923   vl_api_control_ping_t *mp_ping;
12924   u32 domain_index = ~0;
12925   int ret;
12926
12927   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12928     {
12929       if (unformat (i, "index %u", &domain_index))
12930         ;
12931       else
12932         break;
12933     }
12934
12935   if (domain_index == ~0)
12936     {
12937       clib_warning ("parse error: domain index expected");
12938       return -99;
12939     }
12940
12941   /* Construct the API message */
12942   M (MAP_RULE_DUMP, mp);
12943
12944   mp->domain_index = htonl (domain_index);
12945
12946   /* send it... */
12947   S (mp);
12948
12949   /* Use a control ping for synchronization */
12950   M (CONTROL_PING, mp_ping);
12951   S (mp_ping);
12952
12953   W (ret);
12954   return ret;
12955 }
12956
12957 static void vl_api_map_add_domain_reply_t_handler
12958   (vl_api_map_add_domain_reply_t * mp)
12959 {
12960   vat_main_t *vam = &vat_main;
12961   i32 retval = ntohl (mp->retval);
12962
12963   if (vam->async_mode)
12964     {
12965       vam->async_errors += (retval < 0);
12966     }
12967   else
12968     {
12969       vam->retval = retval;
12970       vam->result_ready = 1;
12971     }
12972 }
12973
12974 static void vl_api_map_add_domain_reply_t_handler_json
12975   (vl_api_map_add_domain_reply_t * mp)
12976 {
12977   vat_main_t *vam = &vat_main;
12978   vat_json_node_t node;
12979
12980   vat_json_init_object (&node);
12981   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
12982   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
12983
12984   vat_json_print (vam->ofp, &node);
12985   vat_json_free (&node);
12986
12987   vam->retval = ntohl (mp->retval);
12988   vam->result_ready = 1;
12989 }
12990
12991 static int
12992 api_get_first_msg_id (vat_main_t * vam)
12993 {
12994   vl_api_get_first_msg_id_t *mp;
12995   unformat_input_t *i = vam->input;
12996   u8 *name;
12997   u8 name_set = 0;
12998   int ret;
12999
13000   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13001     {
13002       if (unformat (i, "client %s", &name))
13003         name_set = 1;
13004       else
13005         break;
13006     }
13007
13008   if (name_set == 0)
13009     {
13010       errmsg ("missing client name");
13011       return -99;
13012     }
13013   vec_add1 (name, 0);
13014
13015   if (vec_len (name) > 63)
13016     {
13017       errmsg ("client name too long");
13018       return -99;
13019     }
13020
13021   M (GET_FIRST_MSG_ID, mp);
13022   clib_memcpy (mp->name, name, vec_len (name));
13023   S (mp);
13024   W (ret);
13025   return ret;
13026 }
13027
13028 static int
13029 api_cop_interface_enable_disable (vat_main_t * vam)
13030 {
13031   unformat_input_t *line_input = vam->input;
13032   vl_api_cop_interface_enable_disable_t *mp;
13033   u32 sw_if_index = ~0;
13034   u8 enable_disable = 1;
13035   int ret;
13036
13037   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13038     {
13039       if (unformat (line_input, "disable"))
13040         enable_disable = 0;
13041       if (unformat (line_input, "enable"))
13042         enable_disable = 1;
13043       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13044                          vam, &sw_if_index))
13045         ;
13046       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13047         ;
13048       else
13049         break;
13050     }
13051
13052   if (sw_if_index == ~0)
13053     {
13054       errmsg ("missing interface name or sw_if_index");
13055       return -99;
13056     }
13057
13058   /* Construct the API message */
13059   M (COP_INTERFACE_ENABLE_DISABLE, mp);
13060   mp->sw_if_index = ntohl (sw_if_index);
13061   mp->enable_disable = enable_disable;
13062
13063   /* send it... */
13064   S (mp);
13065   /* Wait for the reply */
13066   W (ret);
13067   return ret;
13068 }
13069
13070 static int
13071 api_cop_whitelist_enable_disable (vat_main_t * vam)
13072 {
13073   unformat_input_t *line_input = vam->input;
13074   vl_api_cop_whitelist_enable_disable_t *mp;
13075   u32 sw_if_index = ~0;
13076   u8 ip4 = 0, ip6 = 0, default_cop = 0;
13077   u32 fib_id = 0;
13078   int ret;
13079
13080   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13081     {
13082       if (unformat (line_input, "ip4"))
13083         ip4 = 1;
13084       else if (unformat (line_input, "ip6"))
13085         ip6 = 1;
13086       else if (unformat (line_input, "default"))
13087         default_cop = 1;
13088       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13089                          vam, &sw_if_index))
13090         ;
13091       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13092         ;
13093       else if (unformat (line_input, "fib-id %d", &fib_id))
13094         ;
13095       else
13096         break;
13097     }
13098
13099   if (sw_if_index == ~0)
13100     {
13101       errmsg ("missing interface name or sw_if_index");
13102       return -99;
13103     }
13104
13105   /* Construct the API message */
13106   M (COP_WHITELIST_ENABLE_DISABLE, mp);
13107   mp->sw_if_index = ntohl (sw_if_index);
13108   mp->fib_id = ntohl (fib_id);
13109   mp->ip4 = ip4;
13110   mp->ip6 = ip6;
13111   mp->default_cop = default_cop;
13112
13113   /* send it... */
13114   S (mp);
13115   /* Wait for the reply */
13116   W (ret);
13117   return ret;
13118 }
13119
13120 static int
13121 api_get_node_graph (vat_main_t * vam)
13122 {
13123   vl_api_get_node_graph_t *mp;
13124   int ret;
13125
13126   M (GET_NODE_GRAPH, mp);
13127
13128   /* send it... */
13129   S (mp);
13130   /* Wait for the reply */
13131   W (ret);
13132   return ret;
13133 }
13134
13135 /* *INDENT-OFF* */
13136 /** Used for parsing LISP eids */
13137 typedef CLIB_PACKED(struct{
13138   u8 addr[16];   /**< eid address */
13139   u32 len;       /**< prefix length if IP */
13140   u8 type;      /**< type of eid */
13141 }) lisp_eid_vat_t;
13142 /* *INDENT-ON* */
13143
13144 static uword
13145 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
13146 {
13147   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
13148
13149   memset (a, 0, sizeof (a[0]));
13150
13151   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
13152     {
13153       a->type = 0;              /* ipv4 type */
13154     }
13155   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
13156     {
13157       a->type = 1;              /* ipv6 type */
13158     }
13159   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
13160     {
13161       a->type = 2;              /* mac type */
13162     }
13163   else
13164     {
13165       return 0;
13166     }
13167
13168   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
13169     {
13170       return 0;
13171     }
13172
13173   return 1;
13174 }
13175
13176 static int
13177 lisp_eid_size_vat (u8 type)
13178 {
13179   switch (type)
13180     {
13181     case 0:
13182       return 4;
13183     case 1:
13184       return 16;
13185     case 2:
13186       return 6;
13187     }
13188   return 0;
13189 }
13190
13191 static void
13192 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
13193 {
13194   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
13195 }
13196
13197 static int
13198 api_one_add_del_locator_set (vat_main_t * vam)
13199 {
13200   unformat_input_t *input = vam->input;
13201   vl_api_one_add_del_locator_set_t *mp;
13202   u8 is_add = 1;
13203   u8 *locator_set_name = NULL;
13204   u8 locator_set_name_set = 0;
13205   vl_api_local_locator_t locator, *locators = 0;
13206   u32 sw_if_index, priority, weight;
13207   u32 data_len = 0;
13208
13209   int ret;
13210   /* Parse args required to build the message */
13211   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13212     {
13213       if (unformat (input, "del"))
13214         {
13215           is_add = 0;
13216         }
13217       else if (unformat (input, "locator-set %s", &locator_set_name))
13218         {
13219           locator_set_name_set = 1;
13220         }
13221       else if (unformat (input, "sw_if_index %u p %u w %u",
13222                          &sw_if_index, &priority, &weight))
13223         {
13224           locator.sw_if_index = htonl (sw_if_index);
13225           locator.priority = priority;
13226           locator.weight = weight;
13227           vec_add1 (locators, locator);
13228         }
13229       else
13230         if (unformat
13231             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
13232              &sw_if_index, &priority, &weight))
13233         {
13234           locator.sw_if_index = htonl (sw_if_index);
13235           locator.priority = priority;
13236           locator.weight = weight;
13237           vec_add1 (locators, locator);
13238         }
13239       else
13240         break;
13241     }
13242
13243   if (locator_set_name_set == 0)
13244     {
13245       errmsg ("missing locator-set name");
13246       vec_free (locators);
13247       return -99;
13248     }
13249
13250   if (vec_len (locator_set_name) > 64)
13251     {
13252       errmsg ("locator-set name too long");
13253       vec_free (locator_set_name);
13254       vec_free (locators);
13255       return -99;
13256     }
13257   vec_add1 (locator_set_name, 0);
13258
13259   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
13260
13261   /* Construct the API message */
13262   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
13263
13264   mp->is_add = is_add;
13265   clib_memcpy (mp->locator_set_name, locator_set_name,
13266                vec_len (locator_set_name));
13267   vec_free (locator_set_name);
13268
13269   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
13270   if (locators)
13271     clib_memcpy (mp->locators, locators, data_len);
13272   vec_free (locators);
13273
13274   /* send it... */
13275   S (mp);
13276
13277   /* Wait for a reply... */
13278   W (ret);
13279   return ret;
13280 }
13281
13282 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
13283
13284 static int
13285 api_one_add_del_locator (vat_main_t * vam)
13286 {
13287   unformat_input_t *input = vam->input;
13288   vl_api_one_add_del_locator_t *mp;
13289   u32 tmp_if_index = ~0;
13290   u32 sw_if_index = ~0;
13291   u8 sw_if_index_set = 0;
13292   u8 sw_if_index_if_name_set = 0;
13293   u32 priority = ~0;
13294   u8 priority_set = 0;
13295   u32 weight = ~0;
13296   u8 weight_set = 0;
13297   u8 is_add = 1;
13298   u8 *locator_set_name = NULL;
13299   u8 locator_set_name_set = 0;
13300   int ret;
13301
13302   /* Parse args required to build the message */
13303   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13304     {
13305       if (unformat (input, "del"))
13306         {
13307           is_add = 0;
13308         }
13309       else if (unformat (input, "locator-set %s", &locator_set_name))
13310         {
13311           locator_set_name_set = 1;
13312         }
13313       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
13314                          &tmp_if_index))
13315         {
13316           sw_if_index_if_name_set = 1;
13317           sw_if_index = tmp_if_index;
13318         }
13319       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
13320         {
13321           sw_if_index_set = 1;
13322           sw_if_index = tmp_if_index;
13323         }
13324       else if (unformat (input, "p %d", &priority))
13325         {
13326           priority_set = 1;
13327         }
13328       else if (unformat (input, "w %d", &weight))
13329         {
13330           weight_set = 1;
13331         }
13332       else
13333         break;
13334     }
13335
13336   if (locator_set_name_set == 0)
13337     {
13338       errmsg ("missing locator-set name");
13339       return -99;
13340     }
13341
13342   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
13343     {
13344       errmsg ("missing sw_if_index");
13345       vec_free (locator_set_name);
13346       return -99;
13347     }
13348
13349   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
13350     {
13351       errmsg ("cannot use both params interface name and sw_if_index");
13352       vec_free (locator_set_name);
13353       return -99;
13354     }
13355
13356   if (priority_set == 0)
13357     {
13358       errmsg ("missing locator-set priority");
13359       vec_free (locator_set_name);
13360       return -99;
13361     }
13362
13363   if (weight_set == 0)
13364     {
13365       errmsg ("missing locator-set weight");
13366       vec_free (locator_set_name);
13367       return -99;
13368     }
13369
13370   if (vec_len (locator_set_name) > 64)
13371     {
13372       errmsg ("locator-set name too long");
13373       vec_free (locator_set_name);
13374       return -99;
13375     }
13376   vec_add1 (locator_set_name, 0);
13377
13378   /* Construct the API message */
13379   M (ONE_ADD_DEL_LOCATOR, mp);
13380
13381   mp->is_add = is_add;
13382   mp->sw_if_index = ntohl (sw_if_index);
13383   mp->priority = priority;
13384   mp->weight = weight;
13385   clib_memcpy (mp->locator_set_name, locator_set_name,
13386                vec_len (locator_set_name));
13387   vec_free (locator_set_name);
13388
13389   /* send it... */
13390   S (mp);
13391
13392   /* Wait for a reply... */
13393   W (ret);
13394   return ret;
13395 }
13396
13397 #define api_lisp_add_del_locator api_one_add_del_locator
13398
13399 uword
13400 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
13401 {
13402   u32 *key_id = va_arg (*args, u32 *);
13403   u8 *s = 0;
13404
13405   if (unformat (input, "%s", &s))
13406     {
13407       if (!strcmp ((char *) s, "sha1"))
13408         key_id[0] = HMAC_SHA_1_96;
13409       else if (!strcmp ((char *) s, "sha256"))
13410         key_id[0] = HMAC_SHA_256_128;
13411       else
13412         {
13413           clib_warning ("invalid key_id: '%s'", s);
13414           key_id[0] = HMAC_NO_KEY;
13415         }
13416     }
13417   else
13418     return 0;
13419
13420   vec_free (s);
13421   return 1;
13422 }
13423
13424 static int
13425 api_one_add_del_local_eid (vat_main_t * vam)
13426 {
13427   unformat_input_t *input = vam->input;
13428   vl_api_one_add_del_local_eid_t *mp;
13429   u8 is_add = 1;
13430   u8 eid_set = 0;
13431   lisp_eid_vat_t _eid, *eid = &_eid;
13432   u8 *locator_set_name = 0;
13433   u8 locator_set_name_set = 0;
13434   u32 vni = 0;
13435   u16 key_id = 0;
13436   u8 *key = 0;
13437   int ret;
13438
13439   /* Parse args required to build the message */
13440   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13441     {
13442       if (unformat (input, "del"))
13443         {
13444           is_add = 0;
13445         }
13446       else if (unformat (input, "vni %d", &vni))
13447         {
13448           ;
13449         }
13450       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13451         {
13452           eid_set = 1;
13453         }
13454       else if (unformat (input, "locator-set %s", &locator_set_name))
13455         {
13456           locator_set_name_set = 1;
13457         }
13458       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
13459         ;
13460       else if (unformat (input, "secret-key %_%v%_", &key))
13461         ;
13462       else
13463         break;
13464     }
13465
13466   if (locator_set_name_set == 0)
13467     {
13468       errmsg ("missing locator-set name");
13469       return -99;
13470     }
13471
13472   if (0 == eid_set)
13473     {
13474       errmsg ("EID address not set!");
13475       vec_free (locator_set_name);
13476       return -99;
13477     }
13478
13479   if (key && (0 == key_id))
13480     {
13481       errmsg ("invalid key_id!");
13482       return -99;
13483     }
13484
13485   if (vec_len (key) > 64)
13486     {
13487       errmsg ("key too long");
13488       vec_free (key);
13489       return -99;
13490     }
13491
13492   if (vec_len (locator_set_name) > 64)
13493     {
13494       errmsg ("locator-set name too long");
13495       vec_free (locator_set_name);
13496       return -99;
13497     }
13498   vec_add1 (locator_set_name, 0);
13499
13500   /* Construct the API message */
13501   M (ONE_ADD_DEL_LOCAL_EID, mp);
13502
13503   mp->is_add = is_add;
13504   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13505   mp->eid_type = eid->type;
13506   mp->prefix_len = eid->len;
13507   mp->vni = clib_host_to_net_u32 (vni);
13508   mp->key_id = clib_host_to_net_u16 (key_id);
13509   clib_memcpy (mp->locator_set_name, locator_set_name,
13510                vec_len (locator_set_name));
13511   clib_memcpy (mp->key, key, vec_len (key));
13512
13513   vec_free (locator_set_name);
13514   vec_free (key);
13515
13516   /* send it... */
13517   S (mp);
13518
13519   /* Wait for a reply... */
13520   W (ret);
13521   return ret;
13522 }
13523
13524 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
13525
13526 static int
13527 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
13528 {
13529   u32 dp_table = 0, vni = 0;;
13530   unformat_input_t *input = vam->input;
13531   vl_api_gpe_add_del_fwd_entry_t *mp;
13532   u8 is_add = 1;
13533   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
13534   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
13535   u8 rmt_eid_set = 0, lcl_eid_set = 0;
13536   u32 action = ~0, w;
13537   ip4_address_t rmt_rloc4, lcl_rloc4;
13538   ip6_address_t rmt_rloc6, lcl_rloc6;
13539   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
13540   int ret;
13541
13542   memset (&rloc, 0, sizeof (rloc));
13543
13544   /* Parse args required to build the message */
13545   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13546     {
13547       if (unformat (input, "del"))
13548         is_add = 0;
13549       else if (unformat (input, "add"))
13550         is_add = 1;
13551       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
13552         {
13553           rmt_eid_set = 1;
13554         }
13555       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
13556         {
13557           lcl_eid_set = 1;
13558         }
13559       else if (unformat (input, "vrf %d", &dp_table))
13560         ;
13561       else if (unformat (input, "bd %d", &dp_table))
13562         ;
13563       else if (unformat (input, "vni %d", &vni))
13564         ;
13565       else if (unformat (input, "w %d", &w))
13566         {
13567           if (!curr_rloc)
13568             {
13569               errmsg ("No RLOC configured for setting priority/weight!");
13570               return -99;
13571             }
13572           curr_rloc->weight = w;
13573         }
13574       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
13575                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
13576         {
13577           rloc.is_ip4 = 1;
13578
13579           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
13580           rloc.weight = 0;
13581           vec_add1 (lcl_locs, rloc);
13582
13583           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
13584           vec_add1 (rmt_locs, rloc);
13585           /* weight saved in rmt loc */
13586           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13587         }
13588       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
13589                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
13590         {
13591           rloc.is_ip4 = 0;
13592           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
13593           rloc.weight = 0;
13594           vec_add1 (lcl_locs, rloc);
13595
13596           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13597           vec_add1 (rmt_locs, rloc);
13598           /* weight saved in rmt loc */
13599           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13600         }
13601       else if (unformat (input, "action %d", &action))
13602         {
13603           ;
13604         }
13605       else
13606         {
13607           clib_warning ("parse error '%U'", format_unformat_error, input);
13608           return -99;
13609         }
13610     }
13611
13612   if (!rmt_eid_set)
13613     {
13614       errmsg ("remote eid addresses not set");
13615       return -99;
13616     }
13617
13618   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13619     {
13620       errmsg ("eid types don't match");
13621       return -99;
13622     }
13623
13624   if (0 == rmt_locs && (u32) ~ 0 == action)
13625     {
13626       errmsg ("action not set for negative mapping");
13627       return -99;
13628     }
13629
13630   /* Construct the API message */
13631   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
13632       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
13633
13634   mp->is_add = is_add;
13635   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13636   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13637   mp->eid_type = rmt_eid->type;
13638   mp->dp_table = clib_host_to_net_u32 (dp_table);
13639   mp->vni = clib_host_to_net_u32 (vni);
13640   mp->rmt_len = rmt_eid->len;
13641   mp->lcl_len = lcl_eid->len;
13642   mp->action = action;
13643
13644   if (0 != rmt_locs && 0 != lcl_locs)
13645     {
13646       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
13647       clib_memcpy (mp->locs, lcl_locs,
13648                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
13649
13650       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
13651       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
13652                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
13653     }
13654   vec_free (lcl_locs);
13655   vec_free (rmt_locs);
13656
13657   /* send it... */
13658   S (mp);
13659
13660   /* Wait for a reply... */
13661   W (ret);
13662   return ret;
13663 }
13664
13665 static int
13666 api_one_add_del_map_server (vat_main_t * vam)
13667 {
13668   unformat_input_t *input = vam->input;
13669   vl_api_one_add_del_map_server_t *mp;
13670   u8 is_add = 1;
13671   u8 ipv4_set = 0;
13672   u8 ipv6_set = 0;
13673   ip4_address_t ipv4;
13674   ip6_address_t ipv6;
13675   int ret;
13676
13677   /* Parse args required to build the message */
13678   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13679     {
13680       if (unformat (input, "del"))
13681         {
13682           is_add = 0;
13683         }
13684       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13685         {
13686           ipv4_set = 1;
13687         }
13688       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13689         {
13690           ipv6_set = 1;
13691         }
13692       else
13693         break;
13694     }
13695
13696   if (ipv4_set && ipv6_set)
13697     {
13698       errmsg ("both eid v4 and v6 addresses set");
13699       return -99;
13700     }
13701
13702   if (!ipv4_set && !ipv6_set)
13703     {
13704       errmsg ("eid addresses not set");
13705       return -99;
13706     }
13707
13708   /* Construct the API message */
13709   M (ONE_ADD_DEL_MAP_SERVER, mp);
13710
13711   mp->is_add = is_add;
13712   if (ipv6_set)
13713     {
13714       mp->is_ipv6 = 1;
13715       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13716     }
13717   else
13718     {
13719       mp->is_ipv6 = 0;
13720       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13721     }
13722
13723   /* send it... */
13724   S (mp);
13725
13726   /* Wait for a reply... */
13727   W (ret);
13728   return ret;
13729 }
13730
13731 #define api_lisp_add_del_map_server api_one_add_del_map_server
13732
13733 static int
13734 api_one_add_del_map_resolver (vat_main_t * vam)
13735 {
13736   unformat_input_t *input = vam->input;
13737   vl_api_one_add_del_map_resolver_t *mp;
13738   u8 is_add = 1;
13739   u8 ipv4_set = 0;
13740   u8 ipv6_set = 0;
13741   ip4_address_t ipv4;
13742   ip6_address_t ipv6;
13743   int ret;
13744
13745   /* Parse args required to build the message */
13746   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13747     {
13748       if (unformat (input, "del"))
13749         {
13750           is_add = 0;
13751         }
13752       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13753         {
13754           ipv4_set = 1;
13755         }
13756       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13757         {
13758           ipv6_set = 1;
13759         }
13760       else
13761         break;
13762     }
13763
13764   if (ipv4_set && ipv6_set)
13765     {
13766       errmsg ("both eid v4 and v6 addresses set");
13767       return -99;
13768     }
13769
13770   if (!ipv4_set && !ipv6_set)
13771     {
13772       errmsg ("eid addresses not set");
13773       return -99;
13774     }
13775
13776   /* Construct the API message */
13777   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
13778
13779   mp->is_add = is_add;
13780   if (ipv6_set)
13781     {
13782       mp->is_ipv6 = 1;
13783       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13784     }
13785   else
13786     {
13787       mp->is_ipv6 = 0;
13788       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13789     }
13790
13791   /* send it... */
13792   S (mp);
13793
13794   /* Wait for a reply... */
13795   W (ret);
13796   return ret;
13797 }
13798
13799 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
13800
13801 static int
13802 api_lisp_gpe_enable_disable (vat_main_t * vam)
13803 {
13804   unformat_input_t *input = vam->input;
13805   vl_api_gpe_enable_disable_t *mp;
13806   u8 is_set = 0;
13807   u8 is_en = 1;
13808   int ret;
13809
13810   /* Parse args required to build the message */
13811   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13812     {
13813       if (unformat (input, "enable"))
13814         {
13815           is_set = 1;
13816           is_en = 1;
13817         }
13818       else if (unformat (input, "disable"))
13819         {
13820           is_set = 1;
13821           is_en = 0;
13822         }
13823       else
13824         break;
13825     }
13826
13827   if (is_set == 0)
13828     {
13829       errmsg ("Value not set");
13830       return -99;
13831     }
13832
13833   /* Construct the API message */
13834   M (GPE_ENABLE_DISABLE, mp);
13835
13836   mp->is_en = is_en;
13837
13838   /* send it... */
13839   S (mp);
13840
13841   /* Wait for a reply... */
13842   W (ret);
13843   return ret;
13844 }
13845
13846 static int
13847 api_one_rloc_probe_enable_disable (vat_main_t * vam)
13848 {
13849   unformat_input_t *input = vam->input;
13850   vl_api_one_rloc_probe_enable_disable_t *mp;
13851   u8 is_set = 0;
13852   u8 is_en = 0;
13853   int ret;
13854
13855   /* Parse args required to build the message */
13856   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13857     {
13858       if (unformat (input, "enable"))
13859         {
13860           is_set = 1;
13861           is_en = 1;
13862         }
13863       else if (unformat (input, "disable"))
13864         is_set = 1;
13865       else
13866         break;
13867     }
13868
13869   if (!is_set)
13870     {
13871       errmsg ("Value not set");
13872       return -99;
13873     }
13874
13875   /* Construct the API message */
13876   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
13877
13878   mp->is_enabled = is_en;
13879
13880   /* send it... */
13881   S (mp);
13882
13883   /* Wait for a reply... */
13884   W (ret);
13885   return ret;
13886 }
13887
13888 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
13889
13890 static int
13891 api_one_map_register_enable_disable (vat_main_t * vam)
13892 {
13893   unformat_input_t *input = vam->input;
13894   vl_api_one_map_register_enable_disable_t *mp;
13895   u8 is_set = 0;
13896   u8 is_en = 0;
13897   int ret;
13898
13899   /* Parse args required to build the message */
13900   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13901     {
13902       if (unformat (input, "enable"))
13903         {
13904           is_set = 1;
13905           is_en = 1;
13906         }
13907       else if (unformat (input, "disable"))
13908         is_set = 1;
13909       else
13910         break;
13911     }
13912
13913   if (!is_set)
13914     {
13915       errmsg ("Value not set");
13916       return -99;
13917     }
13918
13919   /* Construct the API message */
13920   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
13921
13922   mp->is_enabled = is_en;
13923
13924   /* send it... */
13925   S (mp);
13926
13927   /* Wait for a reply... */
13928   W (ret);
13929   return ret;
13930 }
13931
13932 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
13933
13934 static int
13935 api_one_enable_disable (vat_main_t * vam)
13936 {
13937   unformat_input_t *input = vam->input;
13938   vl_api_one_enable_disable_t *mp;
13939   u8 is_set = 0;
13940   u8 is_en = 0;
13941   int ret;
13942
13943   /* Parse args required to build the message */
13944   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13945     {
13946       if (unformat (input, "enable"))
13947         {
13948           is_set = 1;
13949           is_en = 1;
13950         }
13951       else if (unformat (input, "disable"))
13952         {
13953           is_set = 1;
13954         }
13955       else
13956         break;
13957     }
13958
13959   if (!is_set)
13960     {
13961       errmsg ("Value not set");
13962       return -99;
13963     }
13964
13965   /* Construct the API message */
13966   M (ONE_ENABLE_DISABLE, mp);
13967
13968   mp->is_en = is_en;
13969
13970   /* send it... */
13971   S (mp);
13972
13973   /* Wait for a reply... */
13974   W (ret);
13975   return ret;
13976 }
13977
13978 #define api_lisp_enable_disable api_one_enable_disable
13979
13980 static int
13981 api_show_one_map_register_state (vat_main_t * vam)
13982 {
13983   vl_api_show_one_map_register_state_t *mp;
13984   int ret;
13985
13986   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
13987
13988   /* send */
13989   S (mp);
13990
13991   /* wait for reply */
13992   W (ret);
13993   return ret;
13994 }
13995
13996 #define api_show_lisp_map_register_state api_show_one_map_register_state
13997
13998 static int
13999 api_show_one_rloc_probe_state (vat_main_t * vam)
14000 {
14001   vl_api_show_one_rloc_probe_state_t *mp;
14002   int ret;
14003
14004   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
14005
14006   /* send */
14007   S (mp);
14008
14009   /* wait for reply */
14010   W (ret);
14011   return ret;
14012 }
14013
14014 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
14015
14016 static int
14017 api_show_one_map_request_mode (vat_main_t * vam)
14018 {
14019   vl_api_show_one_map_request_mode_t *mp;
14020   int ret;
14021
14022   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
14023
14024   /* send */
14025   S (mp);
14026
14027   /* wait for reply */
14028   W (ret);
14029   return ret;
14030 }
14031
14032 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
14033
14034 static int
14035 api_one_map_request_mode (vat_main_t * vam)
14036 {
14037   unformat_input_t *input = vam->input;
14038   vl_api_one_map_request_mode_t *mp;
14039   u8 mode = 0;
14040   int ret;
14041
14042   /* Parse args required to build the message */
14043   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14044     {
14045       if (unformat (input, "dst-only"))
14046         mode = 0;
14047       else if (unformat (input, "src-dst"))
14048         mode = 1;
14049       else
14050         {
14051           errmsg ("parse error '%U'", format_unformat_error, input);
14052           return -99;
14053         }
14054     }
14055
14056   M (ONE_MAP_REQUEST_MODE, mp);
14057
14058   mp->mode = mode;
14059
14060   /* send */
14061   S (mp);
14062
14063   /* wait for reply */
14064   W (ret);
14065   return ret;
14066 }
14067
14068 #define api_lisp_map_request_mode api_one_map_request_mode
14069
14070 /**
14071  * Enable/disable ONE proxy ITR.
14072  *
14073  * @param vam vpp API test context
14074  * @return return code
14075  */
14076 static int
14077 api_one_pitr_set_locator_set (vat_main_t * vam)
14078 {
14079   u8 ls_name_set = 0;
14080   unformat_input_t *input = vam->input;
14081   vl_api_one_pitr_set_locator_set_t *mp;
14082   u8 is_add = 1;
14083   u8 *ls_name = 0;
14084   int ret;
14085
14086   /* Parse args required to build the message */
14087   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14088     {
14089       if (unformat (input, "del"))
14090         is_add = 0;
14091       else if (unformat (input, "locator-set %s", &ls_name))
14092         ls_name_set = 1;
14093       else
14094         {
14095           errmsg ("parse error '%U'", format_unformat_error, input);
14096           return -99;
14097         }
14098     }
14099
14100   if (!ls_name_set)
14101     {
14102       errmsg ("locator-set name not set!");
14103       return -99;
14104     }
14105
14106   M (ONE_PITR_SET_LOCATOR_SET, mp);
14107
14108   mp->is_add = is_add;
14109   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
14110   vec_free (ls_name);
14111
14112   /* send */
14113   S (mp);
14114
14115   /* wait for reply */
14116   W (ret);
14117   return ret;
14118 }
14119
14120 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
14121
14122 static int
14123 api_show_one_pitr (vat_main_t * vam)
14124 {
14125   vl_api_show_one_pitr_t *mp;
14126   int ret;
14127
14128   if (!vam->json_output)
14129     {
14130       print (vam->ofp, "%=20s", "lisp status:");
14131     }
14132
14133   M (SHOW_ONE_PITR, mp);
14134   /* send it... */
14135   S (mp);
14136
14137   /* Wait for a reply... */
14138   W (ret);
14139   return ret;
14140 }
14141
14142 #define api_show_lisp_pitr api_show_one_pitr
14143
14144 /**
14145  * Add/delete mapping between vni and vrf
14146  */
14147 static int
14148 api_one_eid_table_add_del_map (vat_main_t * vam)
14149 {
14150   unformat_input_t *input = vam->input;
14151   vl_api_one_eid_table_add_del_map_t *mp;
14152   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
14153   u32 vni, vrf, bd_index;
14154   int ret;
14155
14156   /* Parse args required to build the message */
14157   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14158     {
14159       if (unformat (input, "del"))
14160         is_add = 0;
14161       else if (unformat (input, "vrf %d", &vrf))
14162         vrf_set = 1;
14163       else if (unformat (input, "bd_index %d", &bd_index))
14164         bd_index_set = 1;
14165       else if (unformat (input, "vni %d", &vni))
14166         vni_set = 1;
14167       else
14168         break;
14169     }
14170
14171   if (!vni_set || (!vrf_set && !bd_index_set))
14172     {
14173       errmsg ("missing arguments!");
14174       return -99;
14175     }
14176
14177   if (vrf_set && bd_index_set)
14178     {
14179       errmsg ("error: both vrf and bd entered!");
14180       return -99;
14181     }
14182
14183   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
14184
14185   mp->is_add = is_add;
14186   mp->vni = htonl (vni);
14187   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
14188   mp->is_l2 = bd_index_set;
14189
14190   /* send */
14191   S (mp);
14192
14193   /* wait for reply */
14194   W (ret);
14195   return ret;
14196 }
14197
14198 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
14199
14200 uword
14201 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
14202 {
14203   u32 *action = va_arg (*args, u32 *);
14204   u8 *s = 0;
14205
14206   if (unformat (input, "%s", &s))
14207     {
14208       if (!strcmp ((char *) s, "no-action"))
14209         action[0] = 0;
14210       else if (!strcmp ((char *) s, "natively-forward"))
14211         action[0] = 1;
14212       else if (!strcmp ((char *) s, "send-map-request"))
14213         action[0] = 2;
14214       else if (!strcmp ((char *) s, "drop"))
14215         action[0] = 3;
14216       else
14217         {
14218           clib_warning ("invalid action: '%s'", s);
14219           action[0] = 3;
14220         }
14221     }
14222   else
14223     return 0;
14224
14225   vec_free (s);
14226   return 1;
14227 }
14228
14229 /**
14230  * Add/del remote mapping to/from ONE control plane
14231  *
14232  * @param vam vpp API test context
14233  * @return return code
14234  */
14235 static int
14236 api_one_add_del_remote_mapping (vat_main_t * vam)
14237 {
14238   unformat_input_t *input = vam->input;
14239   vl_api_one_add_del_remote_mapping_t *mp;
14240   u32 vni = 0;
14241   lisp_eid_vat_t _eid, *eid = &_eid;
14242   lisp_eid_vat_t _seid, *seid = &_seid;
14243   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
14244   u32 action = ~0, p, w, data_len;
14245   ip4_address_t rloc4;
14246   ip6_address_t rloc6;
14247   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
14248   int ret;
14249
14250   memset (&rloc, 0, sizeof (rloc));
14251
14252   /* Parse args required to build the message */
14253   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14254     {
14255       if (unformat (input, "del-all"))
14256         {
14257           del_all = 1;
14258         }
14259       else if (unformat (input, "del"))
14260         {
14261           is_add = 0;
14262         }
14263       else if (unformat (input, "add"))
14264         {
14265           is_add = 1;
14266         }
14267       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14268         {
14269           eid_set = 1;
14270         }
14271       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
14272         {
14273           seid_set = 1;
14274         }
14275       else if (unformat (input, "vni %d", &vni))
14276         {
14277           ;
14278         }
14279       else if (unformat (input, "p %d w %d", &p, &w))
14280         {
14281           if (!curr_rloc)
14282             {
14283               errmsg ("No RLOC configured for setting priority/weight!");
14284               return -99;
14285             }
14286           curr_rloc->priority = p;
14287           curr_rloc->weight = w;
14288         }
14289       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
14290         {
14291           rloc.is_ip4 = 1;
14292           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
14293           vec_add1 (rlocs, rloc);
14294           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14295         }
14296       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
14297         {
14298           rloc.is_ip4 = 0;
14299           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
14300           vec_add1 (rlocs, rloc);
14301           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14302         }
14303       else if (unformat (input, "action %U",
14304                          unformat_negative_mapping_action, &action))
14305         {
14306           ;
14307         }
14308       else
14309         {
14310           clib_warning ("parse error '%U'", format_unformat_error, input);
14311           return -99;
14312         }
14313     }
14314
14315   if (0 == eid_set)
14316     {
14317       errmsg ("missing params!");
14318       return -99;
14319     }
14320
14321   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
14322     {
14323       errmsg ("no action set for negative map-reply!");
14324       return -99;
14325     }
14326
14327   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
14328
14329   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
14330   mp->is_add = is_add;
14331   mp->vni = htonl (vni);
14332   mp->action = (u8) action;
14333   mp->is_src_dst = seid_set;
14334   mp->eid_len = eid->len;
14335   mp->seid_len = seid->len;
14336   mp->del_all = del_all;
14337   mp->eid_type = eid->type;
14338   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14339   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
14340
14341   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
14342   clib_memcpy (mp->rlocs, rlocs, data_len);
14343   vec_free (rlocs);
14344
14345   /* send it... */
14346   S (mp);
14347
14348   /* Wait for a reply... */
14349   W (ret);
14350   return ret;
14351 }
14352
14353 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
14354
14355 /**
14356  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
14357  * forwarding entries in data-plane accordingly.
14358  *
14359  * @param vam vpp API test context
14360  * @return return code
14361  */
14362 static int
14363 api_one_add_del_adjacency (vat_main_t * vam)
14364 {
14365   unformat_input_t *input = vam->input;
14366   vl_api_one_add_del_adjacency_t *mp;
14367   u32 vni = 0;
14368   ip4_address_t leid4, reid4;
14369   ip6_address_t leid6, reid6;
14370   u8 reid_mac[6] = { 0 };
14371   u8 leid_mac[6] = { 0 };
14372   u8 reid_type, leid_type;
14373   u32 leid_len = 0, reid_len = 0, len;
14374   u8 is_add = 1;
14375   int ret;
14376
14377   leid_type = reid_type = (u8) ~ 0;
14378
14379   /* Parse args required to build the message */
14380   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14381     {
14382       if (unformat (input, "del"))
14383         {
14384           is_add = 0;
14385         }
14386       else if (unformat (input, "add"))
14387         {
14388           is_add = 1;
14389         }
14390       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
14391                          &reid4, &len))
14392         {
14393           reid_type = 0;        /* ipv4 */
14394           reid_len = len;
14395         }
14396       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
14397                          &reid6, &len))
14398         {
14399           reid_type = 1;        /* ipv6 */
14400           reid_len = len;
14401         }
14402       else if (unformat (input, "reid %U", unformat_ethernet_address,
14403                          reid_mac))
14404         {
14405           reid_type = 2;        /* mac */
14406         }
14407       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
14408                          &leid4, &len))
14409         {
14410           leid_type = 0;        /* ipv4 */
14411           leid_len = len;
14412         }
14413       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
14414                          &leid6, &len))
14415         {
14416           leid_type = 1;        /* ipv6 */
14417           leid_len = len;
14418         }
14419       else if (unformat (input, "leid %U", unformat_ethernet_address,
14420                          leid_mac))
14421         {
14422           leid_type = 2;        /* mac */
14423         }
14424       else if (unformat (input, "vni %d", &vni))
14425         {
14426           ;
14427         }
14428       else
14429         {
14430           errmsg ("parse error '%U'", format_unformat_error, input);
14431           return -99;
14432         }
14433     }
14434
14435   if ((u8) ~ 0 == reid_type)
14436     {
14437       errmsg ("missing params!");
14438       return -99;
14439     }
14440
14441   if (leid_type != reid_type)
14442     {
14443       errmsg ("remote and local EIDs are of different types!");
14444       return -99;
14445     }
14446
14447   M (ONE_ADD_DEL_ADJACENCY, mp);
14448   mp->is_add = is_add;
14449   mp->vni = htonl (vni);
14450   mp->leid_len = leid_len;
14451   mp->reid_len = reid_len;
14452   mp->eid_type = reid_type;
14453
14454   switch (mp->eid_type)
14455     {
14456     case 0:
14457       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
14458       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
14459       break;
14460     case 1:
14461       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
14462       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
14463       break;
14464     case 2:
14465       clib_memcpy (mp->leid, leid_mac, 6);
14466       clib_memcpy (mp->reid, reid_mac, 6);
14467       break;
14468     default:
14469       errmsg ("unknown EID type %d!", mp->eid_type);
14470       return 0;
14471     }
14472
14473   /* send it... */
14474   S (mp);
14475
14476   /* Wait for a reply... */
14477   W (ret);
14478   return ret;
14479 }
14480
14481 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
14482
14483 uword
14484 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
14485 {
14486   u32 *mode = va_arg (*args, u32 *);
14487
14488   if (unformat (input, "lisp"))
14489     *mode = 0;
14490   else if (unformat (input, "vxlan"))
14491     *mode = 1;
14492   else
14493     return 0;
14494
14495   return 1;
14496 }
14497
14498 static int
14499 api_gpe_get_encap_mode (vat_main_t * vam)
14500 {
14501   vl_api_gpe_get_encap_mode_t *mp;
14502   int ret;
14503
14504   /* Construct the API message */
14505   M (GPE_GET_ENCAP_MODE, mp);
14506
14507   /* send it... */
14508   S (mp);
14509
14510   /* Wait for a reply... */
14511   W (ret);
14512   return ret;
14513 }
14514
14515 static int
14516 api_gpe_set_encap_mode (vat_main_t * vam)
14517 {
14518   unformat_input_t *input = vam->input;
14519   vl_api_gpe_set_encap_mode_t *mp;
14520   int ret;
14521   u32 mode = 0;
14522
14523   /* Parse args required to build the message */
14524   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14525     {
14526       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
14527         ;
14528       else
14529         break;
14530     }
14531
14532   /* Construct the API message */
14533   M (GPE_SET_ENCAP_MODE, mp);
14534
14535   mp->mode = mode;
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_lisp_gpe_add_del_iface (vat_main_t * vam)
14547 {
14548   unformat_input_t *input = vam->input;
14549   vl_api_gpe_add_del_iface_t *mp;
14550   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
14551   u32 dp_table = 0, vni = 0;
14552   int ret;
14553
14554   /* Parse args required to build the message */
14555   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14556     {
14557       if (unformat (input, "up"))
14558         {
14559           action_set = 1;
14560           is_add = 1;
14561         }
14562       else if (unformat (input, "down"))
14563         {
14564           action_set = 1;
14565           is_add = 0;
14566         }
14567       else if (unformat (input, "table_id %d", &dp_table))
14568         {
14569           dp_table_set = 1;
14570         }
14571       else if (unformat (input, "bd_id %d", &dp_table))
14572         {
14573           dp_table_set = 1;
14574           is_l2 = 1;
14575         }
14576       else if (unformat (input, "vni %d", &vni))
14577         {
14578           vni_set = 1;
14579         }
14580       else
14581         break;
14582     }
14583
14584   if (action_set == 0)
14585     {
14586       errmsg ("Action not set");
14587       return -99;
14588     }
14589   if (dp_table_set == 0 || vni_set == 0)
14590     {
14591       errmsg ("vni and dp_table must be set");
14592       return -99;
14593     }
14594
14595   /* Construct the API message */
14596   M (GPE_ADD_DEL_IFACE, mp);
14597
14598   mp->is_add = is_add;
14599   mp->dp_table = dp_table;
14600   mp->is_l2 = is_l2;
14601   mp->vni = vni;
14602
14603   /* send it... */
14604   S (mp);
14605
14606   /* Wait for a reply... */
14607   W (ret);
14608   return ret;
14609 }
14610
14611 /**
14612  * Add/del map request itr rlocs from ONE control plane and updates
14613  *
14614  * @param vam vpp API test context
14615  * @return return code
14616  */
14617 static int
14618 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
14619 {
14620   unformat_input_t *input = vam->input;
14621   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
14622   u8 *locator_set_name = 0;
14623   u8 locator_set_name_set = 0;
14624   u8 is_add = 1;
14625   int ret;
14626
14627   /* Parse args required to build the message */
14628   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14629     {
14630       if (unformat (input, "del"))
14631         {
14632           is_add = 0;
14633         }
14634       else if (unformat (input, "%_%v%_", &locator_set_name))
14635         {
14636           locator_set_name_set = 1;
14637         }
14638       else
14639         {
14640           clib_warning ("parse error '%U'", format_unformat_error, input);
14641           return -99;
14642         }
14643     }
14644
14645   if (is_add && !locator_set_name_set)
14646     {
14647       errmsg ("itr-rloc is not set!");
14648       return -99;
14649     }
14650
14651   if (is_add && vec_len (locator_set_name) > 64)
14652     {
14653       errmsg ("itr-rloc locator-set name too long");
14654       vec_free (locator_set_name);
14655       return -99;
14656     }
14657
14658   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
14659   mp->is_add = is_add;
14660   if (is_add)
14661     {
14662       clib_memcpy (mp->locator_set_name, locator_set_name,
14663                    vec_len (locator_set_name));
14664     }
14665   else
14666     {
14667       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
14668     }
14669   vec_free (locator_set_name);
14670
14671   /* send it... */
14672   S (mp);
14673
14674   /* Wait for a reply... */
14675   W (ret);
14676   return ret;
14677 }
14678
14679 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
14680
14681 static int
14682 api_one_locator_dump (vat_main_t * vam)
14683 {
14684   unformat_input_t *input = vam->input;
14685   vl_api_one_locator_dump_t *mp;
14686   vl_api_control_ping_t *mp_ping;
14687   u8 is_index_set = 0, is_name_set = 0;
14688   u8 *ls_name = 0;
14689   u32 ls_index = ~0;
14690   int ret;
14691
14692   /* Parse args required to build the message */
14693   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14694     {
14695       if (unformat (input, "ls_name %_%v%_", &ls_name))
14696         {
14697           is_name_set = 1;
14698         }
14699       else if (unformat (input, "ls_index %d", &ls_index))
14700         {
14701           is_index_set = 1;
14702         }
14703       else
14704         {
14705           errmsg ("parse error '%U'", format_unformat_error, input);
14706           return -99;
14707         }
14708     }
14709
14710   if (!is_index_set && !is_name_set)
14711     {
14712       errmsg ("error: expected one of index or name!");
14713       return -99;
14714     }
14715
14716   if (is_index_set && is_name_set)
14717     {
14718       errmsg ("error: only one param expected!");
14719       return -99;
14720     }
14721
14722   if (vec_len (ls_name) > 62)
14723     {
14724       errmsg ("error: locator set name too long!");
14725       return -99;
14726     }
14727
14728   if (!vam->json_output)
14729     {
14730       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
14731     }
14732
14733   M (ONE_LOCATOR_DUMP, mp);
14734   mp->is_index_set = is_index_set;
14735
14736   if (is_index_set)
14737     mp->ls_index = clib_host_to_net_u32 (ls_index);
14738   else
14739     {
14740       vec_add1 (ls_name, 0);
14741       strncpy ((char *) mp->ls_name, (char *) ls_name,
14742                sizeof (mp->ls_name) - 1);
14743     }
14744
14745   /* send it... */
14746   S (mp);
14747
14748   /* Use a control ping for synchronization */
14749   M (CONTROL_PING, mp_ping);
14750   S (mp_ping);
14751
14752   /* Wait for a reply... */
14753   W (ret);
14754   return ret;
14755 }
14756
14757 #define api_lisp_locator_dump api_one_locator_dump
14758
14759 static int
14760 api_one_locator_set_dump (vat_main_t * vam)
14761 {
14762   vl_api_one_locator_set_dump_t *mp;
14763   vl_api_control_ping_t *mp_ping;
14764   unformat_input_t *input = vam->input;
14765   u8 filter = 0;
14766   int ret;
14767
14768   /* Parse args required to build the message */
14769   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14770     {
14771       if (unformat (input, "local"))
14772         {
14773           filter = 1;
14774         }
14775       else if (unformat (input, "remote"))
14776         {
14777           filter = 2;
14778         }
14779       else
14780         {
14781           errmsg ("parse error '%U'", format_unformat_error, input);
14782           return -99;
14783         }
14784     }
14785
14786   if (!vam->json_output)
14787     {
14788       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
14789     }
14790
14791   M (ONE_LOCATOR_SET_DUMP, mp);
14792
14793   mp->filter = filter;
14794
14795   /* send it... */
14796   S (mp);
14797
14798   /* Use a control ping for synchronization */
14799   M (CONTROL_PING, mp_ping);
14800   S (mp_ping);
14801
14802   /* Wait for a reply... */
14803   W (ret);
14804   return ret;
14805 }
14806
14807 #define api_lisp_locator_set_dump api_one_locator_set_dump
14808
14809 static int
14810 api_one_eid_table_map_dump (vat_main_t * vam)
14811 {
14812   u8 is_l2 = 0;
14813   u8 mode_set = 0;
14814   unformat_input_t *input = vam->input;
14815   vl_api_one_eid_table_map_dump_t *mp;
14816   vl_api_control_ping_t *mp_ping;
14817   int ret;
14818
14819   /* Parse args required to build the message */
14820   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14821     {
14822       if (unformat (input, "l2"))
14823         {
14824           is_l2 = 1;
14825           mode_set = 1;
14826         }
14827       else if (unformat (input, "l3"))
14828         {
14829           is_l2 = 0;
14830           mode_set = 1;
14831         }
14832       else
14833         {
14834           errmsg ("parse error '%U'", format_unformat_error, input);
14835           return -99;
14836         }
14837     }
14838
14839   if (!mode_set)
14840     {
14841       errmsg ("expected one of 'l2' or 'l3' parameter!");
14842       return -99;
14843     }
14844
14845   if (!vam->json_output)
14846     {
14847       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
14848     }
14849
14850   M (ONE_EID_TABLE_MAP_DUMP, mp);
14851   mp->is_l2 = is_l2;
14852
14853   /* send it... */
14854   S (mp);
14855
14856   /* Use a control ping for synchronization */
14857   M (CONTROL_PING, mp_ping);
14858   S (mp_ping);
14859
14860   /* Wait for a reply... */
14861   W (ret);
14862   return ret;
14863 }
14864
14865 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
14866
14867 static int
14868 api_one_eid_table_vni_dump (vat_main_t * vam)
14869 {
14870   vl_api_one_eid_table_vni_dump_t *mp;
14871   vl_api_control_ping_t *mp_ping;
14872   int ret;
14873
14874   if (!vam->json_output)
14875     {
14876       print (vam->ofp, "VNI");
14877     }
14878
14879   M (ONE_EID_TABLE_VNI_DUMP, mp);
14880
14881   /* send it... */
14882   S (mp);
14883
14884   /* Use a control ping for synchronization */
14885   M (CONTROL_PING, mp_ping);
14886   S (mp_ping);
14887
14888   /* Wait for a reply... */
14889   W (ret);
14890   return ret;
14891 }
14892
14893 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
14894
14895 static int
14896 api_one_eid_table_dump (vat_main_t * vam)
14897 {
14898   unformat_input_t *i = vam->input;
14899   vl_api_one_eid_table_dump_t *mp;
14900   vl_api_control_ping_t *mp_ping;
14901   struct in_addr ip4;
14902   struct in6_addr ip6;
14903   u8 mac[6];
14904   u8 eid_type = ~0, eid_set = 0;
14905   u32 prefix_length = ~0, t, vni = 0;
14906   u8 filter = 0;
14907   int ret;
14908
14909   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14910     {
14911       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
14912         {
14913           eid_set = 1;
14914           eid_type = 0;
14915           prefix_length = t;
14916         }
14917       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
14918         {
14919           eid_set = 1;
14920           eid_type = 1;
14921           prefix_length = t;
14922         }
14923       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
14924         {
14925           eid_set = 1;
14926           eid_type = 2;
14927         }
14928       else if (unformat (i, "vni %d", &t))
14929         {
14930           vni = t;
14931         }
14932       else if (unformat (i, "local"))
14933         {
14934           filter = 1;
14935         }
14936       else if (unformat (i, "remote"))
14937         {
14938           filter = 2;
14939         }
14940       else
14941         {
14942           errmsg ("parse error '%U'", format_unformat_error, i);
14943           return -99;
14944         }
14945     }
14946
14947   if (!vam->json_output)
14948     {
14949       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
14950              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
14951     }
14952
14953   M (ONE_EID_TABLE_DUMP, mp);
14954
14955   mp->filter = filter;
14956   if (eid_set)
14957     {
14958       mp->eid_set = 1;
14959       mp->vni = htonl (vni);
14960       mp->eid_type = eid_type;
14961       switch (eid_type)
14962         {
14963         case 0:
14964           mp->prefix_length = prefix_length;
14965           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
14966           break;
14967         case 1:
14968           mp->prefix_length = prefix_length;
14969           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
14970           break;
14971         case 2:
14972           clib_memcpy (mp->eid, mac, sizeof (mac));
14973           break;
14974         default:
14975           errmsg ("unknown EID type %d!", eid_type);
14976           return -99;
14977         }
14978     }
14979
14980   /* send it... */
14981   S (mp);
14982
14983   /* Use a control ping for synchronization */
14984   M (CONTROL_PING, mp_ping);
14985   S (mp_ping);
14986
14987   /* Wait for a reply... */
14988   W (ret);
14989   return ret;
14990 }
14991
14992 #define api_lisp_eid_table_dump api_one_eid_table_dump
14993
14994 static int
14995 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
14996 {
14997   unformat_input_t *i = vam->input;
14998   vl_api_gpe_fwd_entries_get_t *mp;
14999   u8 vni_set = 0;
15000   u32 vni = ~0;
15001   int ret;
15002
15003   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15004     {
15005       if (unformat (i, "vni %d", &vni))
15006         {
15007           vni_set = 1;
15008         }
15009       else
15010         {
15011           errmsg ("parse error '%U'", format_unformat_error, i);
15012           return -99;
15013         }
15014     }
15015
15016   if (!vni_set)
15017     {
15018       errmsg ("vni not set!");
15019       return -99;
15020     }
15021
15022   if (!vam->json_output)
15023     {
15024       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
15025              "leid", "reid");
15026     }
15027
15028   M (GPE_FWD_ENTRIES_GET, mp);
15029   mp->vni = clib_host_to_net_u32 (vni);
15030
15031   /* send it... */
15032   S (mp);
15033
15034   /* Wait for a reply... */
15035   W (ret);
15036   return ret;
15037 }
15038
15039 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
15040 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
15041 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
15042 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
15043
15044 static int
15045 api_one_adjacencies_get (vat_main_t * vam)
15046 {
15047   unformat_input_t *i = vam->input;
15048   vl_api_one_adjacencies_get_t *mp;
15049   u8 vni_set = 0;
15050   u32 vni = ~0;
15051   int ret;
15052
15053   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15054     {
15055       if (unformat (i, "vni %d", &vni))
15056         {
15057           vni_set = 1;
15058         }
15059       else
15060         {
15061           errmsg ("parse error '%U'", format_unformat_error, i);
15062           return -99;
15063         }
15064     }
15065
15066   if (!vni_set)
15067     {
15068       errmsg ("vni not set!");
15069       return -99;
15070     }
15071
15072   if (!vam->json_output)
15073     {
15074       print (vam->ofp, "%s %40s", "leid", "reid");
15075     }
15076
15077   M (ONE_ADJACENCIES_GET, mp);
15078   mp->vni = clib_host_to_net_u32 (vni);
15079
15080   /* send it... */
15081   S (mp);
15082
15083   /* Wait for a reply... */
15084   W (ret);
15085   return ret;
15086 }
15087
15088 #define api_lisp_adjacencies_get api_one_adjacencies_get
15089
15090 static int
15091 api_one_map_server_dump (vat_main_t * vam)
15092 {
15093   vl_api_one_map_server_dump_t *mp;
15094   vl_api_control_ping_t *mp_ping;
15095   int ret;
15096
15097   if (!vam->json_output)
15098     {
15099       print (vam->ofp, "%=20s", "Map server");
15100     }
15101
15102   M (ONE_MAP_SERVER_DUMP, mp);
15103   /* send it... */
15104   S (mp);
15105
15106   /* Use a control ping for synchronization */
15107   M (CONTROL_PING, mp_ping);
15108   S (mp_ping);
15109
15110   /* Wait for a reply... */
15111   W (ret);
15112   return ret;
15113 }
15114
15115 #define api_lisp_map_server_dump api_one_map_server_dump
15116
15117 static int
15118 api_one_map_resolver_dump (vat_main_t * vam)
15119 {
15120   vl_api_one_map_resolver_dump_t *mp;
15121   vl_api_control_ping_t *mp_ping;
15122   int ret;
15123
15124   if (!vam->json_output)
15125     {
15126       print (vam->ofp, "%=20s", "Map resolver");
15127     }
15128
15129   M (ONE_MAP_RESOLVER_DUMP, mp);
15130   /* send it... */
15131   S (mp);
15132
15133   /* Use a control ping for synchronization */
15134   M (CONTROL_PING, mp_ping);
15135   S (mp_ping);
15136
15137   /* Wait for a reply... */
15138   W (ret);
15139   return ret;
15140 }
15141
15142 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
15143
15144 static int
15145 api_show_one_status (vat_main_t * vam)
15146 {
15147   vl_api_show_one_status_t *mp;
15148   int ret;
15149
15150   if (!vam->json_output)
15151     {
15152       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
15153     }
15154
15155   M (SHOW_ONE_STATUS, mp);
15156   /* send it... */
15157   S (mp);
15158   /* Wait for a reply... */
15159   W (ret);
15160   return ret;
15161 }
15162
15163 #define api_show_lisp_status api_show_one_status
15164
15165 static int
15166 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
15167 {
15168   vl_api_gpe_fwd_entry_path_dump_t *mp;
15169   vl_api_control_ping_t *mp_ping;
15170   unformat_input_t *i = vam->input;
15171   u32 fwd_entry_index = ~0;
15172   int ret;
15173
15174   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15175     {
15176       if (unformat (i, "index %d", &fwd_entry_index))
15177         ;
15178       else
15179         break;
15180     }
15181
15182   if (~0 == fwd_entry_index)
15183     {
15184       errmsg ("no index specified!");
15185       return -99;
15186     }
15187
15188   if (!vam->json_output)
15189     {
15190       print (vam->ofp, "first line");
15191     }
15192
15193   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
15194
15195   /* send it... */
15196   S (mp);
15197   /* Use a control ping for synchronization */
15198   M (CONTROL_PING, mp_ping);
15199   S (mp_ping);
15200
15201   /* Wait for a reply... */
15202   W (ret);
15203   return ret;
15204 }
15205
15206 static int
15207 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
15208 {
15209   vl_api_one_get_map_request_itr_rlocs_t *mp;
15210   int ret;
15211
15212   if (!vam->json_output)
15213     {
15214       print (vam->ofp, "%=20s", "itr-rlocs:");
15215     }
15216
15217   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
15218   /* send it... */
15219   S (mp);
15220   /* Wait for a reply... */
15221   W (ret);
15222   return ret;
15223 }
15224
15225 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
15226
15227 static int
15228 api_af_packet_create (vat_main_t * vam)
15229 {
15230   unformat_input_t *i = vam->input;
15231   vl_api_af_packet_create_t *mp;
15232   u8 *host_if_name = 0;
15233   u8 hw_addr[6];
15234   u8 random_hw_addr = 1;
15235   int ret;
15236
15237   memset (hw_addr, 0, sizeof (hw_addr));
15238
15239   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15240     {
15241       if (unformat (i, "name %s", &host_if_name))
15242         vec_add1 (host_if_name, 0);
15243       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15244         random_hw_addr = 0;
15245       else
15246         break;
15247     }
15248
15249   if (!vec_len (host_if_name))
15250     {
15251       errmsg ("host-interface name must be specified");
15252       return -99;
15253     }
15254
15255   if (vec_len (host_if_name) > 64)
15256     {
15257       errmsg ("host-interface name too long");
15258       return -99;
15259     }
15260
15261   M (AF_PACKET_CREATE, mp);
15262
15263   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15264   clib_memcpy (mp->hw_addr, hw_addr, 6);
15265   mp->use_random_hw_addr = random_hw_addr;
15266   vec_free (host_if_name);
15267
15268   S (mp);
15269
15270   /* *INDENT-OFF* */
15271   W2 (ret,
15272       ({
15273         if (ret == 0)
15274           fprintf (vam->ofp ? vam->ofp : stderr,
15275                    " new sw_if_index = %d\n", vam->sw_if_index);
15276       }));
15277   /* *INDENT-ON* */
15278   return ret;
15279 }
15280
15281 static int
15282 api_af_packet_delete (vat_main_t * vam)
15283 {
15284   unformat_input_t *i = vam->input;
15285   vl_api_af_packet_delete_t *mp;
15286   u8 *host_if_name = 0;
15287   int ret;
15288
15289   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15290     {
15291       if (unformat (i, "name %s", &host_if_name))
15292         vec_add1 (host_if_name, 0);
15293       else
15294         break;
15295     }
15296
15297   if (!vec_len (host_if_name))
15298     {
15299       errmsg ("host-interface name must be specified");
15300       return -99;
15301     }
15302
15303   if (vec_len (host_if_name) > 64)
15304     {
15305       errmsg ("host-interface name too long");
15306       return -99;
15307     }
15308
15309   M (AF_PACKET_DELETE, mp);
15310
15311   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15312   vec_free (host_if_name);
15313
15314   S (mp);
15315   W (ret);
15316   return ret;
15317 }
15318
15319 static int
15320 api_policer_add_del (vat_main_t * vam)
15321 {
15322   unformat_input_t *i = vam->input;
15323   vl_api_policer_add_del_t *mp;
15324   u8 is_add = 1;
15325   u8 *name = 0;
15326   u32 cir = 0;
15327   u32 eir = 0;
15328   u64 cb = 0;
15329   u64 eb = 0;
15330   u8 rate_type = 0;
15331   u8 round_type = 0;
15332   u8 type = 0;
15333   u8 color_aware = 0;
15334   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
15335   int ret;
15336
15337   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
15338   conform_action.dscp = 0;
15339   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
15340   exceed_action.dscp = 0;
15341   violate_action.action_type = SSE2_QOS_ACTION_DROP;
15342   violate_action.dscp = 0;
15343
15344   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15345     {
15346       if (unformat (i, "del"))
15347         is_add = 0;
15348       else if (unformat (i, "name %s", &name))
15349         vec_add1 (name, 0);
15350       else if (unformat (i, "cir %u", &cir))
15351         ;
15352       else if (unformat (i, "eir %u", &eir))
15353         ;
15354       else if (unformat (i, "cb %u", &cb))
15355         ;
15356       else if (unformat (i, "eb %u", &eb))
15357         ;
15358       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
15359                          &rate_type))
15360         ;
15361       else if (unformat (i, "round_type %U", unformat_policer_round_type,
15362                          &round_type))
15363         ;
15364       else if (unformat (i, "type %U", unformat_policer_type, &type))
15365         ;
15366       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
15367                          &conform_action))
15368         ;
15369       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
15370                          &exceed_action))
15371         ;
15372       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
15373                          &violate_action))
15374         ;
15375       else if (unformat (i, "color-aware"))
15376         color_aware = 1;
15377       else
15378         break;
15379     }
15380
15381   if (!vec_len (name))
15382     {
15383       errmsg ("policer name must be specified");
15384       return -99;
15385     }
15386
15387   if (vec_len (name) > 64)
15388     {
15389       errmsg ("policer name too long");
15390       return -99;
15391     }
15392
15393   M (POLICER_ADD_DEL, mp);
15394
15395   clib_memcpy (mp->name, name, vec_len (name));
15396   vec_free (name);
15397   mp->is_add = is_add;
15398   mp->cir = cir;
15399   mp->eir = eir;
15400   mp->cb = cb;
15401   mp->eb = eb;
15402   mp->rate_type = rate_type;
15403   mp->round_type = round_type;
15404   mp->type = type;
15405   mp->conform_action_type = conform_action.action_type;
15406   mp->conform_dscp = conform_action.dscp;
15407   mp->exceed_action_type = exceed_action.action_type;
15408   mp->exceed_dscp = exceed_action.dscp;
15409   mp->violate_action_type = violate_action.action_type;
15410   mp->violate_dscp = violate_action.dscp;
15411   mp->color_aware = color_aware;
15412
15413   S (mp);
15414   W (ret);
15415   return ret;
15416 }
15417
15418 static int
15419 api_policer_dump (vat_main_t * vam)
15420 {
15421   unformat_input_t *i = vam->input;
15422   vl_api_policer_dump_t *mp;
15423   vl_api_control_ping_t *mp_ping;
15424   u8 *match_name = 0;
15425   u8 match_name_valid = 0;
15426   int ret;
15427
15428   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15429     {
15430       if (unformat (i, "name %s", &match_name))
15431         {
15432           vec_add1 (match_name, 0);
15433           match_name_valid = 1;
15434         }
15435       else
15436         break;
15437     }
15438
15439   M (POLICER_DUMP, mp);
15440   mp->match_name_valid = match_name_valid;
15441   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
15442   vec_free (match_name);
15443   /* send it... */
15444   S (mp);
15445
15446   /* Use a control ping for synchronization */
15447   M (CONTROL_PING, mp_ping);
15448   S (mp_ping);
15449
15450   /* Wait for a reply... */
15451   W (ret);
15452   return ret;
15453 }
15454
15455 static int
15456 api_policer_classify_set_interface (vat_main_t * vam)
15457 {
15458   unformat_input_t *i = vam->input;
15459   vl_api_policer_classify_set_interface_t *mp;
15460   u32 sw_if_index;
15461   int sw_if_index_set;
15462   u32 ip4_table_index = ~0;
15463   u32 ip6_table_index = ~0;
15464   u32 l2_table_index = ~0;
15465   u8 is_add = 1;
15466   int ret;
15467
15468   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15469     {
15470       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15471         sw_if_index_set = 1;
15472       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15473         sw_if_index_set = 1;
15474       else if (unformat (i, "del"))
15475         is_add = 0;
15476       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15477         ;
15478       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15479         ;
15480       else if (unformat (i, "l2-table %d", &l2_table_index))
15481         ;
15482       else
15483         {
15484           clib_warning ("parse error '%U'", format_unformat_error, i);
15485           return -99;
15486         }
15487     }
15488
15489   if (sw_if_index_set == 0)
15490     {
15491       errmsg ("missing interface name or sw_if_index");
15492       return -99;
15493     }
15494
15495   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
15496
15497   mp->sw_if_index = ntohl (sw_if_index);
15498   mp->ip4_table_index = ntohl (ip4_table_index);
15499   mp->ip6_table_index = ntohl (ip6_table_index);
15500   mp->l2_table_index = ntohl (l2_table_index);
15501   mp->is_add = is_add;
15502
15503   S (mp);
15504   W (ret);
15505   return ret;
15506 }
15507
15508 static int
15509 api_policer_classify_dump (vat_main_t * vam)
15510 {
15511   unformat_input_t *i = vam->input;
15512   vl_api_policer_classify_dump_t *mp;
15513   vl_api_control_ping_t *mp_ping;
15514   u8 type = POLICER_CLASSIFY_N_TABLES;
15515   int ret;
15516
15517   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
15518     ;
15519   else
15520     {
15521       errmsg ("classify table type must be specified");
15522       return -99;
15523     }
15524
15525   if (!vam->json_output)
15526     {
15527       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
15528     }
15529
15530   M (POLICER_CLASSIFY_DUMP, mp);
15531   mp->type = type;
15532   /* send it... */
15533   S (mp);
15534
15535   /* Use a control ping for synchronization */
15536   M (CONTROL_PING, mp_ping);
15537   S (mp_ping);
15538
15539   /* Wait for a reply... */
15540   W (ret);
15541   return ret;
15542 }
15543
15544 static int
15545 api_netmap_create (vat_main_t * vam)
15546 {
15547   unformat_input_t *i = vam->input;
15548   vl_api_netmap_create_t *mp;
15549   u8 *if_name = 0;
15550   u8 hw_addr[6];
15551   u8 random_hw_addr = 1;
15552   u8 is_pipe = 0;
15553   u8 is_master = 0;
15554   int ret;
15555
15556   memset (hw_addr, 0, sizeof (hw_addr));
15557
15558   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15559     {
15560       if (unformat (i, "name %s", &if_name))
15561         vec_add1 (if_name, 0);
15562       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15563         random_hw_addr = 0;
15564       else if (unformat (i, "pipe"))
15565         is_pipe = 1;
15566       else if (unformat (i, "master"))
15567         is_master = 1;
15568       else if (unformat (i, "slave"))
15569         is_master = 0;
15570       else
15571         break;
15572     }
15573
15574   if (!vec_len (if_name))
15575     {
15576       errmsg ("interface name must be specified");
15577       return -99;
15578     }
15579
15580   if (vec_len (if_name) > 64)
15581     {
15582       errmsg ("interface name too long");
15583       return -99;
15584     }
15585
15586   M (NETMAP_CREATE, mp);
15587
15588   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15589   clib_memcpy (mp->hw_addr, hw_addr, 6);
15590   mp->use_random_hw_addr = random_hw_addr;
15591   mp->is_pipe = is_pipe;
15592   mp->is_master = is_master;
15593   vec_free (if_name);
15594
15595   S (mp);
15596   W (ret);
15597   return ret;
15598 }
15599
15600 static int
15601 api_netmap_delete (vat_main_t * vam)
15602 {
15603   unformat_input_t *i = vam->input;
15604   vl_api_netmap_delete_t *mp;
15605   u8 *if_name = 0;
15606   int ret;
15607
15608   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15609     {
15610       if (unformat (i, "name %s", &if_name))
15611         vec_add1 (if_name, 0);
15612       else
15613         break;
15614     }
15615
15616   if (!vec_len (if_name))
15617     {
15618       errmsg ("interface name must be specified");
15619       return -99;
15620     }
15621
15622   if (vec_len (if_name) > 64)
15623     {
15624       errmsg ("interface name too long");
15625       return -99;
15626     }
15627
15628   M (NETMAP_DELETE, mp);
15629
15630   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15631   vec_free (if_name);
15632
15633   S (mp);
15634   W (ret);
15635   return ret;
15636 }
15637
15638 static void vl_api_mpls_tunnel_details_t_handler
15639   (vl_api_mpls_tunnel_details_t * mp)
15640 {
15641   vat_main_t *vam = &vat_main;
15642   i32 len = mp->mt_next_hop_n_labels;
15643   i32 i;
15644
15645   print (vam->ofp, "[%d]: via %U %d labels ",
15646          mp->tunnel_index,
15647          format_ip4_address, mp->mt_next_hop,
15648          ntohl (mp->mt_next_hop_sw_if_index));
15649   for (i = 0; i < len; i++)
15650     {
15651       print (vam->ofp, "%u ", ntohl (mp->mt_next_hop_out_labels[i]));
15652     }
15653   print (vam->ofp, "");
15654 }
15655
15656 static void vl_api_mpls_tunnel_details_t_handler_json
15657   (vl_api_mpls_tunnel_details_t * mp)
15658 {
15659   vat_main_t *vam = &vat_main;
15660   vat_json_node_t *node = NULL;
15661   struct in_addr ip4;
15662   i32 i;
15663   i32 len = mp->mt_next_hop_n_labels;
15664
15665   if (VAT_JSON_ARRAY != vam->json_tree.type)
15666     {
15667       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15668       vat_json_init_array (&vam->json_tree);
15669     }
15670   node = vat_json_array_add (&vam->json_tree);
15671
15672   vat_json_init_object (node);
15673   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
15674   clib_memcpy (&ip4, &(mp->mt_next_hop), sizeof (ip4));
15675   vat_json_object_add_ip4 (node, "next_hop", ip4);
15676   vat_json_object_add_uint (node, "next_hop_sw_if_index",
15677                             ntohl (mp->mt_next_hop_sw_if_index));
15678   vat_json_object_add_uint (node, "l2_only", ntohl (mp->mt_l2_only));
15679   vat_json_object_add_uint (node, "label_count", len);
15680   for (i = 0; i < len; i++)
15681     {
15682       vat_json_object_add_uint (node, "label",
15683                                 ntohl (mp->mt_next_hop_out_labels[i]));
15684     }
15685 }
15686
15687 static int
15688 api_mpls_tunnel_dump (vat_main_t * vam)
15689 {
15690   vl_api_mpls_tunnel_dump_t *mp;
15691   vl_api_control_ping_t *mp_ping;
15692   i32 index = -1;
15693   int ret;
15694
15695   /* Parse args required to build the message */
15696   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
15697     {
15698       if (!unformat (vam->input, "tunnel_index %d", &index))
15699         {
15700           index = -1;
15701           break;
15702         }
15703     }
15704
15705   print (vam->ofp, "  tunnel_index %d", index);
15706
15707   M (MPLS_TUNNEL_DUMP, mp);
15708   mp->tunnel_index = htonl (index);
15709   S (mp);
15710
15711   /* Use a control ping for synchronization */
15712   M (CONTROL_PING, mp_ping);
15713   S (mp_ping);
15714
15715   W (ret);
15716   return ret;
15717 }
15718
15719 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
15720 #define vl_api_mpls_fib_details_t_print vl_noop_handler
15721
15722 static void
15723 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
15724 {
15725   vat_main_t *vam = &vat_main;
15726   int count = ntohl (mp->count);
15727   vl_api_fib_path2_t *fp;
15728   int i;
15729
15730   print (vam->ofp,
15731          "table-id %d, label %u, ess_bit %u",
15732          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
15733   fp = mp->path;
15734   for (i = 0; i < count; i++)
15735     {
15736       if (fp->afi == IP46_TYPE_IP6)
15737         print (vam->ofp,
15738                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15739                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15740                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15741                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15742                format_ip6_address, fp->next_hop);
15743       else if (fp->afi == IP46_TYPE_IP4)
15744         print (vam->ofp,
15745                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15746                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15747                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15748                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15749                format_ip4_address, fp->next_hop);
15750       fp++;
15751     }
15752 }
15753
15754 static void vl_api_mpls_fib_details_t_handler_json
15755   (vl_api_mpls_fib_details_t * mp)
15756 {
15757   vat_main_t *vam = &vat_main;
15758   int count = ntohl (mp->count);
15759   vat_json_node_t *node = NULL;
15760   struct in_addr ip4;
15761   struct in6_addr ip6;
15762   vl_api_fib_path2_t *fp;
15763   int i;
15764
15765   if (VAT_JSON_ARRAY != vam->json_tree.type)
15766     {
15767       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15768       vat_json_init_array (&vam->json_tree);
15769     }
15770   node = vat_json_array_add (&vam->json_tree);
15771
15772   vat_json_init_object (node);
15773   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15774   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
15775   vat_json_object_add_uint (node, "label", ntohl (mp->label));
15776   vat_json_object_add_uint (node, "path_count", count);
15777   fp = mp->path;
15778   for (i = 0; i < count; i++)
15779     {
15780       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15781       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15782       vat_json_object_add_uint (node, "is_local", fp->is_local);
15783       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15784       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15785       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15786       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15787       if (fp->afi == IP46_TYPE_IP4)
15788         {
15789           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15790           vat_json_object_add_ip4 (node, "next_hop", ip4);
15791         }
15792       else if (fp->afi == IP46_TYPE_IP6)
15793         {
15794           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15795           vat_json_object_add_ip6 (node, "next_hop", ip6);
15796         }
15797     }
15798 }
15799
15800 static int
15801 api_mpls_fib_dump (vat_main_t * vam)
15802 {
15803   vl_api_mpls_fib_dump_t *mp;
15804   vl_api_control_ping_t *mp_ping;
15805   int ret;
15806
15807   M (MPLS_FIB_DUMP, mp);
15808   S (mp);
15809
15810   /* Use a control ping for synchronization */
15811   M (CONTROL_PING, mp_ping);
15812   S (mp_ping);
15813
15814   W (ret);
15815   return ret;
15816 }
15817
15818 #define vl_api_ip_fib_details_t_endian vl_noop_handler
15819 #define vl_api_ip_fib_details_t_print vl_noop_handler
15820
15821 static void
15822 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
15823 {
15824   vat_main_t *vam = &vat_main;
15825   int count = ntohl (mp->count);
15826   vl_api_fib_path_t *fp;
15827   int i;
15828
15829   print (vam->ofp,
15830          "table-id %d, prefix %U/%d",
15831          ntohl (mp->table_id), format_ip4_address, mp->address,
15832          mp->address_length);
15833   fp = mp->path;
15834   for (i = 0; i < count; i++)
15835     {
15836       if (fp->afi == IP46_TYPE_IP6)
15837         print (vam->ofp,
15838                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15839                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15840                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15841                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15842                format_ip6_address, fp->next_hop);
15843       else if (fp->afi == IP46_TYPE_IP4)
15844         print (vam->ofp,
15845                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15846                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15847                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15848                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15849                format_ip4_address, fp->next_hop);
15850       fp++;
15851     }
15852 }
15853
15854 static void vl_api_ip_fib_details_t_handler_json
15855   (vl_api_ip_fib_details_t * mp)
15856 {
15857   vat_main_t *vam = &vat_main;
15858   int count = ntohl (mp->count);
15859   vat_json_node_t *node = NULL;
15860   struct in_addr ip4;
15861   struct in6_addr ip6;
15862   vl_api_fib_path_t *fp;
15863   int i;
15864
15865   if (VAT_JSON_ARRAY != vam->json_tree.type)
15866     {
15867       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15868       vat_json_init_array (&vam->json_tree);
15869     }
15870   node = vat_json_array_add (&vam->json_tree);
15871
15872   vat_json_init_object (node);
15873   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15874   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
15875   vat_json_object_add_ip4 (node, "prefix", ip4);
15876   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15877   vat_json_object_add_uint (node, "path_count", count);
15878   fp = mp->path;
15879   for (i = 0; i < count; i++)
15880     {
15881       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15882       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15883       vat_json_object_add_uint (node, "is_local", fp->is_local);
15884       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15885       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15886       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15887       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15888       if (fp->afi == IP46_TYPE_IP4)
15889         {
15890           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15891           vat_json_object_add_ip4 (node, "next_hop", ip4);
15892         }
15893       else if (fp->afi == IP46_TYPE_IP6)
15894         {
15895           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15896           vat_json_object_add_ip6 (node, "next_hop", ip6);
15897         }
15898     }
15899 }
15900
15901 static int
15902 api_ip_fib_dump (vat_main_t * vam)
15903 {
15904   vl_api_ip_fib_dump_t *mp;
15905   vl_api_control_ping_t *mp_ping;
15906   int ret;
15907
15908   M (IP_FIB_DUMP, mp);
15909   S (mp);
15910
15911   /* Use a control ping for synchronization */
15912   M (CONTROL_PING, mp_ping);
15913   S (mp_ping);
15914
15915   W (ret);
15916   return ret;
15917 }
15918
15919 static int
15920 api_ip_mfib_dump (vat_main_t * vam)
15921 {
15922   vl_api_ip_mfib_dump_t *mp;
15923   vl_api_control_ping_t *mp_ping;
15924   int ret;
15925
15926   M (IP_MFIB_DUMP, mp);
15927   S (mp);
15928
15929   /* Use a control ping for synchronization */
15930   M (CONTROL_PING, mp_ping);
15931   S (mp_ping);
15932
15933   W (ret);
15934   return ret;
15935 }
15936
15937 static void vl_api_ip_neighbor_details_t_handler
15938   (vl_api_ip_neighbor_details_t * mp)
15939 {
15940   vat_main_t *vam = &vat_main;
15941
15942   print (vam->ofp, "%c %U %U",
15943          (mp->is_static) ? 'S' : 'D',
15944          format_ethernet_address, &mp->mac_address,
15945          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
15946          &mp->ip_address);
15947 }
15948
15949 static void vl_api_ip_neighbor_details_t_handler_json
15950   (vl_api_ip_neighbor_details_t * mp)
15951 {
15952
15953   vat_main_t *vam = &vat_main;
15954   vat_json_node_t *node;
15955   struct in_addr ip4;
15956   struct in6_addr ip6;
15957
15958   if (VAT_JSON_ARRAY != vam->json_tree.type)
15959     {
15960       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15961       vat_json_init_array (&vam->json_tree);
15962     }
15963   node = vat_json_array_add (&vam->json_tree);
15964
15965   vat_json_init_object (node);
15966   vat_json_object_add_string_copy (node, "flag",
15967                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
15968                                    "dynamic");
15969
15970   vat_json_object_add_string_copy (node, "link_layer",
15971                                    format (0, "%U", format_ethernet_address,
15972                                            &mp->mac_address));
15973
15974   if (mp->is_ipv6)
15975     {
15976       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
15977       vat_json_object_add_ip6 (node, "ip_address", ip6);
15978     }
15979   else
15980     {
15981       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
15982       vat_json_object_add_ip4 (node, "ip_address", ip4);
15983     }
15984 }
15985
15986 static int
15987 api_ip_neighbor_dump (vat_main_t * vam)
15988 {
15989   unformat_input_t *i = vam->input;
15990   vl_api_ip_neighbor_dump_t *mp;
15991   vl_api_control_ping_t *mp_ping;
15992   u8 is_ipv6 = 0;
15993   u32 sw_if_index = ~0;
15994   int ret;
15995
15996   /* Parse args required to build the message */
15997   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15998     {
15999       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16000         ;
16001       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16002         ;
16003       else if (unformat (i, "ip6"))
16004         is_ipv6 = 1;
16005       else
16006         break;
16007     }
16008
16009   if (sw_if_index == ~0)
16010     {
16011       errmsg ("missing interface name or sw_if_index");
16012       return -99;
16013     }
16014
16015   M (IP_NEIGHBOR_DUMP, mp);
16016   mp->is_ipv6 = (u8) is_ipv6;
16017   mp->sw_if_index = ntohl (sw_if_index);
16018   S (mp);
16019
16020   /* Use a control ping for synchronization */
16021   M (CONTROL_PING, mp_ping);
16022   S (mp_ping);
16023
16024   W (ret);
16025   return ret;
16026 }
16027
16028 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
16029 #define vl_api_ip6_fib_details_t_print vl_noop_handler
16030
16031 static void
16032 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
16033 {
16034   vat_main_t *vam = &vat_main;
16035   int count = ntohl (mp->count);
16036   vl_api_fib_path_t *fp;
16037   int i;
16038
16039   print (vam->ofp,
16040          "table-id %d, prefix %U/%d",
16041          ntohl (mp->table_id), format_ip6_address, mp->address,
16042          mp->address_length);
16043   fp = mp->path;
16044   for (i = 0; i < count; i++)
16045     {
16046       if (fp->afi == IP46_TYPE_IP6)
16047         print (vam->ofp,
16048                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16049                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16050                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16051                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16052                format_ip6_address, fp->next_hop);
16053       else if (fp->afi == IP46_TYPE_IP4)
16054         print (vam->ofp,
16055                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16056                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16057                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16058                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16059                format_ip4_address, fp->next_hop);
16060       fp++;
16061     }
16062 }
16063
16064 static void vl_api_ip6_fib_details_t_handler_json
16065   (vl_api_ip6_fib_details_t * mp)
16066 {
16067   vat_main_t *vam = &vat_main;
16068   int count = ntohl (mp->count);
16069   vat_json_node_t *node = NULL;
16070   struct in_addr ip4;
16071   struct in6_addr ip6;
16072   vl_api_fib_path_t *fp;
16073   int i;
16074
16075   if (VAT_JSON_ARRAY != vam->json_tree.type)
16076     {
16077       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16078       vat_json_init_array (&vam->json_tree);
16079     }
16080   node = vat_json_array_add (&vam->json_tree);
16081
16082   vat_json_init_object (node);
16083   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16084   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
16085   vat_json_object_add_ip6 (node, "prefix", ip6);
16086   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16087   vat_json_object_add_uint (node, "path_count", count);
16088   fp = mp->path;
16089   for (i = 0; i < count; i++)
16090     {
16091       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16092       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16093       vat_json_object_add_uint (node, "is_local", fp->is_local);
16094       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16095       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16096       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16097       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16098       if (fp->afi == IP46_TYPE_IP4)
16099         {
16100           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16101           vat_json_object_add_ip4 (node, "next_hop", ip4);
16102         }
16103       else if (fp->afi == IP46_TYPE_IP6)
16104         {
16105           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16106           vat_json_object_add_ip6 (node, "next_hop", ip6);
16107         }
16108     }
16109 }
16110
16111 static int
16112 api_ip6_fib_dump (vat_main_t * vam)
16113 {
16114   vl_api_ip6_fib_dump_t *mp;
16115   vl_api_control_ping_t *mp_ping;
16116   int ret;
16117
16118   M (IP6_FIB_DUMP, mp);
16119   S (mp);
16120
16121   /* Use a control ping for synchronization */
16122   M (CONTROL_PING, mp_ping);
16123   S (mp_ping);
16124
16125   W (ret);
16126   return ret;
16127 }
16128
16129 static int
16130 api_ip6_mfib_dump (vat_main_t * vam)
16131 {
16132   vl_api_ip6_mfib_dump_t *mp;
16133   vl_api_control_ping_t *mp_ping;
16134   int ret;
16135
16136   M (IP6_MFIB_DUMP, mp);
16137   S (mp);
16138
16139   /* Use a control ping for synchronization */
16140   M (CONTROL_PING, mp_ping);
16141   S (mp_ping);
16142
16143   W (ret);
16144   return ret;
16145 }
16146
16147 int
16148 api_classify_table_ids (vat_main_t * vam)
16149 {
16150   vl_api_classify_table_ids_t *mp;
16151   int ret;
16152
16153   /* Construct the API message */
16154   M (CLASSIFY_TABLE_IDS, mp);
16155   mp->context = 0;
16156
16157   S (mp);
16158   W (ret);
16159   return ret;
16160 }
16161
16162 int
16163 api_classify_table_by_interface (vat_main_t * vam)
16164 {
16165   unformat_input_t *input = vam->input;
16166   vl_api_classify_table_by_interface_t *mp;
16167
16168   u32 sw_if_index = ~0;
16169   int ret;
16170   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16171     {
16172       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16173         ;
16174       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16175         ;
16176       else
16177         break;
16178     }
16179   if (sw_if_index == ~0)
16180     {
16181       errmsg ("missing interface name or sw_if_index");
16182       return -99;
16183     }
16184
16185   /* Construct the API message */
16186   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
16187   mp->context = 0;
16188   mp->sw_if_index = ntohl (sw_if_index);
16189
16190   S (mp);
16191   W (ret);
16192   return ret;
16193 }
16194
16195 int
16196 api_classify_table_info (vat_main_t * vam)
16197 {
16198   unformat_input_t *input = vam->input;
16199   vl_api_classify_table_info_t *mp;
16200
16201   u32 table_id = ~0;
16202   int ret;
16203   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16204     {
16205       if (unformat (input, "table_id %d", &table_id))
16206         ;
16207       else
16208         break;
16209     }
16210   if (table_id == ~0)
16211     {
16212       errmsg ("missing table id");
16213       return -99;
16214     }
16215
16216   /* Construct the API message */
16217   M (CLASSIFY_TABLE_INFO, mp);
16218   mp->context = 0;
16219   mp->table_id = ntohl (table_id);
16220
16221   S (mp);
16222   W (ret);
16223   return ret;
16224 }
16225
16226 int
16227 api_classify_session_dump (vat_main_t * vam)
16228 {
16229   unformat_input_t *input = vam->input;
16230   vl_api_classify_session_dump_t *mp;
16231   vl_api_control_ping_t *mp_ping;
16232
16233   u32 table_id = ~0;
16234   int ret;
16235   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16236     {
16237       if (unformat (input, "table_id %d", &table_id))
16238         ;
16239       else
16240         break;
16241     }
16242   if (table_id == ~0)
16243     {
16244       errmsg ("missing table id");
16245       return -99;
16246     }
16247
16248   /* Construct the API message */
16249   M (CLASSIFY_SESSION_DUMP, mp);
16250   mp->context = 0;
16251   mp->table_id = ntohl (table_id);
16252   S (mp);
16253
16254   /* Use a control ping for synchronization */
16255   M (CONTROL_PING, mp_ping);
16256   S (mp_ping);
16257
16258   W (ret);
16259   return ret;
16260 }
16261
16262 static void
16263 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
16264 {
16265   vat_main_t *vam = &vat_main;
16266
16267   print (vam->ofp, "collector_address %U, collector_port %d, "
16268          "src_address %U, vrf_id %d, path_mtu %u, "
16269          "template_interval %u, udp_checksum %d",
16270          format_ip4_address, mp->collector_address,
16271          ntohs (mp->collector_port),
16272          format_ip4_address, mp->src_address,
16273          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
16274          ntohl (mp->template_interval), mp->udp_checksum);
16275
16276   vam->retval = 0;
16277   vam->result_ready = 1;
16278 }
16279
16280 static void
16281   vl_api_ipfix_exporter_details_t_handler_json
16282   (vl_api_ipfix_exporter_details_t * mp)
16283 {
16284   vat_main_t *vam = &vat_main;
16285   vat_json_node_t node;
16286   struct in_addr collector_address;
16287   struct in_addr src_address;
16288
16289   vat_json_init_object (&node);
16290   clib_memcpy (&collector_address, &mp->collector_address,
16291                sizeof (collector_address));
16292   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
16293   vat_json_object_add_uint (&node, "collector_port",
16294                             ntohs (mp->collector_port));
16295   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
16296   vat_json_object_add_ip4 (&node, "src_address", src_address);
16297   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
16298   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
16299   vat_json_object_add_uint (&node, "template_interval",
16300                             ntohl (mp->template_interval));
16301   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
16302
16303   vat_json_print (vam->ofp, &node);
16304   vat_json_free (&node);
16305   vam->retval = 0;
16306   vam->result_ready = 1;
16307 }
16308
16309 int
16310 api_ipfix_exporter_dump (vat_main_t * vam)
16311 {
16312   vl_api_ipfix_exporter_dump_t *mp;
16313   int ret;
16314
16315   /* Construct the API message */
16316   M (IPFIX_EXPORTER_DUMP, mp);
16317   mp->context = 0;
16318
16319   S (mp);
16320   W (ret);
16321   return ret;
16322 }
16323
16324 static int
16325 api_ipfix_classify_stream_dump (vat_main_t * vam)
16326 {
16327   vl_api_ipfix_classify_stream_dump_t *mp;
16328   int ret;
16329
16330   /* Construct the API message */
16331   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
16332   mp->context = 0;
16333
16334   S (mp);
16335   W (ret);
16336   return ret;
16337   /* NOTREACHED */
16338   return 0;
16339 }
16340
16341 static void
16342   vl_api_ipfix_classify_stream_details_t_handler
16343   (vl_api_ipfix_classify_stream_details_t * mp)
16344 {
16345   vat_main_t *vam = &vat_main;
16346   print (vam->ofp, "domain_id %d, src_port %d",
16347          ntohl (mp->domain_id), ntohs (mp->src_port));
16348   vam->retval = 0;
16349   vam->result_ready = 1;
16350 }
16351
16352 static void
16353   vl_api_ipfix_classify_stream_details_t_handler_json
16354   (vl_api_ipfix_classify_stream_details_t * mp)
16355 {
16356   vat_main_t *vam = &vat_main;
16357   vat_json_node_t node;
16358
16359   vat_json_init_object (&node);
16360   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
16361   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
16362
16363   vat_json_print (vam->ofp, &node);
16364   vat_json_free (&node);
16365   vam->retval = 0;
16366   vam->result_ready = 1;
16367 }
16368
16369 static int
16370 api_ipfix_classify_table_dump (vat_main_t * vam)
16371 {
16372   vl_api_ipfix_classify_table_dump_t *mp;
16373   vl_api_control_ping_t *mp_ping;
16374   int ret;
16375
16376   if (!vam->json_output)
16377     {
16378       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
16379              "transport_protocol");
16380     }
16381
16382   /* Construct the API message */
16383   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
16384
16385   /* send it... */
16386   S (mp);
16387
16388   /* Use a control ping for synchronization */
16389   M (CONTROL_PING, mp_ping);
16390   S (mp_ping);
16391
16392   W (ret);
16393   return ret;
16394 }
16395
16396 static void
16397   vl_api_ipfix_classify_table_details_t_handler
16398   (vl_api_ipfix_classify_table_details_t * mp)
16399 {
16400   vat_main_t *vam = &vat_main;
16401   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
16402          mp->transport_protocol);
16403 }
16404
16405 static void
16406   vl_api_ipfix_classify_table_details_t_handler_json
16407   (vl_api_ipfix_classify_table_details_t * mp)
16408 {
16409   vat_json_node_t *node = NULL;
16410   vat_main_t *vam = &vat_main;
16411
16412   if (VAT_JSON_ARRAY != vam->json_tree.type)
16413     {
16414       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16415       vat_json_init_array (&vam->json_tree);
16416     }
16417
16418   node = vat_json_array_add (&vam->json_tree);
16419   vat_json_init_object (node);
16420
16421   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
16422   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
16423   vat_json_object_add_uint (node, "transport_protocol",
16424                             mp->transport_protocol);
16425 }
16426
16427 static int
16428 api_sw_interface_span_enable_disable (vat_main_t * vam)
16429 {
16430   unformat_input_t *i = vam->input;
16431   vl_api_sw_interface_span_enable_disable_t *mp;
16432   u32 src_sw_if_index = ~0;
16433   u32 dst_sw_if_index = ~0;
16434   u8 state = 3;
16435   int ret;
16436
16437   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16438     {
16439       if (unformat
16440           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
16441         ;
16442       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
16443         ;
16444       else
16445         if (unformat
16446             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
16447         ;
16448       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
16449         ;
16450       else if (unformat (i, "disable"))
16451         state = 0;
16452       else if (unformat (i, "rx"))
16453         state = 1;
16454       else if (unformat (i, "tx"))
16455         state = 2;
16456       else if (unformat (i, "both"))
16457         state = 3;
16458       else
16459         break;
16460     }
16461
16462   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
16463
16464   mp->sw_if_index_from = htonl (src_sw_if_index);
16465   mp->sw_if_index_to = htonl (dst_sw_if_index);
16466   mp->state = state;
16467
16468   S (mp);
16469   W (ret);
16470   return ret;
16471 }
16472
16473 static void
16474 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
16475                                             * mp)
16476 {
16477   vat_main_t *vam = &vat_main;
16478   u8 *sw_if_from_name = 0;
16479   u8 *sw_if_to_name = 0;
16480   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16481   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16482   char *states[] = { "none", "rx", "tx", "both" };
16483   hash_pair_t *p;
16484
16485   /* *INDENT-OFF* */
16486   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16487   ({
16488     if ((u32) p->value[0] == sw_if_index_from)
16489       {
16490         sw_if_from_name = (u8 *)(p->key);
16491         if (sw_if_to_name)
16492           break;
16493       }
16494     if ((u32) p->value[0] == sw_if_index_to)
16495       {
16496         sw_if_to_name = (u8 *)(p->key);
16497         if (sw_if_from_name)
16498           break;
16499       }
16500   }));
16501   /* *INDENT-ON* */
16502   print (vam->ofp, "%20s => %20s (%s)",
16503          sw_if_from_name, sw_if_to_name, states[mp->state]);
16504 }
16505
16506 static void
16507   vl_api_sw_interface_span_details_t_handler_json
16508   (vl_api_sw_interface_span_details_t * mp)
16509 {
16510   vat_main_t *vam = &vat_main;
16511   vat_json_node_t *node = NULL;
16512   u8 *sw_if_from_name = 0;
16513   u8 *sw_if_to_name = 0;
16514   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16515   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16516   hash_pair_t *p;
16517
16518   /* *INDENT-OFF* */
16519   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16520   ({
16521     if ((u32) p->value[0] == sw_if_index_from)
16522       {
16523         sw_if_from_name = (u8 *)(p->key);
16524         if (sw_if_to_name)
16525           break;
16526       }
16527     if ((u32) p->value[0] == sw_if_index_to)
16528       {
16529         sw_if_to_name = (u8 *)(p->key);
16530         if (sw_if_from_name)
16531           break;
16532       }
16533   }));
16534   /* *INDENT-ON* */
16535
16536   if (VAT_JSON_ARRAY != vam->json_tree.type)
16537     {
16538       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16539       vat_json_init_array (&vam->json_tree);
16540     }
16541   node = vat_json_array_add (&vam->json_tree);
16542
16543   vat_json_init_object (node);
16544   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
16545   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
16546   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
16547   if (0 != sw_if_to_name)
16548     {
16549       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
16550     }
16551   vat_json_object_add_uint (node, "state", mp->state);
16552 }
16553
16554 static int
16555 api_sw_interface_span_dump (vat_main_t * vam)
16556 {
16557   vl_api_sw_interface_span_dump_t *mp;
16558   vl_api_control_ping_t *mp_ping;
16559   int ret;
16560
16561   M (SW_INTERFACE_SPAN_DUMP, mp);
16562   S (mp);
16563
16564   /* Use a control ping for synchronization */
16565   M (CONTROL_PING, mp_ping);
16566   S (mp_ping);
16567
16568   W (ret);
16569   return ret;
16570 }
16571
16572 int
16573 api_pg_create_interface (vat_main_t * vam)
16574 {
16575   unformat_input_t *input = vam->input;
16576   vl_api_pg_create_interface_t *mp;
16577
16578   u32 if_id = ~0;
16579   int ret;
16580   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16581     {
16582       if (unformat (input, "if_id %d", &if_id))
16583         ;
16584       else
16585         break;
16586     }
16587   if (if_id == ~0)
16588     {
16589       errmsg ("missing pg interface index");
16590       return -99;
16591     }
16592
16593   /* Construct the API message */
16594   M (PG_CREATE_INTERFACE, mp);
16595   mp->context = 0;
16596   mp->interface_id = ntohl (if_id);
16597
16598   S (mp);
16599   W (ret);
16600   return ret;
16601 }
16602
16603 int
16604 api_pg_capture (vat_main_t * vam)
16605 {
16606   unformat_input_t *input = vam->input;
16607   vl_api_pg_capture_t *mp;
16608
16609   u32 if_id = ~0;
16610   u8 enable = 1;
16611   u32 count = 1;
16612   u8 pcap_file_set = 0;
16613   u8 *pcap_file = 0;
16614   int ret;
16615   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16616     {
16617       if (unformat (input, "if_id %d", &if_id))
16618         ;
16619       else if (unformat (input, "pcap %s", &pcap_file))
16620         pcap_file_set = 1;
16621       else if (unformat (input, "count %d", &count))
16622         ;
16623       else if (unformat (input, "disable"))
16624         enable = 0;
16625       else
16626         break;
16627     }
16628   if (if_id == ~0)
16629     {
16630       errmsg ("missing pg interface index");
16631       return -99;
16632     }
16633   if (pcap_file_set > 0)
16634     {
16635       if (vec_len (pcap_file) > 255)
16636         {
16637           errmsg ("pcap file name is too long");
16638           return -99;
16639         }
16640     }
16641
16642   u32 name_len = vec_len (pcap_file);
16643   /* Construct the API message */
16644   M (PG_CAPTURE, mp);
16645   mp->context = 0;
16646   mp->interface_id = ntohl (if_id);
16647   mp->is_enabled = enable;
16648   mp->count = ntohl (count);
16649   mp->pcap_name_length = ntohl (name_len);
16650   if (pcap_file_set != 0)
16651     {
16652       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
16653     }
16654   vec_free (pcap_file);
16655
16656   S (mp);
16657   W (ret);
16658   return ret;
16659 }
16660
16661 int
16662 api_pg_enable_disable (vat_main_t * vam)
16663 {
16664   unformat_input_t *input = vam->input;
16665   vl_api_pg_enable_disable_t *mp;
16666
16667   u8 enable = 1;
16668   u8 stream_name_set = 0;
16669   u8 *stream_name = 0;
16670   int ret;
16671   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16672     {
16673       if (unformat (input, "stream %s", &stream_name))
16674         stream_name_set = 1;
16675       else if (unformat (input, "disable"))
16676         enable = 0;
16677       else
16678         break;
16679     }
16680
16681   if (stream_name_set > 0)
16682     {
16683       if (vec_len (stream_name) > 255)
16684         {
16685           errmsg ("stream name too long");
16686           return -99;
16687         }
16688     }
16689
16690   u32 name_len = vec_len (stream_name);
16691   /* Construct the API message */
16692   M (PG_ENABLE_DISABLE, mp);
16693   mp->context = 0;
16694   mp->is_enabled = enable;
16695   if (stream_name_set != 0)
16696     {
16697       mp->stream_name_length = ntohl (name_len);
16698       clib_memcpy (mp->stream_name, stream_name, name_len);
16699     }
16700   vec_free (stream_name);
16701
16702   S (mp);
16703   W (ret);
16704   return ret;
16705 }
16706
16707 int
16708 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
16709 {
16710   unformat_input_t *input = vam->input;
16711   vl_api_ip_source_and_port_range_check_add_del_t *mp;
16712
16713   u16 *low_ports = 0;
16714   u16 *high_ports = 0;
16715   u16 this_low;
16716   u16 this_hi;
16717   ip4_address_t ip4_addr;
16718   ip6_address_t ip6_addr;
16719   u32 length;
16720   u32 tmp, tmp2;
16721   u8 prefix_set = 0;
16722   u32 vrf_id = ~0;
16723   u8 is_add = 1;
16724   u8 is_ipv6 = 0;
16725   int ret;
16726
16727   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16728     {
16729       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
16730         {
16731           prefix_set = 1;
16732         }
16733       else
16734         if (unformat
16735             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
16736         {
16737           prefix_set = 1;
16738           is_ipv6 = 1;
16739         }
16740       else if (unformat (input, "vrf %d", &vrf_id))
16741         ;
16742       else if (unformat (input, "del"))
16743         is_add = 0;
16744       else if (unformat (input, "port %d", &tmp))
16745         {
16746           if (tmp == 0 || tmp > 65535)
16747             {
16748               errmsg ("port %d out of range", tmp);
16749               return -99;
16750             }
16751           this_low = tmp;
16752           this_hi = this_low + 1;
16753           vec_add1 (low_ports, this_low);
16754           vec_add1 (high_ports, this_hi);
16755         }
16756       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
16757         {
16758           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
16759             {
16760               errmsg ("incorrect range parameters");
16761               return -99;
16762             }
16763           this_low = tmp;
16764           /* Note: in debug CLI +1 is added to high before
16765              passing to real fn that does "the work"
16766              (ip_source_and_port_range_check_add_del).
16767              This fn is a wrapper around the binary API fn a
16768              control plane will call, which expects this increment
16769              to have occurred. Hence letting the binary API control
16770              plane fn do the increment for consistency between VAT
16771              and other control planes.
16772            */
16773           this_hi = tmp2;
16774           vec_add1 (low_ports, this_low);
16775           vec_add1 (high_ports, this_hi);
16776         }
16777       else
16778         break;
16779     }
16780
16781   if (prefix_set == 0)
16782     {
16783       errmsg ("<address>/<mask> not specified");
16784       return -99;
16785     }
16786
16787   if (vrf_id == ~0)
16788     {
16789       errmsg ("VRF ID required, not specified");
16790       return -99;
16791     }
16792
16793   if (vrf_id == 0)
16794     {
16795       errmsg
16796         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
16797       return -99;
16798     }
16799
16800   if (vec_len (low_ports) == 0)
16801     {
16802       errmsg ("At least one port or port range required");
16803       return -99;
16804     }
16805
16806   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
16807
16808   mp->is_add = is_add;
16809
16810   if (is_ipv6)
16811     {
16812       mp->is_ipv6 = 1;
16813       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
16814     }
16815   else
16816     {
16817       mp->is_ipv6 = 0;
16818       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
16819     }
16820
16821   mp->mask_length = length;
16822   mp->number_of_ranges = vec_len (low_ports);
16823
16824   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
16825   vec_free (low_ports);
16826
16827   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
16828   vec_free (high_ports);
16829
16830   mp->vrf_id = ntohl (vrf_id);
16831
16832   S (mp);
16833   W (ret);
16834   return ret;
16835 }
16836
16837 int
16838 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
16839 {
16840   unformat_input_t *input = vam->input;
16841   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
16842   u32 sw_if_index = ~0;
16843   int vrf_set = 0;
16844   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
16845   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
16846   u8 is_add = 1;
16847   int ret;
16848
16849   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16850     {
16851       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16852         ;
16853       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16854         ;
16855       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
16856         vrf_set = 1;
16857       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
16858         vrf_set = 1;
16859       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
16860         vrf_set = 1;
16861       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
16862         vrf_set = 1;
16863       else if (unformat (input, "del"))
16864         is_add = 0;
16865       else
16866         break;
16867     }
16868
16869   if (sw_if_index == ~0)
16870     {
16871       errmsg ("Interface required but not specified");
16872       return -99;
16873     }
16874
16875   if (vrf_set == 0)
16876     {
16877       errmsg ("VRF ID required but not specified");
16878       return -99;
16879     }
16880
16881   if (tcp_out_vrf_id == 0
16882       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
16883     {
16884       errmsg
16885         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
16886       return -99;
16887     }
16888
16889   /* Construct the API message */
16890   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
16891
16892   mp->sw_if_index = ntohl (sw_if_index);
16893   mp->is_add = is_add;
16894   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
16895   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
16896   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
16897   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
16898
16899   /* send it... */
16900   S (mp);
16901
16902   /* Wait for a reply... */
16903   W (ret);
16904   return ret;
16905 }
16906
16907 static int
16908 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
16909 {
16910   unformat_input_t *i = vam->input;
16911   vl_api_ipsec_gre_add_del_tunnel_t *mp;
16912   u32 local_sa_id = 0;
16913   u32 remote_sa_id = 0;
16914   ip4_address_t src_address;
16915   ip4_address_t dst_address;
16916   u8 is_add = 1;
16917   int ret;
16918
16919   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16920     {
16921       if (unformat (i, "local_sa %d", &local_sa_id))
16922         ;
16923       else if (unformat (i, "remote_sa %d", &remote_sa_id))
16924         ;
16925       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
16926         ;
16927       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
16928         ;
16929       else if (unformat (i, "del"))
16930         is_add = 0;
16931       else
16932         {
16933           clib_warning ("parse error '%U'", format_unformat_error, i);
16934           return -99;
16935         }
16936     }
16937
16938   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
16939
16940   mp->local_sa_id = ntohl (local_sa_id);
16941   mp->remote_sa_id = ntohl (remote_sa_id);
16942   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
16943   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
16944   mp->is_add = is_add;
16945
16946   S (mp);
16947   W (ret);
16948   return ret;
16949 }
16950
16951 static int
16952 api_punt (vat_main_t * vam)
16953 {
16954   unformat_input_t *i = vam->input;
16955   vl_api_punt_t *mp;
16956   u32 ipv = ~0;
16957   u32 protocol = ~0;
16958   u32 port = ~0;
16959   int is_add = 1;
16960   int ret;
16961
16962   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16963     {
16964       if (unformat (i, "ip %d", &ipv))
16965         ;
16966       else if (unformat (i, "protocol %d", &protocol))
16967         ;
16968       else if (unformat (i, "port %d", &port))
16969         ;
16970       else if (unformat (i, "del"))
16971         is_add = 0;
16972       else
16973         {
16974           clib_warning ("parse error '%U'", format_unformat_error, i);
16975           return -99;
16976         }
16977     }
16978
16979   M (PUNT, mp);
16980
16981   mp->is_add = (u8) is_add;
16982   mp->ipv = (u8) ipv;
16983   mp->l4_protocol = (u8) protocol;
16984   mp->l4_port = htons ((u16) port);
16985
16986   S (mp);
16987   W (ret);
16988   return ret;
16989 }
16990
16991 static void vl_api_ipsec_gre_tunnel_details_t_handler
16992   (vl_api_ipsec_gre_tunnel_details_t * mp)
16993 {
16994   vat_main_t *vam = &vat_main;
16995
16996   print (vam->ofp, "%11d%15U%15U%14d%14d",
16997          ntohl (mp->sw_if_index),
16998          format_ip4_address, &mp->src_address,
16999          format_ip4_address, &mp->dst_address,
17000          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
17001 }
17002
17003 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
17004   (vl_api_ipsec_gre_tunnel_details_t * mp)
17005 {
17006   vat_main_t *vam = &vat_main;
17007   vat_json_node_t *node = NULL;
17008   struct in_addr ip4;
17009
17010   if (VAT_JSON_ARRAY != vam->json_tree.type)
17011     {
17012       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17013       vat_json_init_array (&vam->json_tree);
17014     }
17015   node = vat_json_array_add (&vam->json_tree);
17016
17017   vat_json_init_object (node);
17018   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17019   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
17020   vat_json_object_add_ip4 (node, "src_address", ip4);
17021   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
17022   vat_json_object_add_ip4 (node, "dst_address", ip4);
17023   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
17024   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
17025 }
17026
17027 static int
17028 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
17029 {
17030   unformat_input_t *i = vam->input;
17031   vl_api_ipsec_gre_tunnel_dump_t *mp;
17032   vl_api_control_ping_t *mp_ping;
17033   u32 sw_if_index;
17034   u8 sw_if_index_set = 0;
17035   int ret;
17036
17037   /* Parse args required to build the message */
17038   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17039     {
17040       if (unformat (i, "sw_if_index %d", &sw_if_index))
17041         sw_if_index_set = 1;
17042       else
17043         break;
17044     }
17045
17046   if (sw_if_index_set == 0)
17047     {
17048       sw_if_index = ~0;
17049     }
17050
17051   if (!vam->json_output)
17052     {
17053       print (vam->ofp, "%11s%15s%15s%14s%14s",
17054              "sw_if_index", "src_address", "dst_address",
17055              "local_sa_id", "remote_sa_id");
17056     }
17057
17058   /* Get list of gre-tunnel interfaces */
17059   M (IPSEC_GRE_TUNNEL_DUMP, mp);
17060
17061   mp->sw_if_index = htonl (sw_if_index);
17062
17063   S (mp);
17064
17065   /* Use a control ping for synchronization */
17066   M (CONTROL_PING, mp_ping);
17067   S (mp_ping);
17068
17069   W (ret);
17070   return ret;
17071 }
17072
17073 static int
17074 api_delete_subif (vat_main_t * vam)
17075 {
17076   unformat_input_t *i = vam->input;
17077   vl_api_delete_subif_t *mp;
17078   u32 sw_if_index = ~0;
17079   int ret;
17080
17081   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17082     {
17083       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17084         ;
17085       if (unformat (i, "sw_if_index %d", &sw_if_index))
17086         ;
17087       else
17088         break;
17089     }
17090
17091   if (sw_if_index == ~0)
17092     {
17093       errmsg ("missing sw_if_index");
17094       return -99;
17095     }
17096
17097   /* Construct the API message */
17098   M (DELETE_SUBIF, mp);
17099   mp->sw_if_index = ntohl (sw_if_index);
17100
17101   S (mp);
17102   W (ret);
17103   return ret;
17104 }
17105
17106 #define foreach_pbb_vtr_op      \
17107 _("disable",  L2_VTR_DISABLED)  \
17108 _("pop",  L2_VTR_POP_2)         \
17109 _("push",  L2_VTR_PUSH_2)
17110
17111 static int
17112 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
17113 {
17114   unformat_input_t *i = vam->input;
17115   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
17116   u32 sw_if_index = ~0, vtr_op = ~0;
17117   u16 outer_tag = ~0;
17118   u8 dmac[6], smac[6];
17119   u8 dmac_set = 0, smac_set = 0;
17120   u16 vlanid = 0;
17121   u32 sid = ~0;
17122   u32 tmp;
17123   int ret;
17124
17125   /* Shut up coverity */
17126   memset (dmac, 0, sizeof (dmac));
17127   memset (smac, 0, sizeof (smac));
17128
17129   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17130     {
17131       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17132         ;
17133       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17134         ;
17135       else if (unformat (i, "vtr_op %d", &vtr_op))
17136         ;
17137 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
17138       foreach_pbb_vtr_op
17139 #undef _
17140         else if (unformat (i, "translate_pbb_stag"))
17141         {
17142           if (unformat (i, "%d", &tmp))
17143             {
17144               vtr_op = L2_VTR_TRANSLATE_2_1;
17145               outer_tag = tmp;
17146             }
17147           else
17148             {
17149               errmsg
17150                 ("translate_pbb_stag operation requires outer tag definition");
17151               return -99;
17152             }
17153         }
17154       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
17155         dmac_set++;
17156       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
17157         smac_set++;
17158       else if (unformat (i, "sid %d", &sid))
17159         ;
17160       else if (unformat (i, "vlanid %d", &tmp))
17161         vlanid = tmp;
17162       else
17163         {
17164           clib_warning ("parse error '%U'", format_unformat_error, i);
17165           return -99;
17166         }
17167     }
17168
17169   if ((sw_if_index == ~0) || (vtr_op == ~0))
17170     {
17171       errmsg ("missing sw_if_index or vtr operation");
17172       return -99;
17173     }
17174   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
17175       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
17176     {
17177       errmsg
17178         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
17179       return -99;
17180     }
17181
17182   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
17183   mp->sw_if_index = ntohl (sw_if_index);
17184   mp->vtr_op = ntohl (vtr_op);
17185   mp->outer_tag = ntohs (outer_tag);
17186   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
17187   clib_memcpy (mp->b_smac, smac, sizeof (smac));
17188   mp->b_vlanid = ntohs (vlanid);
17189   mp->i_sid = ntohl (sid);
17190
17191   S (mp);
17192   W (ret);
17193   return ret;
17194 }
17195
17196 static int
17197 api_flow_classify_set_interface (vat_main_t * vam)
17198 {
17199   unformat_input_t *i = vam->input;
17200   vl_api_flow_classify_set_interface_t *mp;
17201   u32 sw_if_index;
17202   int sw_if_index_set;
17203   u32 ip4_table_index = ~0;
17204   u32 ip6_table_index = ~0;
17205   u8 is_add = 1;
17206   int ret;
17207
17208   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17209     {
17210       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17211         sw_if_index_set = 1;
17212       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17213         sw_if_index_set = 1;
17214       else if (unformat (i, "del"))
17215         is_add = 0;
17216       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17217         ;
17218       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17219         ;
17220       else
17221         {
17222           clib_warning ("parse error '%U'", format_unformat_error, i);
17223           return -99;
17224         }
17225     }
17226
17227   if (sw_if_index_set == 0)
17228     {
17229       errmsg ("missing interface name or sw_if_index");
17230       return -99;
17231     }
17232
17233   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
17234
17235   mp->sw_if_index = ntohl (sw_if_index);
17236   mp->ip4_table_index = ntohl (ip4_table_index);
17237   mp->ip6_table_index = ntohl (ip6_table_index);
17238   mp->is_add = is_add;
17239
17240   S (mp);
17241   W (ret);
17242   return ret;
17243 }
17244
17245 static int
17246 api_flow_classify_dump (vat_main_t * vam)
17247 {
17248   unformat_input_t *i = vam->input;
17249   vl_api_flow_classify_dump_t *mp;
17250   vl_api_control_ping_t *mp_ping;
17251   u8 type = FLOW_CLASSIFY_N_TABLES;
17252   int ret;
17253
17254   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
17255     ;
17256   else
17257     {
17258       errmsg ("classify table type must be specified");
17259       return -99;
17260     }
17261
17262   if (!vam->json_output)
17263     {
17264       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17265     }
17266
17267   M (FLOW_CLASSIFY_DUMP, mp);
17268   mp->type = type;
17269   /* send it... */
17270   S (mp);
17271
17272   /* Use a control ping for synchronization */
17273   M (CONTROL_PING, mp_ping);
17274   S (mp_ping);
17275
17276   /* Wait for a reply... */
17277   W (ret);
17278   return ret;
17279 }
17280
17281 static int
17282 api_feature_enable_disable (vat_main_t * vam)
17283 {
17284   unformat_input_t *i = vam->input;
17285   vl_api_feature_enable_disable_t *mp;
17286   u8 *arc_name = 0;
17287   u8 *feature_name = 0;
17288   u32 sw_if_index = ~0;
17289   u8 enable = 1;
17290   int ret;
17291
17292   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17293     {
17294       if (unformat (i, "arc_name %s", &arc_name))
17295         ;
17296       else if (unformat (i, "feature_name %s", &feature_name))
17297         ;
17298       else
17299         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17300         ;
17301       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17302         ;
17303       else if (unformat (i, "disable"))
17304         enable = 0;
17305       else
17306         break;
17307     }
17308
17309   if (arc_name == 0)
17310     {
17311       errmsg ("missing arc name");
17312       return -99;
17313     }
17314   if (vec_len (arc_name) > 63)
17315     {
17316       errmsg ("arc name too long");
17317     }
17318
17319   if (feature_name == 0)
17320     {
17321       errmsg ("missing feature name");
17322       return -99;
17323     }
17324   if (vec_len (feature_name) > 63)
17325     {
17326       errmsg ("feature name too long");
17327     }
17328
17329   if (sw_if_index == ~0)
17330     {
17331       errmsg ("missing interface name or sw_if_index");
17332       return -99;
17333     }
17334
17335   /* Construct the API message */
17336   M (FEATURE_ENABLE_DISABLE, mp);
17337   mp->sw_if_index = ntohl (sw_if_index);
17338   mp->enable = enable;
17339   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
17340   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
17341   vec_free (arc_name);
17342   vec_free (feature_name);
17343
17344   S (mp);
17345   W (ret);
17346   return ret;
17347 }
17348
17349 static int
17350 api_sw_interface_tag_add_del (vat_main_t * vam)
17351 {
17352   unformat_input_t *i = vam->input;
17353   vl_api_sw_interface_tag_add_del_t *mp;
17354   u32 sw_if_index = ~0;
17355   u8 *tag = 0;
17356   u8 enable = 1;
17357   int ret;
17358
17359   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17360     {
17361       if (unformat (i, "tag %s", &tag))
17362         ;
17363       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17364         ;
17365       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17366         ;
17367       else if (unformat (i, "del"))
17368         enable = 0;
17369       else
17370         break;
17371     }
17372
17373   if (sw_if_index == ~0)
17374     {
17375       errmsg ("missing interface name or sw_if_index");
17376       return -99;
17377     }
17378
17379   if (enable && (tag == 0))
17380     {
17381       errmsg ("no tag specified");
17382       return -99;
17383     }
17384
17385   /* Construct the API message */
17386   M (SW_INTERFACE_TAG_ADD_DEL, mp);
17387   mp->sw_if_index = ntohl (sw_if_index);
17388   mp->is_add = enable;
17389   if (enable)
17390     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
17391   vec_free (tag);
17392
17393   S (mp);
17394   W (ret);
17395   return ret;
17396 }
17397
17398 static void vl_api_l2_xconnect_details_t_handler
17399   (vl_api_l2_xconnect_details_t * mp)
17400 {
17401   vat_main_t *vam = &vat_main;
17402
17403   print (vam->ofp, "%15d%15d",
17404          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
17405 }
17406
17407 static void vl_api_l2_xconnect_details_t_handler_json
17408   (vl_api_l2_xconnect_details_t * mp)
17409 {
17410   vat_main_t *vam = &vat_main;
17411   vat_json_node_t *node = NULL;
17412
17413   if (VAT_JSON_ARRAY != vam->json_tree.type)
17414     {
17415       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17416       vat_json_init_array (&vam->json_tree);
17417     }
17418   node = vat_json_array_add (&vam->json_tree);
17419
17420   vat_json_init_object (node);
17421   vat_json_object_add_uint (node, "rx_sw_if_index",
17422                             ntohl (mp->rx_sw_if_index));
17423   vat_json_object_add_uint (node, "tx_sw_if_index",
17424                             ntohl (mp->tx_sw_if_index));
17425 }
17426
17427 static int
17428 api_l2_xconnect_dump (vat_main_t * vam)
17429 {
17430   vl_api_l2_xconnect_dump_t *mp;
17431   vl_api_control_ping_t *mp_ping;
17432   int ret;
17433
17434   if (!vam->json_output)
17435     {
17436       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
17437     }
17438
17439   M (L2_XCONNECT_DUMP, mp);
17440
17441   S (mp);
17442
17443   /* Use a control ping for synchronization */
17444   M (CONTROL_PING, mp_ping);
17445   S (mp_ping);
17446
17447   W (ret);
17448   return ret;
17449 }
17450
17451 static int
17452 api_sw_interface_set_mtu (vat_main_t * vam)
17453 {
17454   unformat_input_t *i = vam->input;
17455   vl_api_sw_interface_set_mtu_t *mp;
17456   u32 sw_if_index = ~0;
17457   u32 mtu = 0;
17458   int ret;
17459
17460   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17461     {
17462       if (unformat (i, "mtu %d", &mtu))
17463         ;
17464       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17465         ;
17466       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17467         ;
17468       else
17469         break;
17470     }
17471
17472   if (sw_if_index == ~0)
17473     {
17474       errmsg ("missing interface name or sw_if_index");
17475       return -99;
17476     }
17477
17478   if (mtu == 0)
17479     {
17480       errmsg ("no mtu specified");
17481       return -99;
17482     }
17483
17484   /* Construct the API message */
17485   M (SW_INTERFACE_SET_MTU, mp);
17486   mp->sw_if_index = ntohl (sw_if_index);
17487   mp->mtu = ntohs ((u16) mtu);
17488
17489   S (mp);
17490   W (ret);
17491   return ret;
17492 }
17493
17494
17495 static int
17496 q_or_quit (vat_main_t * vam)
17497 {
17498 #if VPP_API_TEST_BUILTIN == 0
17499   longjmp (vam->jump_buf, 1);
17500 #endif
17501   return 0;                     /* not so much */
17502 }
17503
17504 static int
17505 q (vat_main_t * vam)
17506 {
17507   return q_or_quit (vam);
17508 }
17509
17510 static int
17511 quit (vat_main_t * vam)
17512 {
17513   return q_or_quit (vam);
17514 }
17515
17516 static int
17517 comment (vat_main_t * vam)
17518 {
17519   return 0;
17520 }
17521
17522 static int
17523 cmd_cmp (void *a1, void *a2)
17524 {
17525   u8 **c1 = a1;
17526   u8 **c2 = a2;
17527
17528   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
17529 }
17530
17531 static int
17532 help (vat_main_t * vam)
17533 {
17534   u8 **cmds = 0;
17535   u8 *name = 0;
17536   hash_pair_t *p;
17537   unformat_input_t *i = vam->input;
17538   int j;
17539
17540   if (unformat (i, "%s", &name))
17541     {
17542       uword *hs;
17543
17544       vec_add1 (name, 0);
17545
17546       hs = hash_get_mem (vam->help_by_name, name);
17547       if (hs)
17548         print (vam->ofp, "usage: %s %s", name, hs[0]);
17549       else
17550         print (vam->ofp, "No such msg / command '%s'", name);
17551       vec_free (name);
17552       return 0;
17553     }
17554
17555   print (vam->ofp, "Help is available for the following:");
17556
17557     /* *INDENT-OFF* */
17558     hash_foreach_pair (p, vam->function_by_name,
17559     ({
17560       vec_add1 (cmds, (u8 *)(p->key));
17561     }));
17562     /* *INDENT-ON* */
17563
17564   vec_sort_with_function (cmds, cmd_cmp);
17565
17566   for (j = 0; j < vec_len (cmds); j++)
17567     print (vam->ofp, "%s", cmds[j]);
17568
17569   vec_free (cmds);
17570   return 0;
17571 }
17572
17573 static int
17574 set (vat_main_t * vam)
17575 {
17576   u8 *name = 0, *value = 0;
17577   unformat_input_t *i = vam->input;
17578
17579   if (unformat (i, "%s", &name))
17580     {
17581       /* The input buffer is a vector, not a string. */
17582       value = vec_dup (i->buffer);
17583       vec_delete (value, i->index, 0);
17584       /* Almost certainly has a trailing newline */
17585       if (value[vec_len (value) - 1] == '\n')
17586         value[vec_len (value) - 1] = 0;
17587       /* Make sure it's a proper string, one way or the other */
17588       vec_add1 (value, 0);
17589       (void) clib_macro_set_value (&vam->macro_main,
17590                                    (char *) name, (char *) value);
17591     }
17592   else
17593     errmsg ("usage: set <name> <value>");
17594
17595   vec_free (name);
17596   vec_free (value);
17597   return 0;
17598 }
17599
17600 static int
17601 unset (vat_main_t * vam)
17602 {
17603   u8 *name = 0;
17604
17605   if (unformat (vam->input, "%s", &name))
17606     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
17607       errmsg ("unset: %s wasn't set", name);
17608   vec_free (name);
17609   return 0;
17610 }
17611
17612 typedef struct
17613 {
17614   u8 *name;
17615   u8 *value;
17616 } macro_sort_t;
17617
17618
17619 static int
17620 macro_sort_cmp (void *a1, void *a2)
17621 {
17622   macro_sort_t *s1 = a1;
17623   macro_sort_t *s2 = a2;
17624
17625   return strcmp ((char *) (s1->name), (char *) (s2->name));
17626 }
17627
17628 static int
17629 dump_macro_table (vat_main_t * vam)
17630 {
17631   macro_sort_t *sort_me = 0, *sm;
17632   int i;
17633   hash_pair_t *p;
17634
17635     /* *INDENT-OFF* */
17636     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
17637     ({
17638       vec_add2 (sort_me, sm, 1);
17639       sm->name = (u8 *)(p->key);
17640       sm->value = (u8 *) (p->value[0]);
17641     }));
17642     /* *INDENT-ON* */
17643
17644   vec_sort_with_function (sort_me, macro_sort_cmp);
17645
17646   if (vec_len (sort_me))
17647     print (vam->ofp, "%-15s%s", "Name", "Value");
17648   else
17649     print (vam->ofp, "The macro table is empty...");
17650
17651   for (i = 0; i < vec_len (sort_me); i++)
17652     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
17653   return 0;
17654 }
17655
17656 static int
17657 dump_node_table (vat_main_t * vam)
17658 {
17659   int i, j;
17660   vlib_node_t *node, *next_node;
17661
17662   if (vec_len (vam->graph_nodes) == 0)
17663     {
17664       print (vam->ofp, "Node table empty, issue get_node_graph...");
17665       return 0;
17666     }
17667
17668   for (i = 0; i < vec_len (vam->graph_nodes); i++)
17669     {
17670       node = vam->graph_nodes[i];
17671       print (vam->ofp, "[%d] %s", i, node->name);
17672       for (j = 0; j < vec_len (node->next_nodes); j++)
17673         {
17674           if (node->next_nodes[j] != ~0)
17675             {
17676               next_node = vam->graph_nodes[node->next_nodes[j]];
17677               print (vam->ofp, "  [%d] %s", j, next_node->name);
17678             }
17679         }
17680     }
17681   return 0;
17682 }
17683
17684 static int
17685 value_sort_cmp (void *a1, void *a2)
17686 {
17687   name_sort_t *n1 = a1;
17688   name_sort_t *n2 = a2;
17689
17690   if (n1->value < n2->value)
17691     return -1;
17692   if (n1->value > n2->value)
17693     return 1;
17694   return 0;
17695 }
17696
17697
17698 static int
17699 dump_msg_api_table (vat_main_t * vam)
17700 {
17701   api_main_t *am = &api_main;
17702   name_sort_t *nses = 0, *ns;
17703   hash_pair_t *hp;
17704   int i;
17705
17706   /* *INDENT-OFF* */
17707   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
17708   ({
17709     vec_add2 (nses, ns, 1);
17710     ns->name = (u8 *)(hp->key);
17711     ns->value = (u32) hp->value[0];
17712   }));
17713   /* *INDENT-ON* */
17714
17715   vec_sort_with_function (nses, value_sort_cmp);
17716
17717   for (i = 0; i < vec_len (nses); i++)
17718     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
17719   vec_free (nses);
17720   return 0;
17721 }
17722
17723 static int
17724 get_msg_id (vat_main_t * vam)
17725 {
17726   u8 *name_and_crc;
17727   u32 message_index;
17728
17729   if (unformat (vam->input, "%s", &name_and_crc))
17730     {
17731       message_index = vl_api_get_msg_index (name_and_crc);
17732       if (message_index == ~0)
17733         {
17734           print (vam->ofp, " '%s' not found", name_and_crc);
17735           return 0;
17736         }
17737       print (vam->ofp, " '%s' has message index %d",
17738              name_and_crc, message_index);
17739       return 0;
17740     }
17741   errmsg ("name_and_crc required...");
17742   return 0;
17743 }
17744
17745 static int
17746 search_node_table (vat_main_t * vam)
17747 {
17748   unformat_input_t *line_input = vam->input;
17749   u8 *node_to_find;
17750   int j;
17751   vlib_node_t *node, *next_node;
17752   uword *p;
17753
17754   if (vam->graph_node_index_by_name == 0)
17755     {
17756       print (vam->ofp, "Node table empty, issue get_node_graph...");
17757       return 0;
17758     }
17759
17760   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
17761     {
17762       if (unformat (line_input, "%s", &node_to_find))
17763         {
17764           vec_add1 (node_to_find, 0);
17765           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
17766           if (p == 0)
17767             {
17768               print (vam->ofp, "%s not found...", node_to_find);
17769               goto out;
17770             }
17771           node = vam->graph_nodes[p[0]];
17772           print (vam->ofp, "[%d] %s", p[0], node->name);
17773           for (j = 0; j < vec_len (node->next_nodes); j++)
17774             {
17775               if (node->next_nodes[j] != ~0)
17776                 {
17777                   next_node = vam->graph_nodes[node->next_nodes[j]];
17778                   print (vam->ofp, "  [%d] %s", j, next_node->name);
17779                 }
17780             }
17781         }
17782
17783       else
17784         {
17785           clib_warning ("parse error '%U'", format_unformat_error,
17786                         line_input);
17787           return -99;
17788         }
17789
17790     out:
17791       vec_free (node_to_find);
17792
17793     }
17794
17795   return 0;
17796 }
17797
17798
17799 static int
17800 script (vat_main_t * vam)
17801 {
17802 #if (VPP_API_TEST_BUILTIN==0)
17803   u8 *s = 0;
17804   char *save_current_file;
17805   unformat_input_t save_input;
17806   jmp_buf save_jump_buf;
17807   u32 save_line_number;
17808
17809   FILE *new_fp, *save_ifp;
17810
17811   if (unformat (vam->input, "%s", &s))
17812     {
17813       new_fp = fopen ((char *) s, "r");
17814       if (new_fp == 0)
17815         {
17816           errmsg ("Couldn't open script file %s", s);
17817           vec_free (s);
17818           return -99;
17819         }
17820     }
17821   else
17822     {
17823       errmsg ("Missing script name");
17824       return -99;
17825     }
17826
17827   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
17828   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
17829   save_ifp = vam->ifp;
17830   save_line_number = vam->input_line_number;
17831   save_current_file = (char *) vam->current_file;
17832
17833   vam->input_line_number = 0;
17834   vam->ifp = new_fp;
17835   vam->current_file = s;
17836   do_one_file (vam);
17837
17838   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
17839   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
17840   vam->ifp = save_ifp;
17841   vam->input_line_number = save_line_number;
17842   vam->current_file = (u8 *) save_current_file;
17843   vec_free (s);
17844
17845   return 0;
17846 #else
17847   clib_warning ("use the exec command...");
17848   return -99;
17849 #endif
17850 }
17851
17852 static int
17853 echo (vat_main_t * vam)
17854 {
17855   print (vam->ofp, "%v", vam->input->buffer);
17856   return 0;
17857 }
17858
17859 /* List of API message constructors, CLI names map to api_xxx */
17860 #define foreach_vpe_api_msg                                             \
17861 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
17862 _(sw_interface_dump,"")                                                 \
17863 _(sw_interface_set_flags,                                               \
17864   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
17865 _(sw_interface_add_del_address,                                         \
17866   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
17867 _(sw_interface_set_table,                                               \
17868   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
17869 _(sw_interface_set_mpls_enable,                                         \
17870   "<intfc> | sw_if_index [disable | dis]")                              \
17871 _(sw_interface_set_vpath,                                               \
17872   "<intfc> | sw_if_index <id> enable | disable")                        \
17873 _(sw_interface_set_vxlan_bypass,                                        \
17874   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
17875 _(sw_interface_set_l2_xconnect,                                         \
17876   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17877   "enable | disable")                                                   \
17878 _(sw_interface_set_l2_bridge,                                           \
17879   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"               \
17880   "[shg <split-horizon-group>] [bvi]\n"                                 \
17881   "enable | disable")                                                   \
17882 _(bridge_domain_add_del,                                                \
17883   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n") \
17884 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
17885 _(l2fib_add_del,                                                        \
17886   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
17887 _(l2_flags,                                                             \
17888   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
17889 _(bridge_flags,                                                         \
17890   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
17891 _(tap_connect,                                                          \
17892   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
17893 _(tap_modify,                                                           \
17894   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
17895 _(tap_delete,                                                           \
17896   "<vpp-if-name> | sw_if_index <id>")                                   \
17897 _(sw_interface_tap_dump, "")                                            \
17898 _(ip_add_del_route,                                                     \
17899   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
17900   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
17901   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
17902   "[multipath] [count <n>]")                                            \
17903 _(ip_mroute_add_del,                                                    \
17904   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
17905   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
17906 _(mpls_route_add_del,                                                   \
17907   "<label> <eos> via <addr> [table-id <n>]\n"                           \
17908   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
17909   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
17910   "[multipath] [count <n>]")                                            \
17911 _(mpls_ip_bind_unbind,                                                  \
17912   "<label> <addr/len>")                                                 \
17913 _(mpls_tunnel_add_del,                                                  \
17914   " via <addr> [table-id <n>]\n"                                        \
17915   "sw_if_index <id>] [l2]  [del]")                                      \
17916 _(proxy_arp_add_del,                                                    \
17917   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
17918 _(proxy_arp_intfc_enable_disable,                                       \
17919   "<intfc> | sw_if_index <id> enable | disable")                        \
17920 _(sw_interface_set_unnumbered,                                          \
17921   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
17922 _(ip_neighbor_add_del,                                                  \
17923   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
17924   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
17925 _(reset_vrf, "vrf <id> [ipv6]")                                         \
17926 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
17927 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
17928   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
17929   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
17930   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
17931 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
17932 _(reset_fib, "vrf <n> [ipv6]")                                          \
17933 _(dhcp_proxy_config,                                                    \
17934   "svr <v46-address> src <v46-address>\n"                               \
17935    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
17936 _(dhcp_proxy_set_vss,                                                   \
17937   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
17938 _(dhcp_proxy_dump, "ip6")                                               \
17939 _(dhcp_client_config,                                                   \
17940   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
17941 _(set_ip_flow_hash,                                                     \
17942   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
17943 _(sw_interface_ip6_enable_disable,                                      \
17944   "<intfc> | sw_if_index <id> enable | disable")                        \
17945 _(sw_interface_ip6_set_link_local_address,                              \
17946   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
17947 _(sw_interface_ip6nd_ra_prefix,                                         \
17948   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
17949   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
17950   "[nolink] [isno]")                                                    \
17951 _(sw_interface_ip6nd_ra_config,                                         \
17952   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
17953   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
17954   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
17955 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
17956 _(l2_patch_add_del,                                                     \
17957   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17958   "enable | disable")                                                   \
17959 _(sr_localsid_add_del,                                                  \
17960   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
17961   "fib-table <num> (end.psp) sw_if_index <num>")                        \
17962 _(classify_add_del_table,                                               \
17963   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
17964   " [del] [del-chain] mask <mask-value>\n"                              \
17965   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
17966   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
17967 _(classify_add_del_session,                                             \
17968   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
17969   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
17970   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
17971   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
17972 _(classify_set_interface_ip_table,                                      \
17973   "<intfc> | sw_if_index <nn> table <nn>")                              \
17974 _(classify_set_interface_l2_tables,                                     \
17975   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17976   "  [other-table <nn>]")                                               \
17977 _(get_node_index, "node <node-name")                                    \
17978 _(add_node_next, "node <node-name> next <next-node-name>")              \
17979 _(l2tpv3_create_tunnel,                                                 \
17980   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
17981   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
17982   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
17983 _(l2tpv3_set_tunnel_cookies,                                            \
17984   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
17985   "[new_remote_cookie <nn>]\n")                                         \
17986 _(l2tpv3_interface_enable_disable,                                      \
17987   "<intfc> | sw_if_index <nn> enable | disable")                        \
17988 _(l2tpv3_set_lookup_key,                                                \
17989   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
17990 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
17991 _(vxlan_add_del_tunnel,                                                 \
17992   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
17993   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
17994   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
17995 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
17996 _(gre_add_del_tunnel,                                                   \
17997   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
17998 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
17999 _(l2_fib_clear_table, "")                                               \
18000 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
18001 _(l2_interface_vlan_tag_rewrite,                                        \
18002   "<intfc> | sw_if_index <nn> \n"                                       \
18003   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
18004   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
18005 _(create_vhost_user_if,                                                 \
18006         "socket <filename> [server] [renumber <dev_instance>] "         \
18007         "[mac <mac_address>]")                                          \
18008 _(modify_vhost_user_if,                                                 \
18009         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
18010         "[server] [renumber <dev_instance>]")                           \
18011 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
18012 _(sw_interface_vhost_user_dump, "")                                     \
18013 _(show_version, "")                                                     \
18014 _(vxlan_gpe_add_del_tunnel,                                             \
18015   "local <addr> remote <addr> vni <nn>\n"                               \
18016     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
18017   "[next-ethernet] [next-nsh]\n")                                       \
18018 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
18019 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
18020 _(interface_name_renumber,                                              \
18021   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
18022 _(input_acl_set_interface,                                              \
18023   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18024   "  [l2-table <nn>] [del]")                                            \
18025 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
18026 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
18027 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
18028 _(ip_dump, "ipv4 | ipv6")                                               \
18029 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
18030 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
18031   "  spid_id <n> ")                                                     \
18032 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
18033   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
18034   "  integ_alg <alg> integ_key <hex>")                                  \
18035 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
18036   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
18037   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
18038   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
18039 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
18040 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
18041 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
18042   "(auth_data 0x<data> | auth_data <data>)")                            \
18043 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
18044   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
18045 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
18046   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
18047   "(local|remote)")                                                     \
18048 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
18049 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
18050 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18051 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18052 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
18053 _(ikev2_initiate_sa_init, "<profile_name>")                             \
18054 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
18055 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
18056 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
18057 _(delete_loopback,"sw_if_index <nn>")                                   \
18058 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
18059 _(map_add_domain,                                                       \
18060   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
18061   "ip6-src <ip6addr> "                                                  \
18062   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
18063 _(map_del_domain, "index <n>")                                          \
18064 _(map_add_del_rule,                                                     \
18065   "index <n> psid <n> dst <ip6addr> [del]")                             \
18066 _(map_domain_dump, "")                                                  \
18067 _(map_rule_dump, "index <map-domain>")                                  \
18068 _(want_interface_events,  "enable|disable")                             \
18069 _(want_stats,"enable|disable")                                          \
18070 _(get_first_msg_id, "client <name>")                                    \
18071 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
18072 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
18073   "fib-id <nn> [ip4][ip6][default]")                                    \
18074 _(get_node_graph, " ")                                                  \
18075 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
18076 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
18077 _(ioam_disable, "")                                                     \
18078 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
18079                             " sw_if_index <sw_if_index> p <priority> "  \
18080                             "w <weight>] [del]")                        \
18081 _(one_add_del_locator, "locator-set <locator_name> "                    \
18082                         "iface <intf> | sw_if_index <sw_if_index> "     \
18083                         "p <priority> w <weight> [del]")                \
18084 _(one_add_del_local_eid,"vni <vni> eid "                                \
18085                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
18086                          "locator-set <locator_name> [del]"             \
18087                          "[key-id sha1|sha256 secret-key <secret-key>]")\
18088 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
18089 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
18090 _(one_enable_disable, "enable|disable")                                 \
18091 _(one_map_register_enable_disable, "enable|disable")                    \
18092 _(one_rloc_probe_enable_disable, "enable|disable")                      \
18093 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
18094                                "[seid <seid>] "                         \
18095                                "rloc <locator> p <prio> "               \
18096                                "w <weight> [rloc <loc> ... ] "          \
18097                                "action <action> [del-all]")             \
18098 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
18099                           "<local-eid>")                                \
18100 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
18101 _(one_map_request_mode, "src-dst|dst-only")                             \
18102 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
18103 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
18104 _(one_locator_set_dump, "[local | remote]")                             \
18105 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
18106 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
18107                        "[local] | [remote]")                            \
18108 _(one_eid_table_vni_dump, "")                                           \
18109 _(one_eid_table_map_dump, "l2|l3")                                      \
18110 _(one_map_resolver_dump, "")                                            \
18111 _(one_map_server_dump, "")                                              \
18112 _(one_adjacencies_get, "vni <vni>")                                     \
18113 _(show_one_rloc_probe_state, "")                                        \
18114 _(show_one_map_register_state, "")                                      \
18115 _(show_one_status, "")                                                  \
18116 _(one_get_map_request_itr_rlocs, "")                                    \
18117 _(show_one_pitr, "")                                                    \
18118 _(show_one_map_request_mode, "")                                        \
18119 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
18120                             " sw_if_index <sw_if_index> p <priority> "  \
18121                             "w <weight>] [del]")                        \
18122 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
18123                         "iface <intf> | sw_if_index <sw_if_index> "     \
18124                         "p <priority> w <weight> [del]")                \
18125 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
18126                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
18127                          "locator-set <locator_name> [del]"             \
18128                          "[key-id sha1|sha256 secret-key <secret-key>]") \
18129 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
18130 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
18131 _(lisp_enable_disable, "enable|disable")                                \
18132 _(lisp_map_register_enable_disable, "enable|disable")                   \
18133 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
18134 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
18135                                "[seid <seid>] "                         \
18136                                "rloc <locator> p <prio> "               \
18137                                "w <weight> [rloc <loc> ... ] "          \
18138                                "action <action> [del-all]")             \
18139 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
18140                           "<local-eid>")                                \
18141 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
18142 _(lisp_map_request_mode, "src-dst|dst-only")                            \
18143 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
18144 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
18145 _(lisp_locator_set_dump, "[local | remote]")                            \
18146 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
18147 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
18148                        "[local] | [remote]")                            \
18149 _(lisp_eid_table_vni_dump, "")                                          \
18150 _(lisp_eid_table_map_dump, "l2|l3")                                     \
18151 _(lisp_map_resolver_dump, "")                                           \
18152 _(lisp_map_server_dump, "")                                             \
18153 _(lisp_adjacencies_get, "vni <vni>")                                    \
18154 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
18155 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
18156 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
18157 _(gpe_get_encap_mode, "")                                               \
18158 _(lisp_gpe_add_del_iface, "up|down")                                    \
18159 _(lisp_gpe_enable_disable, "enable|disable")                            \
18160 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
18161   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
18162 _(show_lisp_rloc_probe_state, "")                                       \
18163 _(show_lisp_map_register_state, "")                                     \
18164 _(show_lisp_status, "")                                                 \
18165 _(lisp_get_map_request_itr_rlocs, "")                                   \
18166 _(show_lisp_pitr, "")                                                   \
18167 _(show_lisp_map_request_mode, "")                                       \
18168 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
18169 _(af_packet_delete, "name <host interface name>")                       \
18170 _(policer_add_del, "name <policer name> <params> [del]")                \
18171 _(policer_dump, "[name <policer name>]")                                \
18172 _(policer_classify_set_interface,                                       \
18173   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18174   "  [l2-table <nn>] [del]")                                            \
18175 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
18176 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
18177     "[master|slave]")                                                   \
18178 _(netmap_delete, "name <interface name>")                               \
18179 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
18180 _(mpls_fib_dump, "")                                                    \
18181 _(classify_table_ids, "")                                               \
18182 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
18183 _(classify_table_info, "table_id <nn>")                                 \
18184 _(classify_session_dump, "table_id <nn>")                               \
18185 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
18186     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
18187     "[template_interval <nn>] [udp_checksum]")                          \
18188 _(ipfix_exporter_dump, "")                                              \
18189 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
18190 _(ipfix_classify_stream_dump, "")                                       \
18191 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
18192 _(ipfix_classify_table_dump, "")                                        \
18193 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
18194 _(sw_interface_span_dump, "")                                           \
18195 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
18196 _(pg_create_interface, "if_id <nn>")                                    \
18197 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
18198 _(pg_enable_disable, "[stream <id>] disable")                           \
18199 _(ip_source_and_port_range_check_add_del,                               \
18200   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
18201 _(ip_source_and_port_range_check_interface_add_del,                     \
18202   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
18203   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
18204 _(ipsec_gre_add_del_tunnel,                                             \
18205   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
18206 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
18207 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
18208 _(l2_interface_pbb_tag_rewrite,                                         \
18209   "<intfc> | sw_if_index <nn> \n"                                       \
18210   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
18211   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
18212 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
18213 _(flow_classify_set_interface,                                          \
18214   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
18215 _(flow_classify_dump, "type [ip4|ip6]")                                 \
18216 _(ip_fib_dump, "")                                                      \
18217 _(ip_mfib_dump, "")                                                     \
18218 _(ip6_fib_dump, "")                                                     \
18219 _(ip6_mfib_dump, "")                                                    \
18220 _(feature_enable_disable, "arc_name <arc_name> "                        \
18221   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
18222 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
18223 "[disable]")                                                            \
18224 _(l2_xconnect_dump, "")                                                 \
18225 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
18226 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
18227 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
18228
18229 /* List of command functions, CLI names map directly to functions */
18230 #define foreach_cli_function                                    \
18231 _(comment, "usage: comment <ignore-rest-of-line>")              \
18232 _(dump_interface_table, "usage: dump_interface_table")          \
18233 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
18234 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
18235 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
18236 _(dump_stats_table, "usage: dump_stats_table")                  \
18237 _(dump_macro_table, "usage: dump_macro_table ")                 \
18238 _(dump_node_table, "usage: dump_node_table")                    \
18239 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
18240 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
18241 _(echo, "usage: echo <message>")                                \
18242 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
18243 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
18244 _(help, "usage: help")                                          \
18245 _(q, "usage: quit")                                             \
18246 _(quit, "usage: quit")                                          \
18247 _(search_node_table, "usage: search_node_table <name>...")      \
18248 _(set, "usage: set <variable-name> <value>")                    \
18249 _(script, "usage: script <file-name>")                          \
18250 _(unset, "usage: unset <variable-name>")
18251
18252 #define _(N,n)                                  \
18253     static void vl_api_##n##_t_handler_uni      \
18254     (vl_api_##n##_t * mp)                       \
18255     {                                           \
18256         vat_main_t * vam = &vat_main;           \
18257         if (vam->json_output) {                 \
18258             vl_api_##n##_t_handler_json(mp);    \
18259         } else {                                \
18260             vl_api_##n##_t_handler(mp);         \
18261         }                                       \
18262     }
18263 foreach_vpe_api_reply_msg;
18264 #if VPP_API_TEST_BUILTIN == 0
18265 foreach_standalone_reply_msg;
18266 #endif
18267 #undef _
18268
18269 void
18270 vat_api_hookup (vat_main_t * vam)
18271 {
18272 #define _(N,n)                                                  \
18273     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
18274                            vl_api_##n##_t_handler_uni,          \
18275                            vl_noop_handler,                     \
18276                            vl_api_##n##_t_endian,               \
18277                            vl_api_##n##_t_print,                \
18278                            sizeof(vl_api_##n##_t), 1);
18279   foreach_vpe_api_reply_msg;
18280 #if VPP_API_TEST_BUILTIN == 0
18281   foreach_standalone_reply_msg;
18282 #endif
18283 #undef _
18284
18285 #if (VPP_API_TEST_BUILTIN==0)
18286   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
18287 #endif
18288
18289   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
18290
18291   vam->function_by_name = hash_create_string (0, sizeof (uword));
18292
18293   vam->help_by_name = hash_create_string (0, sizeof (uword));
18294
18295   /* API messages we can send */
18296 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
18297   foreach_vpe_api_msg;
18298 #undef _
18299
18300   /* Help strings */
18301 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18302   foreach_vpe_api_msg;
18303 #undef _
18304
18305   /* CLI functions */
18306 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
18307   foreach_cli_function;
18308 #undef _
18309
18310   /* Help strings */
18311 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18312   foreach_cli_function;
18313 #undef _
18314 }
18315
18316 #if VPP_API_TEST_BUILTIN
18317 static clib_error_t *
18318 vat_api_hookup_shim (vlib_main_t * vm)
18319 {
18320   vat_api_hookup (&vat_main);
18321   return 0;
18322 }
18323
18324 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
18325 #endif
18326
18327 /*
18328  * fd.io coding-style-patch-verification: ON
18329  *
18330  * Local Variables:
18331  * eval: (c-set-style "gnu")
18332  * End:
18333  */