LISP: make TTL for map register messages configurable
[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 = uword_to_pointer (mp->reply_in_shmem, u8 *);
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 = uword_to_pointer (mp->reply_in_shmem, u8 *);
1022   vec_free (reply);
1023
1024   svm_pop_heap (oldheap);
1025   pthread_mutex_unlock (&am->vlib_rp->mutex);
1026
1027   vat_json_print (vam->ofp, &node);
1028   vat_json_free (&node);
1029
1030   vam->retval = ntohl (mp->retval);
1031   vam->result_ready = 1;
1032 }
1033
1034 static void
1035 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1036 {
1037   vat_main_t *vam = &vat_main;
1038   i32 retval = ntohl (mp->retval);
1039
1040   vam->retval = retval;
1041   vam->cmd_reply = mp->reply;
1042   vam->result_ready = 1;
1043 }
1044
1045 static void
1046 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1047 {
1048   vat_main_t *vam = &vat_main;
1049   vat_json_node_t node;
1050
1051   vat_json_init_object (&node);
1052   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1053   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1054
1055   vat_json_print (vam->ofp, &node);
1056   vat_json_free (&node);
1057
1058   vam->retval = ntohl (mp->retval);
1059   vam->result_ready = 1;
1060 }
1061
1062 static void vl_api_classify_add_del_table_reply_t_handler
1063   (vl_api_classify_add_del_table_reply_t * mp)
1064 {
1065   vat_main_t *vam = &vat_main;
1066   i32 retval = ntohl (mp->retval);
1067   if (vam->async_mode)
1068     {
1069       vam->async_errors += (retval < 0);
1070     }
1071   else
1072     {
1073       vam->retval = retval;
1074       if (retval == 0 &&
1075           ((mp->new_table_index != 0xFFFFFFFF) ||
1076            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1077            (mp->match_n_vectors != 0xFFFFFFFF)))
1078         /*
1079          * Note: this is just barely thread-safe, depends on
1080          * the main thread spinning waiting for an answer...
1081          */
1082         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1083                 ntohl (mp->new_table_index),
1084                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1085       vam->result_ready = 1;
1086     }
1087 }
1088
1089 static void vl_api_classify_add_del_table_reply_t_handler_json
1090   (vl_api_classify_add_del_table_reply_t * mp)
1091 {
1092   vat_main_t *vam = &vat_main;
1093   vat_json_node_t node;
1094
1095   vat_json_init_object (&node);
1096   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1097   vat_json_object_add_uint (&node, "new_table_index",
1098                             ntohl (mp->new_table_index));
1099   vat_json_object_add_uint (&node, "skip_n_vectors",
1100                             ntohl (mp->skip_n_vectors));
1101   vat_json_object_add_uint (&node, "match_n_vectors",
1102                             ntohl (mp->match_n_vectors));
1103
1104   vat_json_print (vam->ofp, &node);
1105   vat_json_free (&node);
1106
1107   vam->retval = ntohl (mp->retval);
1108   vam->result_ready = 1;
1109 }
1110
1111 static void vl_api_get_node_index_reply_t_handler
1112   (vl_api_get_node_index_reply_t * mp)
1113 {
1114   vat_main_t *vam = &vat_main;
1115   i32 retval = ntohl (mp->retval);
1116   if (vam->async_mode)
1117     {
1118       vam->async_errors += (retval < 0);
1119     }
1120   else
1121     {
1122       vam->retval = retval;
1123       if (retval == 0)
1124         errmsg ("node index %d", ntohl (mp->node_index));
1125       vam->result_ready = 1;
1126     }
1127 }
1128
1129 static void vl_api_get_node_index_reply_t_handler_json
1130   (vl_api_get_node_index_reply_t * mp)
1131 {
1132   vat_main_t *vam = &vat_main;
1133   vat_json_node_t node;
1134
1135   vat_json_init_object (&node);
1136   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1137   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1138
1139   vat_json_print (vam->ofp, &node);
1140   vat_json_free (&node);
1141
1142   vam->retval = ntohl (mp->retval);
1143   vam->result_ready = 1;
1144 }
1145
1146 static void vl_api_get_next_index_reply_t_handler
1147   (vl_api_get_next_index_reply_t * mp)
1148 {
1149   vat_main_t *vam = &vat_main;
1150   i32 retval = ntohl (mp->retval);
1151   if (vam->async_mode)
1152     {
1153       vam->async_errors += (retval < 0);
1154     }
1155   else
1156     {
1157       vam->retval = retval;
1158       if (retval == 0)
1159         errmsg ("next node index %d", ntohl (mp->next_index));
1160       vam->result_ready = 1;
1161     }
1162 }
1163
1164 static void vl_api_get_next_index_reply_t_handler_json
1165   (vl_api_get_next_index_reply_t * mp)
1166 {
1167   vat_main_t *vam = &vat_main;
1168   vat_json_node_t node;
1169
1170   vat_json_init_object (&node);
1171   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1172   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1173
1174   vat_json_print (vam->ofp, &node);
1175   vat_json_free (&node);
1176
1177   vam->retval = ntohl (mp->retval);
1178   vam->result_ready = 1;
1179 }
1180
1181 static void vl_api_add_node_next_reply_t_handler
1182   (vl_api_add_node_next_reply_t * mp)
1183 {
1184   vat_main_t *vam = &vat_main;
1185   i32 retval = ntohl (mp->retval);
1186   if (vam->async_mode)
1187     {
1188       vam->async_errors += (retval < 0);
1189     }
1190   else
1191     {
1192       vam->retval = retval;
1193       if (retval == 0)
1194         errmsg ("next index %d", ntohl (mp->next_index));
1195       vam->result_ready = 1;
1196     }
1197 }
1198
1199 static void vl_api_add_node_next_reply_t_handler_json
1200   (vl_api_add_node_next_reply_t * mp)
1201 {
1202   vat_main_t *vam = &vat_main;
1203   vat_json_node_t node;
1204
1205   vat_json_init_object (&node);
1206   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1207   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1208
1209   vat_json_print (vam->ofp, &node);
1210   vat_json_free (&node);
1211
1212   vam->retval = ntohl (mp->retval);
1213   vam->result_ready = 1;
1214 }
1215
1216 static void vl_api_show_version_reply_t_handler
1217   (vl_api_show_version_reply_t * mp)
1218 {
1219   vat_main_t *vam = &vat_main;
1220   i32 retval = ntohl (mp->retval);
1221
1222   if (retval >= 0)
1223     {
1224       errmsg ("        program: %s", mp->program);
1225       errmsg ("        version: %s", mp->version);
1226       errmsg ("     build date: %s", mp->build_date);
1227       errmsg ("build directory: %s", mp->build_directory);
1228     }
1229   vam->retval = retval;
1230   vam->result_ready = 1;
1231 }
1232
1233 static void vl_api_show_version_reply_t_handler_json
1234   (vl_api_show_version_reply_t * mp)
1235 {
1236   vat_main_t *vam = &vat_main;
1237   vat_json_node_t node;
1238
1239   vat_json_init_object (&node);
1240   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1241   vat_json_object_add_string_copy (&node, "program", mp->program);
1242   vat_json_object_add_string_copy (&node, "version", mp->version);
1243   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1244   vat_json_object_add_string_copy (&node, "build_directory",
1245                                    mp->build_directory);
1246
1247   vat_json_print (vam->ofp, &node);
1248   vat_json_free (&node);
1249
1250   vam->retval = ntohl (mp->retval);
1251   vam->result_ready = 1;
1252 }
1253
1254 static void
1255 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1256 {
1257   u32 sw_if_index = ntohl (mp->sw_if_index);
1258   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1259           mp->mac_ip ? "mac/ip binding" : "address resolution",
1260           ntohl (mp->pid), format_ip4_address, &mp->address,
1261           format_ethernet_address, mp->new_mac, sw_if_index);
1262 }
1263
1264 static void
1265 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1266 {
1267   /* JSON output not supported */
1268 }
1269
1270 static void
1271 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1272 {
1273   u32 sw_if_index = ntohl (mp->sw_if_index);
1274   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1275           mp->mac_ip ? "mac/ip binding" : "address resolution",
1276           ntohl (mp->pid), format_ip6_address, mp->address,
1277           format_ethernet_address, mp->new_mac, sw_if_index);
1278 }
1279
1280 static void
1281 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1282 {
1283   /* JSON output not supported */
1284 }
1285
1286 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1287 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1288
1289 /*
1290  * Special-case: build the bridge domain table, maintain
1291  * the next bd id vbl.
1292  */
1293 static void vl_api_bridge_domain_details_t_handler
1294   (vl_api_bridge_domain_details_t * mp)
1295 {
1296   vat_main_t *vam = &vat_main;
1297   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1298   int i;
1299
1300   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1301          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1302
1303   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1304          ntohl (mp->bd_id), mp->learn, mp->forward,
1305          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1306
1307   if (n_sw_ifs)
1308     {
1309       vl_api_bridge_domain_sw_if_t *sw_ifs;
1310       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1311              "Interface Name");
1312
1313       sw_ifs = mp->sw_if_details;
1314       for (i = 0; i < n_sw_ifs; i++)
1315         {
1316           u8 *sw_if_name = 0;
1317           u32 sw_if_index;
1318           hash_pair_t *p;
1319
1320           sw_if_index = ntohl (sw_ifs->sw_if_index);
1321
1322           /* *INDENT-OFF* */
1323           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1324                              ({
1325                                if ((u32) p->value[0] == sw_if_index)
1326                                  {
1327                                    sw_if_name = (u8 *)(p->key);
1328                                    break;
1329                                  }
1330                              }));
1331           /* *INDENT-ON* */
1332           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1333                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1334                  "sw_if_index not found!");
1335
1336           sw_ifs++;
1337         }
1338     }
1339 }
1340
1341 static void vl_api_bridge_domain_details_t_handler_json
1342   (vl_api_bridge_domain_details_t * mp)
1343 {
1344   vat_main_t *vam = &vat_main;
1345   vat_json_node_t *node, *array = NULL;
1346   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1347
1348   if (VAT_JSON_ARRAY != vam->json_tree.type)
1349     {
1350       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1351       vat_json_init_array (&vam->json_tree);
1352     }
1353   node = vat_json_array_add (&vam->json_tree);
1354
1355   vat_json_init_object (node);
1356   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1357   vat_json_object_add_uint (node, "flood", mp->flood);
1358   vat_json_object_add_uint (node, "forward", mp->forward);
1359   vat_json_object_add_uint (node, "learn", mp->learn);
1360   vat_json_object_add_uint (node, "bvi_sw_if_index",
1361                             ntohl (mp->bvi_sw_if_index));
1362   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1363   array = vat_json_object_add (node, "sw_if");
1364   vat_json_init_array (array);
1365
1366
1367
1368   if (n_sw_ifs)
1369     {
1370       vl_api_bridge_domain_sw_if_t *sw_ifs;
1371       int i;
1372
1373       sw_ifs = mp->sw_if_details;
1374       for (i = 0; i < n_sw_ifs; i++)
1375         {
1376           node = vat_json_array_add (array);
1377           vat_json_init_object (node);
1378           vat_json_object_add_uint (node, "sw_if_index",
1379                                     ntohl (sw_ifs->sw_if_index));
1380           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1381           sw_ifs++;
1382         }
1383     }
1384 }
1385
1386 static void vl_api_control_ping_reply_t_handler
1387   (vl_api_control_ping_reply_t * mp)
1388 {
1389   vat_main_t *vam = &vat_main;
1390   i32 retval = ntohl (mp->retval);
1391   if (vam->async_mode)
1392     {
1393       vam->async_errors += (retval < 0);
1394     }
1395   else
1396     {
1397       vam->retval = retval;
1398       vam->result_ready = 1;
1399     }
1400 }
1401
1402 static void vl_api_control_ping_reply_t_handler_json
1403   (vl_api_control_ping_reply_t * mp)
1404 {
1405   vat_main_t *vam = &vat_main;
1406   i32 retval = ntohl (mp->retval);
1407
1408   if (VAT_JSON_NONE != vam->json_tree.type)
1409     {
1410       vat_json_print (vam->ofp, &vam->json_tree);
1411       vat_json_free (&vam->json_tree);
1412       vam->json_tree.type = VAT_JSON_NONE;
1413     }
1414   else
1415     {
1416       /* just print [] */
1417       vat_json_init_array (&vam->json_tree);
1418       vat_json_print (vam->ofp, &vam->json_tree);
1419       vam->json_tree.type = VAT_JSON_NONE;
1420     }
1421
1422   vam->retval = retval;
1423   vam->result_ready = 1;
1424 }
1425
1426 static void
1427   vl_api_bridge_domain_set_mac_age_reply_t_handler
1428   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1429 {
1430   vat_main_t *vam = &vat_main;
1431   i32 retval = ntohl (mp->retval);
1432   if (vam->async_mode)
1433     {
1434       vam->async_errors += (retval < 0);
1435     }
1436   else
1437     {
1438       vam->retval = retval;
1439       vam->result_ready = 1;
1440     }
1441 }
1442
1443 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1444   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1445 {
1446   vat_main_t *vam = &vat_main;
1447   vat_json_node_t node;
1448
1449   vat_json_init_object (&node);
1450   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1451
1452   vat_json_print (vam->ofp, &node);
1453   vat_json_free (&node);
1454
1455   vam->retval = ntohl (mp->retval);
1456   vam->result_ready = 1;
1457 }
1458
1459 static void
1460 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1461 {
1462   vat_main_t *vam = &vat_main;
1463   i32 retval = ntohl (mp->retval);
1464   if (vam->async_mode)
1465     {
1466       vam->async_errors += (retval < 0);
1467     }
1468   else
1469     {
1470       vam->retval = retval;
1471       vam->result_ready = 1;
1472     }
1473 }
1474
1475 static void vl_api_l2_flags_reply_t_handler_json
1476   (vl_api_l2_flags_reply_t * mp)
1477 {
1478   vat_main_t *vam = &vat_main;
1479   vat_json_node_t node;
1480
1481   vat_json_init_object (&node);
1482   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1483   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1484                             ntohl (mp->resulting_feature_bitmap));
1485
1486   vat_json_print (vam->ofp, &node);
1487   vat_json_free (&node);
1488
1489   vam->retval = ntohl (mp->retval);
1490   vam->result_ready = 1;
1491 }
1492
1493 static void vl_api_bridge_flags_reply_t_handler
1494   (vl_api_bridge_flags_reply_t * mp)
1495 {
1496   vat_main_t *vam = &vat_main;
1497   i32 retval = ntohl (mp->retval);
1498   if (vam->async_mode)
1499     {
1500       vam->async_errors += (retval < 0);
1501     }
1502   else
1503     {
1504       vam->retval = retval;
1505       vam->result_ready = 1;
1506     }
1507 }
1508
1509 static void vl_api_bridge_flags_reply_t_handler_json
1510   (vl_api_bridge_flags_reply_t * mp)
1511 {
1512   vat_main_t *vam = &vat_main;
1513   vat_json_node_t node;
1514
1515   vat_json_init_object (&node);
1516   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1517   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1518                             ntohl (mp->resulting_feature_bitmap));
1519
1520   vat_json_print (vam->ofp, &node);
1521   vat_json_free (&node);
1522
1523   vam->retval = ntohl (mp->retval);
1524   vam->result_ready = 1;
1525 }
1526
1527 static void vl_api_tap_connect_reply_t_handler
1528   (vl_api_tap_connect_reply_t * mp)
1529 {
1530   vat_main_t *vam = &vat_main;
1531   i32 retval = ntohl (mp->retval);
1532   if (vam->async_mode)
1533     {
1534       vam->async_errors += (retval < 0);
1535     }
1536   else
1537     {
1538       vam->retval = retval;
1539       vam->sw_if_index = ntohl (mp->sw_if_index);
1540       vam->result_ready = 1;
1541     }
1542
1543 }
1544
1545 static void vl_api_tap_connect_reply_t_handler_json
1546   (vl_api_tap_connect_reply_t * mp)
1547 {
1548   vat_main_t *vam = &vat_main;
1549   vat_json_node_t node;
1550
1551   vat_json_init_object (&node);
1552   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1553   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1554
1555   vat_json_print (vam->ofp, &node);
1556   vat_json_free (&node);
1557
1558   vam->retval = ntohl (mp->retval);
1559   vam->result_ready = 1;
1560
1561 }
1562
1563 static void
1564 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1565 {
1566   vat_main_t *vam = &vat_main;
1567   i32 retval = ntohl (mp->retval);
1568   if (vam->async_mode)
1569     {
1570       vam->async_errors += (retval < 0);
1571     }
1572   else
1573     {
1574       vam->retval = retval;
1575       vam->sw_if_index = ntohl (mp->sw_if_index);
1576       vam->result_ready = 1;
1577     }
1578 }
1579
1580 static void vl_api_tap_modify_reply_t_handler_json
1581   (vl_api_tap_modify_reply_t * mp)
1582 {
1583   vat_main_t *vam = &vat_main;
1584   vat_json_node_t node;
1585
1586   vat_json_init_object (&node);
1587   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1588   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1589
1590   vat_json_print (vam->ofp, &node);
1591   vat_json_free (&node);
1592
1593   vam->retval = ntohl (mp->retval);
1594   vam->result_ready = 1;
1595 }
1596
1597 static void
1598 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1599 {
1600   vat_main_t *vam = &vat_main;
1601   i32 retval = ntohl (mp->retval);
1602   if (vam->async_mode)
1603     {
1604       vam->async_errors += (retval < 0);
1605     }
1606   else
1607     {
1608       vam->retval = retval;
1609       vam->result_ready = 1;
1610     }
1611 }
1612
1613 static void vl_api_tap_delete_reply_t_handler_json
1614   (vl_api_tap_delete_reply_t * mp)
1615 {
1616   vat_main_t *vam = &vat_main;
1617   vat_json_node_t node;
1618
1619   vat_json_init_object (&node);
1620   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1621
1622   vat_json_print (vam->ofp, &node);
1623   vat_json_free (&node);
1624
1625   vam->retval = ntohl (mp->retval);
1626   vam->result_ready = 1;
1627 }
1628
1629 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1630   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1631 {
1632   vat_main_t *vam = &vat_main;
1633   i32 retval = ntohl (mp->retval);
1634   if (vam->async_mode)
1635     {
1636       vam->async_errors += (retval < 0);
1637     }
1638   else
1639     {
1640       vam->retval = retval;
1641       vam->result_ready = 1;
1642     }
1643 }
1644
1645 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1646   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1647 {
1648   vat_main_t *vam = &vat_main;
1649   vat_json_node_t node;
1650
1651   vat_json_init_object (&node);
1652   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1653   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1654                             ntohl (mp->sw_if_index));
1655
1656   vat_json_print (vam->ofp, &node);
1657   vat_json_free (&node);
1658
1659   vam->retval = ntohl (mp->retval);
1660   vam->result_ready = 1;
1661 }
1662
1663 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1664   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1665 {
1666   vat_main_t *vam = &vat_main;
1667   i32 retval = ntohl (mp->retval);
1668   if (vam->async_mode)
1669     {
1670       vam->async_errors += (retval < 0);
1671     }
1672   else
1673     {
1674       vam->retval = retval;
1675       vam->sw_if_index = ntohl (mp->sw_if_index);
1676       vam->result_ready = 1;
1677     }
1678 }
1679
1680 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1681   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1682 {
1683   vat_main_t *vam = &vat_main;
1684   vat_json_node_t node;
1685
1686   vat_json_init_object (&node);
1687   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1688   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1689
1690   vat_json_print (vam->ofp, &node);
1691   vat_json_free (&node);
1692
1693   vam->retval = ntohl (mp->retval);
1694   vam->result_ready = 1;
1695 }
1696
1697 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
1698   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1699 {
1700   vat_main_t *vam = &vat_main;
1701   i32 retval = ntohl (mp->retval);
1702   if (vam->async_mode)
1703     {
1704       vam->async_errors += (retval < 0);
1705     }
1706   else
1707     {
1708       vam->retval = retval;
1709       vam->result_ready = 1;
1710     }
1711 }
1712
1713 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
1714   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1715 {
1716   vat_main_t *vam = &vat_main;
1717   vat_json_node_t node;
1718
1719   vat_json_init_object (&node);
1720   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1721   vat_json_object_add_uint (&node, "fwd_entry_index",
1722                             clib_net_to_host_u32 (mp->fwd_entry_index));
1723
1724   vat_json_print (vam->ofp, &node);
1725   vat_json_free (&node);
1726
1727   vam->retval = ntohl (mp->retval);
1728   vam->result_ready = 1;
1729 }
1730
1731 static void vl_api_one_add_del_locator_set_reply_t_handler
1732   (vl_api_one_add_del_locator_set_reply_t * mp)
1733 {
1734   vat_main_t *vam = &vat_main;
1735   i32 retval = ntohl (mp->retval);
1736   if (vam->async_mode)
1737     {
1738       vam->async_errors += (retval < 0);
1739     }
1740   else
1741     {
1742       vam->retval = retval;
1743       vam->result_ready = 1;
1744     }
1745 }
1746
1747 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1748   (vl_api_one_add_del_locator_set_reply_t * mp)
1749 {
1750   vat_main_t *vam = &vat_main;
1751   vat_json_node_t node;
1752
1753   vat_json_init_object (&node);
1754   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1755   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1756
1757   vat_json_print (vam->ofp, &node);
1758   vat_json_free (&node);
1759
1760   vam->retval = ntohl (mp->retval);
1761   vam->result_ready = 1;
1762 }
1763
1764 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1765   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1766 {
1767   vat_main_t *vam = &vat_main;
1768   i32 retval = ntohl (mp->retval);
1769   if (vam->async_mode)
1770     {
1771       vam->async_errors += (retval < 0);
1772     }
1773   else
1774     {
1775       vam->retval = retval;
1776       vam->sw_if_index = ntohl (mp->sw_if_index);
1777       vam->result_ready = 1;
1778     }
1779 }
1780
1781 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1782   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1783 {
1784   vat_main_t *vam = &vat_main;
1785   vat_json_node_t node;
1786
1787   vat_json_init_object (&node);
1788   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1789   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1790
1791   vat_json_print (vam->ofp, &node);
1792   vat_json_free (&node);
1793
1794   vam->retval = ntohl (mp->retval);
1795   vam->result_ready = 1;
1796 }
1797
1798 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
1799   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
1800 {
1801   vat_main_t *vam = &vat_main;
1802   i32 retval = ntohl (mp->retval);
1803   if (vam->async_mode)
1804     {
1805       vam->async_errors += (retval < 0);
1806     }
1807   else
1808     {
1809       vam->retval = retval;
1810       vam->sw_if_index = ntohl (mp->sw_if_index);
1811       vam->result_ready = 1;
1812     }
1813 }
1814
1815 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
1816   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
1817 {
1818   vat_main_t *vam = &vat_main;
1819   vat_json_node_t node;
1820
1821   vat_json_init_object (&node);
1822   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1823   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1824
1825   vat_json_print (vam->ofp, &node);
1826   vat_json_free (&node);
1827
1828   vam->retval = ntohl (mp->retval);
1829   vam->result_ready = 1;
1830 }
1831
1832 static void vl_api_gre_add_del_tunnel_reply_t_handler
1833   (vl_api_gre_add_del_tunnel_reply_t * mp)
1834 {
1835   vat_main_t *vam = &vat_main;
1836   i32 retval = ntohl (mp->retval);
1837   if (vam->async_mode)
1838     {
1839       vam->async_errors += (retval < 0);
1840     }
1841   else
1842     {
1843       vam->retval = retval;
1844       vam->sw_if_index = ntohl (mp->sw_if_index);
1845       vam->result_ready = 1;
1846     }
1847 }
1848
1849 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1850   (vl_api_gre_add_del_tunnel_reply_t * mp)
1851 {
1852   vat_main_t *vam = &vat_main;
1853   vat_json_node_t node;
1854
1855   vat_json_init_object (&node);
1856   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1857   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1858
1859   vat_json_print (vam->ofp, &node);
1860   vat_json_free (&node);
1861
1862   vam->retval = ntohl (mp->retval);
1863   vam->result_ready = 1;
1864 }
1865
1866 static void vl_api_create_vhost_user_if_reply_t_handler
1867   (vl_api_create_vhost_user_if_reply_t * mp)
1868 {
1869   vat_main_t *vam = &vat_main;
1870   i32 retval = ntohl (mp->retval);
1871   if (vam->async_mode)
1872     {
1873       vam->async_errors += (retval < 0);
1874     }
1875   else
1876     {
1877       vam->retval = retval;
1878       vam->sw_if_index = ntohl (mp->sw_if_index);
1879       vam->result_ready = 1;
1880     }
1881 }
1882
1883 static void vl_api_create_vhost_user_if_reply_t_handler_json
1884   (vl_api_create_vhost_user_if_reply_t * mp)
1885 {
1886   vat_main_t *vam = &vat_main;
1887   vat_json_node_t node;
1888
1889   vat_json_init_object (&node);
1890   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1891   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1892
1893   vat_json_print (vam->ofp, &node);
1894   vat_json_free (&node);
1895
1896   vam->retval = ntohl (mp->retval);
1897   vam->result_ready = 1;
1898 }
1899
1900 static void vl_api_ip_address_details_t_handler
1901   (vl_api_ip_address_details_t * mp)
1902 {
1903   vat_main_t *vam = &vat_main;
1904   static ip_address_details_t empty_ip_address_details = { {0} };
1905   ip_address_details_t *address = NULL;
1906   ip_details_t *current_ip_details = NULL;
1907   ip_details_t *details = NULL;
1908
1909   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1910
1911   if (!details || vam->current_sw_if_index >= vec_len (details)
1912       || !details[vam->current_sw_if_index].present)
1913     {
1914       errmsg ("ip address details arrived but not stored");
1915       errmsg ("ip_dump should be called first");
1916       return;
1917     }
1918
1919   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1920
1921 #define addresses (current_ip_details->addr)
1922
1923   vec_validate_init_empty (addresses, vec_len (addresses),
1924                            empty_ip_address_details);
1925
1926   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1927
1928   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1929   address->prefix_length = mp->prefix_length;
1930 #undef addresses
1931 }
1932
1933 static void vl_api_ip_address_details_t_handler_json
1934   (vl_api_ip_address_details_t * mp)
1935 {
1936   vat_main_t *vam = &vat_main;
1937   vat_json_node_t *node = NULL;
1938   struct in6_addr ip6;
1939   struct in_addr ip4;
1940
1941   if (VAT_JSON_ARRAY != vam->json_tree.type)
1942     {
1943       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1944       vat_json_init_array (&vam->json_tree);
1945     }
1946   node = vat_json_array_add (&vam->json_tree);
1947
1948   vat_json_init_object (node);
1949   if (vam->is_ipv6)
1950     {
1951       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1952       vat_json_object_add_ip6 (node, "ip", ip6);
1953     }
1954   else
1955     {
1956       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1957       vat_json_object_add_ip4 (node, "ip", ip4);
1958     }
1959   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1960 }
1961
1962 static void
1963 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1964 {
1965   vat_main_t *vam = &vat_main;
1966   static ip_details_t empty_ip_details = { 0 };
1967   ip_details_t *ip = NULL;
1968   u32 sw_if_index = ~0;
1969
1970   sw_if_index = ntohl (mp->sw_if_index);
1971
1972   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1973                            sw_if_index, empty_ip_details);
1974
1975   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1976                          sw_if_index);
1977
1978   ip->present = 1;
1979 }
1980
1981 static void
1982 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1983 {
1984   vat_main_t *vam = &vat_main;
1985
1986   if (VAT_JSON_ARRAY != vam->json_tree.type)
1987     {
1988       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1989       vat_json_init_array (&vam->json_tree);
1990     }
1991   vat_json_array_add_uint (&vam->json_tree,
1992                            clib_net_to_host_u32 (mp->sw_if_index));
1993 }
1994
1995 static void vl_api_map_domain_details_t_handler_json
1996   (vl_api_map_domain_details_t * mp)
1997 {
1998   vat_json_node_t *node = NULL;
1999   vat_main_t *vam = &vat_main;
2000   struct in6_addr ip6;
2001   struct in_addr ip4;
2002
2003   if (VAT_JSON_ARRAY != vam->json_tree.type)
2004     {
2005       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2006       vat_json_init_array (&vam->json_tree);
2007     }
2008
2009   node = vat_json_array_add (&vam->json_tree);
2010   vat_json_init_object (node);
2011
2012   vat_json_object_add_uint (node, "domain_index",
2013                             clib_net_to_host_u32 (mp->domain_index));
2014   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
2015   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
2016   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
2017   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
2018   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
2019   vat_json_object_add_ip6 (node, "ip6_src", ip6);
2020   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
2021   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
2022   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
2023   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
2024   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
2025   vat_json_object_add_int (node, "psid_length", mp->psid_length);
2026   vat_json_object_add_uint (node, "flags", mp->flags);
2027   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
2028   vat_json_object_add_int (node, "is_translation", mp->is_translation);
2029 }
2030
2031 static void vl_api_map_domain_details_t_handler
2032   (vl_api_map_domain_details_t * mp)
2033 {
2034   vat_main_t *vam = &vat_main;
2035
2036   if (mp->is_translation)
2037     {
2038       print (vam->ofp,
2039              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2040              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2041              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2042              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2043              clib_net_to_host_u32 (mp->domain_index));
2044     }
2045   else
2046     {
2047       print (vam->ofp,
2048              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2049              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2050              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2051              format_ip6_address, mp->ip6_src,
2052              clib_net_to_host_u32 (mp->domain_index));
2053     }
2054   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2055          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2056          mp->is_translation ? "map-t" : "");
2057 }
2058
2059 static void vl_api_map_rule_details_t_handler_json
2060   (vl_api_map_rule_details_t * mp)
2061 {
2062   struct in6_addr ip6;
2063   vat_json_node_t *node = NULL;
2064   vat_main_t *vam = &vat_main;
2065
2066   if (VAT_JSON_ARRAY != vam->json_tree.type)
2067     {
2068       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2069       vat_json_init_array (&vam->json_tree);
2070     }
2071
2072   node = vat_json_array_add (&vam->json_tree);
2073   vat_json_init_object (node);
2074
2075   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2076   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2077   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2078 }
2079
2080 static void
2081 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2082 {
2083   vat_main_t *vam = &vat_main;
2084   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2085          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2086 }
2087
2088 static void
2089 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2090 {
2091   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2092           "router_addr %U host_mac %U",
2093           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2094           format_ip4_address, &mp->host_address,
2095           format_ip4_address, &mp->router_address,
2096           format_ethernet_address, mp->host_mac);
2097 }
2098
2099 static void vl_api_dhcp_compl_event_t_handler_json
2100   (vl_api_dhcp_compl_event_t * mp)
2101 {
2102   /* JSON output not supported */
2103 }
2104
2105 static void
2106 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2107                               u32 counter)
2108 {
2109   vat_main_t *vam = &vat_main;
2110   static u64 default_counter = 0;
2111
2112   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2113                            NULL);
2114   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2115                            sw_if_index, default_counter);
2116   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2117 }
2118
2119 static void
2120 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2121                                 interface_counter_t counter)
2122 {
2123   vat_main_t *vam = &vat_main;
2124   static interface_counter_t default_counter = { 0, };
2125
2126   vec_validate_init_empty (vam->combined_interface_counters,
2127                            vnet_counter_type, NULL);
2128   vec_validate_init_empty (vam->combined_interface_counters
2129                            [vnet_counter_type], sw_if_index, default_counter);
2130   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2131 }
2132
2133 static void vl_api_vnet_interface_simple_counters_t_handler
2134   (vl_api_vnet_interface_simple_counters_t * mp)
2135 {
2136   /* not supported */
2137 }
2138
2139 static void vl_api_vnet_interface_combined_counters_t_handler
2140   (vl_api_vnet_interface_combined_counters_t * mp)
2141 {
2142   /* not supported */
2143 }
2144
2145 static void vl_api_vnet_interface_simple_counters_t_handler_json
2146   (vl_api_vnet_interface_simple_counters_t * mp)
2147 {
2148   u64 *v_packets;
2149   u64 packets;
2150   u32 count;
2151   u32 first_sw_if_index;
2152   int i;
2153
2154   count = ntohl (mp->count);
2155   first_sw_if_index = ntohl (mp->first_sw_if_index);
2156
2157   v_packets = (u64 *) & mp->data;
2158   for (i = 0; i < count; i++)
2159     {
2160       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2161       set_simple_interface_counter (mp->vnet_counter_type,
2162                                     first_sw_if_index + i, packets);
2163       v_packets++;
2164     }
2165 }
2166
2167 static void vl_api_vnet_interface_combined_counters_t_handler_json
2168   (vl_api_vnet_interface_combined_counters_t * mp)
2169 {
2170   interface_counter_t counter;
2171   vlib_counter_t *v;
2172   u32 first_sw_if_index;
2173   int i;
2174   u32 count;
2175
2176   count = ntohl (mp->count);
2177   first_sw_if_index = ntohl (mp->first_sw_if_index);
2178
2179   v = (vlib_counter_t *) & mp->data;
2180   for (i = 0; i < count; i++)
2181     {
2182       counter.packets =
2183         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2184       counter.bytes =
2185         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2186       set_combined_interface_counter (mp->vnet_counter_type,
2187                                       first_sw_if_index + i, counter);
2188       v++;
2189     }
2190 }
2191
2192 static u32
2193 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2194 {
2195   vat_main_t *vam = &vat_main;
2196   u32 i;
2197
2198   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2199     {
2200       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2201         {
2202           return i;
2203         }
2204     }
2205   return ~0;
2206 }
2207
2208 static u32
2209 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2210 {
2211   vat_main_t *vam = &vat_main;
2212   u32 i;
2213
2214   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2215     {
2216       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2217         {
2218           return i;
2219         }
2220     }
2221   return ~0;
2222 }
2223
2224 static void vl_api_vnet_ip4_fib_counters_t_handler
2225   (vl_api_vnet_ip4_fib_counters_t * mp)
2226 {
2227   /* not supported */
2228 }
2229
2230 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2231   (vl_api_vnet_ip4_fib_counters_t * mp)
2232 {
2233   vat_main_t *vam = &vat_main;
2234   vl_api_ip4_fib_counter_t *v;
2235   ip4_fib_counter_t *counter;
2236   struct in_addr ip4;
2237   u32 vrf_id;
2238   u32 vrf_index;
2239   u32 count;
2240   int i;
2241
2242   vrf_id = ntohl (mp->vrf_id);
2243   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2244   if (~0 == vrf_index)
2245     {
2246       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2247       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2248       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2249       vec_validate (vam->ip4_fib_counters, vrf_index);
2250       vam->ip4_fib_counters[vrf_index] = NULL;
2251     }
2252
2253   vec_free (vam->ip4_fib_counters[vrf_index]);
2254   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2255   count = ntohl (mp->count);
2256   for (i = 0; i < count; i++)
2257     {
2258       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2259       counter = &vam->ip4_fib_counters[vrf_index][i];
2260       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2261       counter->address = ip4;
2262       counter->address_length = v->address_length;
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_vnet_ip4_nbr_counters_t_handler
2270   (vl_api_vnet_ip4_nbr_counters_t * mp)
2271 {
2272   /* not supported */
2273 }
2274
2275 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2276   (vl_api_vnet_ip4_nbr_counters_t * mp)
2277 {
2278   vat_main_t *vam = &vat_main;
2279   vl_api_ip4_nbr_counter_t *v;
2280   ip4_nbr_counter_t *counter;
2281   u32 sw_if_index;
2282   u32 count;
2283   int i;
2284
2285   sw_if_index = ntohl (mp->sw_if_index);
2286   count = ntohl (mp->count);
2287   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2288
2289   if (mp->begin)
2290     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2291
2292   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2293   for (i = 0; i < count; i++)
2294     {
2295       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2296       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2297       counter->address.s_addr = v->address;
2298       counter->packets = clib_net_to_host_u64 (v->packets);
2299       counter->bytes = clib_net_to_host_u64 (v->bytes);
2300       counter->linkt = v->link_type;
2301       v++;
2302     }
2303 }
2304
2305 static void vl_api_vnet_ip6_fib_counters_t_handler
2306   (vl_api_vnet_ip6_fib_counters_t * mp)
2307 {
2308   /* not supported */
2309 }
2310
2311 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2312   (vl_api_vnet_ip6_fib_counters_t * mp)
2313 {
2314   vat_main_t *vam = &vat_main;
2315   vl_api_ip6_fib_counter_t *v;
2316   ip6_fib_counter_t *counter;
2317   struct in6_addr ip6;
2318   u32 vrf_id;
2319   u32 vrf_index;
2320   u32 count;
2321   int i;
2322
2323   vrf_id = ntohl (mp->vrf_id);
2324   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2325   if (~0 == vrf_index)
2326     {
2327       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2328       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2329       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2330       vec_validate (vam->ip6_fib_counters, vrf_index);
2331       vam->ip6_fib_counters[vrf_index] = NULL;
2332     }
2333
2334   vec_free (vam->ip6_fib_counters[vrf_index]);
2335   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2336   count = ntohl (mp->count);
2337   for (i = 0; i < count; i++)
2338     {
2339       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2340       counter = &vam->ip6_fib_counters[vrf_index][i];
2341       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2342       counter->address = ip6;
2343       counter->address_length = v->address_length;
2344       counter->packets = clib_net_to_host_u64 (v->packets);
2345       counter->bytes = clib_net_to_host_u64 (v->bytes);
2346       v++;
2347     }
2348 }
2349
2350 static void vl_api_vnet_ip6_nbr_counters_t_handler
2351   (vl_api_vnet_ip6_nbr_counters_t * mp)
2352 {
2353   /* not supported */
2354 }
2355
2356 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2357   (vl_api_vnet_ip6_nbr_counters_t * mp)
2358 {
2359   vat_main_t *vam = &vat_main;
2360   vl_api_ip6_nbr_counter_t *v;
2361   ip6_nbr_counter_t *counter;
2362   struct in6_addr ip6;
2363   u32 sw_if_index;
2364   u32 count;
2365   int i;
2366
2367   sw_if_index = ntohl (mp->sw_if_index);
2368   count = ntohl (mp->count);
2369   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2370
2371   if (mp->begin)
2372     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2373
2374   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2375   for (i = 0; i < count; i++)
2376     {
2377       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2378       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2379       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2380       counter->address = ip6;
2381       counter->packets = clib_net_to_host_u64 (v->packets);
2382       counter->bytes = clib_net_to_host_u64 (v->bytes);
2383       v++;
2384     }
2385 }
2386
2387 static void vl_api_get_first_msg_id_reply_t_handler
2388   (vl_api_get_first_msg_id_reply_t * mp)
2389 {
2390   vat_main_t *vam = &vat_main;
2391   i32 retval = ntohl (mp->retval);
2392
2393   if (vam->async_mode)
2394     {
2395       vam->async_errors += (retval < 0);
2396     }
2397   else
2398     {
2399       vam->retval = retval;
2400       vam->result_ready = 1;
2401     }
2402   if (retval >= 0)
2403     {
2404       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2405     }
2406 }
2407
2408 static void vl_api_get_first_msg_id_reply_t_handler_json
2409   (vl_api_get_first_msg_id_reply_t * mp)
2410 {
2411   vat_main_t *vam = &vat_main;
2412   vat_json_node_t node;
2413
2414   vat_json_init_object (&node);
2415   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2416   vat_json_object_add_uint (&node, "first_msg_id",
2417                             (uint) ntohs (mp->first_msg_id));
2418
2419   vat_json_print (vam->ofp, &node);
2420   vat_json_free (&node);
2421
2422   vam->retval = ntohl (mp->retval);
2423   vam->result_ready = 1;
2424 }
2425
2426 static void vl_api_get_node_graph_reply_t_handler
2427   (vl_api_get_node_graph_reply_t * mp)
2428 {
2429   vat_main_t *vam = &vat_main;
2430   api_main_t *am = &api_main;
2431   i32 retval = ntohl (mp->retval);
2432   u8 *pvt_copy, *reply;
2433   void *oldheap;
2434   vlib_node_t *node;
2435   int i;
2436
2437   if (vam->async_mode)
2438     {
2439       vam->async_errors += (retval < 0);
2440     }
2441   else
2442     {
2443       vam->retval = retval;
2444       vam->result_ready = 1;
2445     }
2446
2447   /* "Should never happen..." */
2448   if (retval != 0)
2449     return;
2450
2451   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2452   pvt_copy = vec_dup (reply);
2453
2454   /* Toss the shared-memory original... */
2455   pthread_mutex_lock (&am->vlib_rp->mutex);
2456   oldheap = svm_push_data_heap (am->vlib_rp);
2457
2458   vec_free (reply);
2459
2460   svm_pop_heap (oldheap);
2461   pthread_mutex_unlock (&am->vlib_rp->mutex);
2462
2463   if (vam->graph_nodes)
2464     {
2465       hash_free (vam->graph_node_index_by_name);
2466
2467       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2468         {
2469           node = vam->graph_nodes[i];
2470           vec_free (node->name);
2471           vec_free (node->next_nodes);
2472           vec_free (node);
2473         }
2474       vec_free (vam->graph_nodes);
2475     }
2476
2477   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2478   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2479   vec_free (pvt_copy);
2480
2481   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2482     {
2483       node = vam->graph_nodes[i];
2484       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2485     }
2486 }
2487
2488 static void vl_api_get_node_graph_reply_t_handler_json
2489   (vl_api_get_node_graph_reply_t * mp)
2490 {
2491   vat_main_t *vam = &vat_main;
2492   api_main_t *am = &api_main;
2493   void *oldheap;
2494   vat_json_node_t node;
2495   u8 *reply;
2496
2497   /* $$$$ make this real? */
2498   vat_json_init_object (&node);
2499   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2500   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2501
2502   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2503
2504   /* Toss the shared-memory original... */
2505   pthread_mutex_lock (&am->vlib_rp->mutex);
2506   oldheap = svm_push_data_heap (am->vlib_rp);
2507
2508   vec_free (reply);
2509
2510   svm_pop_heap (oldheap);
2511   pthread_mutex_unlock (&am->vlib_rp->mutex);
2512
2513   vat_json_print (vam->ofp, &node);
2514   vat_json_free (&node);
2515
2516   vam->retval = ntohl (mp->retval);
2517   vam->result_ready = 1;
2518 }
2519
2520 static void
2521 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2522 {
2523   vat_main_t *vam = &vat_main;
2524   u8 *s = 0;
2525
2526   if (mp->local)
2527     {
2528       s = format (s, "%=16d%=16d%=16d",
2529                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2530     }
2531   else
2532     {
2533       s = format (s, "%=16U%=16d%=16d",
2534                   mp->is_ipv6 ? format_ip6_address :
2535                   format_ip4_address,
2536                   mp->ip_address, mp->priority, mp->weight);
2537     }
2538
2539   print (vam->ofp, "%v", s);
2540   vec_free (s);
2541 }
2542
2543 static void
2544 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2545 {
2546   vat_main_t *vam = &vat_main;
2547   vat_json_node_t *node = NULL;
2548   struct in6_addr ip6;
2549   struct in_addr ip4;
2550
2551   if (VAT_JSON_ARRAY != vam->json_tree.type)
2552     {
2553       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2554       vat_json_init_array (&vam->json_tree);
2555     }
2556   node = vat_json_array_add (&vam->json_tree);
2557   vat_json_init_object (node);
2558
2559   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2560   vat_json_object_add_uint (node, "priority", mp->priority);
2561   vat_json_object_add_uint (node, "weight", mp->weight);
2562
2563   if (mp->local)
2564     vat_json_object_add_uint (node, "sw_if_index",
2565                               clib_net_to_host_u32 (mp->sw_if_index));
2566   else
2567     {
2568       if (mp->is_ipv6)
2569         {
2570           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2571           vat_json_object_add_ip6 (node, "address", ip6);
2572         }
2573       else
2574         {
2575           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2576           vat_json_object_add_ip4 (node, "address", ip4);
2577         }
2578     }
2579 }
2580
2581 static void
2582 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2583                                           mp)
2584 {
2585   vat_main_t *vam = &vat_main;
2586   u8 *ls_name = 0;
2587
2588   ls_name = format (0, "%s", mp->ls_name);
2589
2590   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2591          ls_name);
2592   vec_free (ls_name);
2593 }
2594
2595 static void
2596   vl_api_one_locator_set_details_t_handler_json
2597   (vl_api_one_locator_set_details_t * mp)
2598 {
2599   vat_main_t *vam = &vat_main;
2600   vat_json_node_t *node = 0;
2601   u8 *ls_name = 0;
2602
2603   ls_name = format (0, "%s", mp->ls_name);
2604   vec_add1 (ls_name, 0);
2605
2606   if (VAT_JSON_ARRAY != vam->json_tree.type)
2607     {
2608       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2609       vat_json_init_array (&vam->json_tree);
2610     }
2611   node = vat_json_array_add (&vam->json_tree);
2612
2613   vat_json_init_object (node);
2614   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2615   vat_json_object_add_uint (node, "ls_index",
2616                             clib_net_to_host_u32 (mp->ls_index));
2617   vec_free (ls_name);
2618 }
2619
2620 typedef struct
2621 {
2622   u32 spi;
2623   u8 si;
2624 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2625
2626 uword
2627 unformat_nsh_address (unformat_input_t * input, va_list * args)
2628 {
2629   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2630   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2631 }
2632
2633 u8 *
2634 format_nsh_address_vat (u8 * s, va_list * args)
2635 {
2636   nsh_t *a = va_arg (*args, nsh_t *);
2637   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2638 }
2639
2640 static u8 *
2641 format_lisp_flat_eid (u8 * s, va_list * args)
2642 {
2643   u32 type = va_arg (*args, u32);
2644   u8 *eid = va_arg (*args, u8 *);
2645   u32 eid_len = va_arg (*args, u32);
2646
2647   switch (type)
2648     {
2649     case 0:
2650       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2651     case 1:
2652       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2653     case 2:
2654       return format (s, "%U", format_ethernet_address, eid);
2655     case 3:
2656       return format (s, "%U", format_nsh_address_vat, eid);
2657     }
2658   return 0;
2659 }
2660
2661 static u8 *
2662 format_lisp_eid_vat (u8 * s, va_list * args)
2663 {
2664   u32 type = va_arg (*args, u32);
2665   u8 *eid = va_arg (*args, u8 *);
2666   u32 eid_len = va_arg (*args, u32);
2667   u8 *seid = va_arg (*args, u8 *);
2668   u32 seid_len = va_arg (*args, u32);
2669   u32 is_src_dst = va_arg (*args, u32);
2670
2671   if (is_src_dst)
2672     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2673
2674   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2675
2676   return s;
2677 }
2678
2679 static void
2680 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2681 {
2682   vat_main_t *vam = &vat_main;
2683   u8 *s = 0, *eid = 0;
2684
2685   if (~0 == mp->locator_set_index)
2686     s = format (0, "action: %d", mp->action);
2687   else
2688     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2689
2690   eid = format (0, "%U", format_lisp_eid_vat,
2691                 mp->eid_type,
2692                 mp->eid,
2693                 mp->eid_prefix_len,
2694                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2695   vec_add1 (eid, 0);
2696
2697   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2698          clib_net_to_host_u32 (mp->vni),
2699          eid,
2700          mp->is_local ? "local" : "remote",
2701          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2702          clib_net_to_host_u16 (mp->key_id), mp->key);
2703
2704   vec_free (s);
2705   vec_free (eid);
2706 }
2707
2708 static void
2709 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2710                                              * mp)
2711 {
2712   vat_main_t *vam = &vat_main;
2713   vat_json_node_t *node = 0;
2714   u8 *eid = 0;
2715
2716   if (VAT_JSON_ARRAY != vam->json_tree.type)
2717     {
2718       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2719       vat_json_init_array (&vam->json_tree);
2720     }
2721   node = vat_json_array_add (&vam->json_tree);
2722
2723   vat_json_init_object (node);
2724   if (~0 == mp->locator_set_index)
2725     vat_json_object_add_uint (node, "action", mp->action);
2726   else
2727     vat_json_object_add_uint (node, "locator_set_index",
2728                               clib_net_to_host_u32 (mp->locator_set_index));
2729
2730   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2731   if (mp->eid_type == 3)
2732     {
2733       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
2734       vat_json_init_object (nsh_json);
2735       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
2736       vat_json_object_add_uint (nsh_json, "spi",
2737                                 clib_net_to_host_u32 (nsh->spi));
2738       vat_json_object_add_uint (nsh_json, "si", nsh->si);
2739     }
2740   else
2741     {
2742       eid = format (0, "%U", format_lisp_eid_vat,
2743                     mp->eid_type,
2744                     mp->eid,
2745                     mp->eid_prefix_len,
2746                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2747       vec_add1 (eid, 0);
2748       vat_json_object_add_string_copy (node, "eid", eid);
2749       vec_free (eid);
2750     }
2751   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2752   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2753   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2754
2755   if (mp->key_id)
2756     {
2757       vat_json_object_add_uint (node, "key_id",
2758                                 clib_net_to_host_u16 (mp->key_id));
2759       vat_json_object_add_string_copy (node, "key", mp->key);
2760     }
2761 }
2762
2763 static void
2764 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
2765 {
2766   vat_main_t *vam = &vat_main;
2767   u8 *seid = 0, *deid = 0;
2768   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2769
2770   deid = format (0, "%U", format_lisp_eid_vat,
2771                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2772
2773   seid = format (0, "%U", format_lisp_eid_vat,
2774                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2775
2776   vec_add1 (deid, 0);
2777   vec_add1 (seid, 0);
2778
2779   if (mp->is_ip4)
2780     format_ip_address_fcn = format_ip4_address;
2781   else
2782     format_ip_address_fcn = format_ip6_address;
2783
2784
2785   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
2786          clib_net_to_host_u32 (mp->vni),
2787          seid, deid,
2788          format_ip_address_fcn, mp->lloc,
2789          format_ip_address_fcn, mp->rloc,
2790          clib_net_to_host_u32 (mp->pkt_count),
2791          clib_net_to_host_u32 (mp->bytes));
2792
2793   vec_free (deid);
2794   vec_free (seid);
2795 }
2796
2797 static void
2798 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
2799 {
2800   struct in6_addr ip6;
2801   struct in_addr ip4;
2802   vat_main_t *vam = &vat_main;
2803   vat_json_node_t *node = 0;
2804   u8 *deid = 0, *seid = 0;
2805
2806   if (VAT_JSON_ARRAY != vam->json_tree.type)
2807     {
2808       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2809       vat_json_init_array (&vam->json_tree);
2810     }
2811   node = vat_json_array_add (&vam->json_tree);
2812
2813   vat_json_init_object (node);
2814   deid = format (0, "%U", format_lisp_eid_vat,
2815                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2816
2817   seid = format (0, "%U", format_lisp_eid_vat,
2818                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2819
2820   vec_add1 (deid, 0);
2821   vec_add1 (seid, 0);
2822
2823   vat_json_object_add_string_copy (node, "seid", seid);
2824   vat_json_object_add_string_copy (node, "deid", deid);
2825   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2826
2827   if (mp->is_ip4)
2828     {
2829       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
2830       vat_json_object_add_ip4 (node, "lloc", ip4);
2831       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
2832       vat_json_object_add_ip4 (node, "rloc", ip4);
2833     }
2834   else
2835     {
2836       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
2837       vat_json_object_add_ip6 (node, "lloc", ip6);
2838       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
2839       vat_json_object_add_ip6 (node, "rloc", ip6);
2840     }
2841   vat_json_object_add_uint (node, "pkt_count",
2842                             clib_net_to_host_u32 (mp->pkt_count));
2843   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
2844
2845   vec_free (deid);
2846   vec_free (seid);
2847 }
2848
2849 static void
2850   vl_api_one_eid_table_map_details_t_handler
2851   (vl_api_one_eid_table_map_details_t * mp)
2852 {
2853   vat_main_t *vam = &vat_main;
2854
2855   u8 *line = format (0, "%=10d%=10d",
2856                      clib_net_to_host_u32 (mp->vni),
2857                      clib_net_to_host_u32 (mp->dp_table));
2858   print (vam->ofp, "%v", line);
2859   vec_free (line);
2860 }
2861
2862 static void
2863   vl_api_one_eid_table_map_details_t_handler_json
2864   (vl_api_one_eid_table_map_details_t * mp)
2865 {
2866   vat_main_t *vam = &vat_main;
2867   vat_json_node_t *node = NULL;
2868
2869   if (VAT_JSON_ARRAY != vam->json_tree.type)
2870     {
2871       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2872       vat_json_init_array (&vam->json_tree);
2873     }
2874   node = vat_json_array_add (&vam->json_tree);
2875   vat_json_init_object (node);
2876   vat_json_object_add_uint (node, "dp_table",
2877                             clib_net_to_host_u32 (mp->dp_table));
2878   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2879 }
2880
2881 static void
2882   vl_api_one_eid_table_vni_details_t_handler
2883   (vl_api_one_eid_table_vni_details_t * mp)
2884 {
2885   vat_main_t *vam = &vat_main;
2886
2887   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2888   print (vam->ofp, "%v", line);
2889   vec_free (line);
2890 }
2891
2892 static void
2893   vl_api_one_eid_table_vni_details_t_handler_json
2894   (vl_api_one_eid_table_vni_details_t * mp)
2895 {
2896   vat_main_t *vam = &vat_main;
2897   vat_json_node_t *node = NULL;
2898
2899   if (VAT_JSON_ARRAY != vam->json_tree.type)
2900     {
2901       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2902       vat_json_init_array (&vam->json_tree);
2903     }
2904   node = vat_json_array_add (&vam->json_tree);
2905   vat_json_init_object (node);
2906   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2907 }
2908
2909 static void
2910   vl_api_show_one_map_register_state_reply_t_handler
2911   (vl_api_show_one_map_register_state_reply_t * mp)
2912 {
2913   vat_main_t *vam = &vat_main;
2914   int retval = clib_net_to_host_u32 (mp->retval);
2915
2916   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2917
2918   vam->retval = retval;
2919   vam->result_ready = 1;
2920 }
2921
2922 static void
2923   vl_api_show_one_map_register_state_reply_t_handler_json
2924   (vl_api_show_one_map_register_state_reply_t * mp)
2925 {
2926   vat_main_t *vam = &vat_main;
2927   vat_json_node_t _node, *node = &_node;
2928   int retval = clib_net_to_host_u32 (mp->retval);
2929
2930   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2931
2932   vat_json_init_object (node);
2933   vat_json_object_add_string_copy (node, "state", s);
2934
2935   vat_json_print (vam->ofp, node);
2936   vat_json_free (node);
2937
2938   vam->retval = retval;
2939   vam->result_ready = 1;
2940   vec_free (s);
2941 }
2942
2943 static void
2944   vl_api_show_one_rloc_probe_state_reply_t_handler
2945   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2946 {
2947   vat_main_t *vam = &vat_main;
2948   int retval = clib_net_to_host_u32 (mp->retval);
2949
2950   if (retval)
2951     goto end;
2952
2953   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2954 end:
2955   vam->retval = retval;
2956   vam->result_ready = 1;
2957 }
2958
2959 static void
2960   vl_api_show_one_rloc_probe_state_reply_t_handler_json
2961   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2962 {
2963   vat_main_t *vam = &vat_main;
2964   vat_json_node_t _node, *node = &_node;
2965   int retval = clib_net_to_host_u32 (mp->retval);
2966
2967   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2968   vat_json_init_object (node);
2969   vat_json_object_add_string_copy (node, "state", s);
2970
2971   vat_json_print (vam->ofp, node);
2972   vat_json_free (node);
2973
2974   vam->retval = retval;
2975   vam->result_ready = 1;
2976   vec_free (s);
2977 }
2978
2979 static void
2980   vl_api_show_one_stats_enable_disable_reply_t_handler
2981   (vl_api_show_one_stats_enable_disable_reply_t * mp)
2982 {
2983   vat_main_t *vam = &vat_main;
2984   int retval = clib_net_to_host_u32 (mp->retval);
2985
2986   if (retval)
2987     goto end;
2988
2989   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
2990 end:
2991   vam->retval = retval;
2992   vam->result_ready = 1;
2993 }
2994
2995 static void
2996   vl_api_show_one_stats_enable_disable_reply_t_handler_json
2997   (vl_api_show_one_stats_enable_disable_reply_t * mp)
2998 {
2999   vat_main_t *vam = &vat_main;
3000   vat_json_node_t _node, *node = &_node;
3001   int retval = clib_net_to_host_u32 (mp->retval);
3002
3003   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3004   vat_json_init_object (node);
3005   vat_json_object_add_string_copy (node, "state", s);
3006
3007   vat_json_print (vam->ofp, node);
3008   vat_json_free (node);
3009
3010   vam->retval = retval;
3011   vam->result_ready = 1;
3012   vec_free (s);
3013 }
3014
3015 static void
3016 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3017 {
3018   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3019   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3020   e->vni = clib_net_to_host_u32 (e->vni);
3021 }
3022
3023 static void
3024   gpe_fwd_entries_get_reply_t_net_to_host
3025   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3026 {
3027   u32 i;
3028
3029   mp->count = clib_net_to_host_u32 (mp->count);
3030   for (i = 0; i < mp->count; i++)
3031     {
3032       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3033     }
3034 }
3035
3036 static u8 *
3037 format_gpe_encap_mode (u8 * s, va_list * args)
3038 {
3039   u32 mode = va_arg (*args, u32);
3040
3041   switch (mode)
3042     {
3043     case 0:
3044       return format (s, "lisp");
3045     case 1:
3046       return format (s, "vxlan");
3047     }
3048   return 0;
3049 }
3050
3051 static void
3052   vl_api_gpe_get_encap_mode_reply_t_handler
3053   (vl_api_gpe_get_encap_mode_reply_t * mp)
3054 {
3055   vat_main_t *vam = &vat_main;
3056
3057   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3058   vam->retval = ntohl (mp->retval);
3059   vam->result_ready = 1;
3060 }
3061
3062 static void
3063   vl_api_gpe_get_encap_mode_reply_t_handler_json
3064   (vl_api_gpe_get_encap_mode_reply_t * mp)
3065 {
3066   vat_main_t *vam = &vat_main;
3067   vat_json_node_t node;
3068
3069   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3070   vec_add1 (encap_mode, 0);
3071
3072   vat_json_init_object (&node);
3073   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3074
3075   vec_free (encap_mode);
3076   vat_json_print (vam->ofp, &node);
3077   vat_json_free (&node);
3078
3079   vam->retval = ntohl (mp->retval);
3080   vam->result_ready = 1;
3081 }
3082
3083 static void
3084   vl_api_gpe_fwd_entry_path_details_t_handler
3085   (vl_api_gpe_fwd_entry_path_details_t * mp)
3086 {
3087   vat_main_t *vam = &vat_main;
3088   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3089
3090   if (mp->lcl_loc.is_ip4)
3091     format_ip_address_fcn = format_ip4_address;
3092   else
3093     format_ip_address_fcn = format_ip6_address;
3094
3095   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3096          format_ip_address_fcn, &mp->lcl_loc,
3097          format_ip_address_fcn, &mp->rmt_loc);
3098 }
3099
3100 static void
3101 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3102 {
3103   struct in6_addr ip6;
3104   struct in_addr ip4;
3105
3106   if (loc->is_ip4)
3107     {
3108       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3109       vat_json_object_add_ip4 (n, "address", ip4);
3110     }
3111   else
3112     {
3113       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3114       vat_json_object_add_ip6 (n, "address", ip6);
3115     }
3116   vat_json_object_add_uint (n, "weight", loc->weight);
3117 }
3118
3119 static void
3120   vl_api_gpe_fwd_entry_path_details_t_handler_json
3121   (vl_api_gpe_fwd_entry_path_details_t * mp)
3122 {
3123   vat_main_t *vam = &vat_main;
3124   vat_json_node_t *node = NULL;
3125   vat_json_node_t *loc_node;
3126
3127   if (VAT_JSON_ARRAY != vam->json_tree.type)
3128     {
3129       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3130       vat_json_init_array (&vam->json_tree);
3131     }
3132   node = vat_json_array_add (&vam->json_tree);
3133   vat_json_init_object (node);
3134
3135   loc_node = vat_json_object_add (node, "local_locator");
3136   vat_json_init_object (loc_node);
3137   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3138
3139   loc_node = vat_json_object_add (node, "remote_locator");
3140   vat_json_init_object (loc_node);
3141   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3142 }
3143
3144 static void
3145   vl_api_gpe_fwd_entries_get_reply_t_handler
3146   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3147 {
3148   vat_main_t *vam = &vat_main;
3149   u32 i;
3150   int retval = clib_net_to_host_u32 (mp->retval);
3151   vl_api_gpe_fwd_entry_t *e;
3152
3153   if (retval)
3154     goto end;
3155
3156   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3157
3158   for (i = 0; i < mp->count; i++)
3159     {
3160       e = &mp->entries[i];
3161       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3162              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3163              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3164     }
3165
3166 end:
3167   vam->retval = retval;
3168   vam->result_ready = 1;
3169 }
3170
3171 static void
3172   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3173   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3174 {
3175   u8 *s = 0;
3176   vat_main_t *vam = &vat_main;
3177   vat_json_node_t *e = 0, root;
3178   u32 i;
3179   int retval = clib_net_to_host_u32 (mp->retval);
3180   vl_api_gpe_fwd_entry_t *fwd;
3181
3182   if (retval)
3183     goto end;
3184
3185   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3186   vat_json_init_array (&root);
3187
3188   for (i = 0; i < mp->count; i++)
3189     {
3190       e = vat_json_array_add (&root);
3191       fwd = &mp->entries[i];
3192
3193       vat_json_init_object (e);
3194       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3195       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3196       vat_json_object_add_int (e, "vni", fwd->vni);
3197       vat_json_object_add_int (e, "action", fwd->action);
3198
3199       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3200                   fwd->leid_prefix_len);
3201       vec_add1 (s, 0);
3202       vat_json_object_add_string_copy (e, "leid", s);
3203       vec_free (s);
3204
3205       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3206                   fwd->reid_prefix_len);
3207       vec_add1 (s, 0);
3208       vat_json_object_add_string_copy (e, "reid", s);
3209       vec_free (s);
3210     }
3211
3212   vat_json_print (vam->ofp, &root);
3213   vat_json_free (&root);
3214
3215 end:
3216   vam->retval = retval;
3217   vam->result_ready = 1;
3218 }
3219
3220 static void
3221   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3222   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3223 {
3224   vat_main_t *vam = &vat_main;
3225   u32 i, n;
3226   int retval = clib_net_to_host_u32 (mp->retval);
3227   vl_api_gpe_native_fwd_rpath_t *r;
3228
3229   if (retval)
3230     goto end;
3231
3232   n = clib_net_to_host_u32 (mp->count);
3233
3234   for (i = 0; i < n; i++)
3235     {
3236       r = &mp->entries[i];
3237       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3238              clib_net_to_host_u32 (r->fib_index),
3239              clib_net_to_host_u32 (r->nh_sw_if_index),
3240              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3241     }
3242
3243 end:
3244   vam->retval = retval;
3245   vam->result_ready = 1;
3246 }
3247
3248 static void
3249   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3250   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3251 {
3252   vat_main_t *vam = &vat_main;
3253   vat_json_node_t root, *e;
3254   u32 i, n;
3255   int retval = clib_net_to_host_u32 (mp->retval);
3256   vl_api_gpe_native_fwd_rpath_t *r;
3257   u8 *s;
3258
3259   if (retval)
3260     goto end;
3261
3262   n = clib_net_to_host_u32 (mp->count);
3263   vat_json_init_array (&root);
3264
3265   for (i = 0; i < n; i++)
3266     {
3267       e = vat_json_array_add (&root);
3268       vat_json_init_object (e);
3269       r = &mp->entries[i];
3270       s =
3271         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3272                 r->nh_addr);
3273       vec_add1 (s, 0);
3274       vat_json_object_add_string_copy (e, "ip4", s);
3275       vec_free (s);
3276
3277       vat_json_object_add_uint (e, "fib_index",
3278                                 clib_net_to_host_u32 (r->fib_index));
3279       vat_json_object_add_uint (e, "nh_sw_if_index",
3280                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3281     }
3282
3283   vat_json_print (vam->ofp, &root);
3284   vat_json_free (&root);
3285
3286 end:
3287   vam->retval = retval;
3288   vam->result_ready = 1;
3289 }
3290
3291 static void
3292   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3293   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3294 {
3295   vat_main_t *vam = &vat_main;
3296   u32 i, n;
3297   int retval = clib_net_to_host_u32 (mp->retval);
3298
3299   if (retval)
3300     goto end;
3301
3302   n = clib_net_to_host_u32 (mp->count);
3303
3304   for (i = 0; i < n; i++)
3305     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3306
3307 end:
3308   vam->retval = retval;
3309   vam->result_ready = 1;
3310 }
3311
3312 static void
3313   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3314   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3315 {
3316   vat_main_t *vam = &vat_main;
3317   vat_json_node_t root;
3318   u32 i, n;
3319   int retval = clib_net_to_host_u32 (mp->retval);
3320
3321   if (retval)
3322     goto end;
3323
3324   n = clib_net_to_host_u32 (mp->count);
3325   vat_json_init_array (&root);
3326
3327   for (i = 0; i < n; i++)
3328     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3329
3330   vat_json_print (vam->ofp, &root);
3331   vat_json_free (&root);
3332
3333 end:
3334   vam->retval = retval;
3335   vam->result_ready = 1;
3336 }
3337
3338 static void
3339   vl_api_one_l2_arp_entries_get_reply_t_handler
3340   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3341 {
3342   vat_main_t *vam = &vat_main;
3343   u32 i, n;
3344   int retval = clib_net_to_host_u32 (mp->retval);
3345
3346   if (retval)
3347     goto end;
3348
3349   n = clib_net_to_host_u32 (mp->count);
3350
3351   for (i = 0; i < n; i++)
3352     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3353            format_ethernet_address, mp->entries[i].mac);
3354
3355 end:
3356   vam->retval = retval;
3357   vam->result_ready = 1;
3358 }
3359
3360 static void
3361   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3362   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3363 {
3364   u8 *s = 0;
3365   vat_main_t *vam = &vat_main;
3366   vat_json_node_t *e = 0, root;
3367   u32 i, n;
3368   int retval = clib_net_to_host_u32 (mp->retval);
3369   vl_api_one_l2_arp_entry_t *arp_entry;
3370
3371   if (retval)
3372     goto end;
3373
3374   n = clib_net_to_host_u32 (mp->count);
3375   vat_json_init_array (&root);
3376
3377   for (i = 0; i < n; i++)
3378     {
3379       e = vat_json_array_add (&root);
3380       arp_entry = &mp->entries[i];
3381
3382       vat_json_init_object (e);
3383       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3384       vec_add1 (s, 0);
3385
3386       vat_json_object_add_string_copy (e, "mac", s);
3387       vec_free (s);
3388
3389       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3390       vec_add1 (s, 0);
3391       vat_json_object_add_string_copy (e, "ip4", s);
3392       vec_free (s);
3393     }
3394
3395   vat_json_print (vam->ofp, &root);
3396   vat_json_free (&root);
3397
3398 end:
3399   vam->retval = retval;
3400   vam->result_ready = 1;
3401 }
3402
3403 static void
3404   vl_api_one_l2_arp_bd_get_reply_t_handler
3405   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3406 {
3407   vat_main_t *vam = &vat_main;
3408   u32 i, n;
3409   int retval = clib_net_to_host_u32 (mp->retval);
3410
3411   if (retval)
3412     goto end;
3413
3414   n = clib_net_to_host_u32 (mp->count);
3415
3416   for (i = 0; i < n; i++)
3417     {
3418       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3419     }
3420
3421 end:
3422   vam->retval = retval;
3423   vam->result_ready = 1;
3424 }
3425
3426 static void
3427   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3428   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3429 {
3430   vat_main_t *vam = &vat_main;
3431   vat_json_node_t root;
3432   u32 i, n;
3433   int retval = clib_net_to_host_u32 (mp->retval);
3434
3435   if (retval)
3436     goto end;
3437
3438   n = clib_net_to_host_u32 (mp->count);
3439   vat_json_init_array (&root);
3440
3441   for (i = 0; i < n; i++)
3442     {
3443       vat_json_array_add_uint (&root,
3444                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3445     }
3446
3447   vat_json_print (vam->ofp, &root);
3448   vat_json_free (&root);
3449
3450 end:
3451   vam->retval = retval;
3452   vam->result_ready = 1;
3453 }
3454
3455 static void
3456   vl_api_one_adjacencies_get_reply_t_handler
3457   (vl_api_one_adjacencies_get_reply_t * mp)
3458 {
3459   vat_main_t *vam = &vat_main;
3460   u32 i, n;
3461   int retval = clib_net_to_host_u32 (mp->retval);
3462   vl_api_one_adjacency_t *a;
3463
3464   if (retval)
3465     goto end;
3466
3467   n = clib_net_to_host_u32 (mp->count);
3468
3469   for (i = 0; i < n; i++)
3470     {
3471       a = &mp->adjacencies[i];
3472       print (vam->ofp, "%U %40U",
3473              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3474              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3475     }
3476
3477 end:
3478   vam->retval = retval;
3479   vam->result_ready = 1;
3480 }
3481
3482 static void
3483   vl_api_one_adjacencies_get_reply_t_handler_json
3484   (vl_api_one_adjacencies_get_reply_t * mp)
3485 {
3486   u8 *s = 0;
3487   vat_main_t *vam = &vat_main;
3488   vat_json_node_t *e = 0, root;
3489   u32 i, n;
3490   int retval = clib_net_to_host_u32 (mp->retval);
3491   vl_api_one_adjacency_t *a;
3492
3493   if (retval)
3494     goto end;
3495
3496   n = clib_net_to_host_u32 (mp->count);
3497   vat_json_init_array (&root);
3498
3499   for (i = 0; i < n; i++)
3500     {
3501       e = vat_json_array_add (&root);
3502       a = &mp->adjacencies[i];
3503
3504       vat_json_init_object (e);
3505       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3506                   a->leid_prefix_len);
3507       vec_add1 (s, 0);
3508       vat_json_object_add_string_copy (e, "leid", s);
3509       vec_free (s);
3510
3511       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3512                   a->reid_prefix_len);
3513       vec_add1 (s, 0);
3514       vat_json_object_add_string_copy (e, "reid", s);
3515       vec_free (s);
3516     }
3517
3518   vat_json_print (vam->ofp, &root);
3519   vat_json_free (&root);
3520
3521 end:
3522   vam->retval = retval;
3523   vam->result_ready = 1;
3524 }
3525
3526 static void
3527 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3528 {
3529   vat_main_t *vam = &vat_main;
3530
3531   print (vam->ofp, "%=20U",
3532          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3533          mp->ip_address);
3534 }
3535
3536 static void
3537   vl_api_one_map_server_details_t_handler_json
3538   (vl_api_one_map_server_details_t * mp)
3539 {
3540   vat_main_t *vam = &vat_main;
3541   vat_json_node_t *node = NULL;
3542   struct in6_addr ip6;
3543   struct in_addr ip4;
3544
3545   if (VAT_JSON_ARRAY != vam->json_tree.type)
3546     {
3547       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3548       vat_json_init_array (&vam->json_tree);
3549     }
3550   node = vat_json_array_add (&vam->json_tree);
3551
3552   vat_json_init_object (node);
3553   if (mp->is_ipv6)
3554     {
3555       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3556       vat_json_object_add_ip6 (node, "map-server", ip6);
3557     }
3558   else
3559     {
3560       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3561       vat_json_object_add_ip4 (node, "map-server", ip4);
3562     }
3563 }
3564
3565 static void
3566 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3567                                            * mp)
3568 {
3569   vat_main_t *vam = &vat_main;
3570
3571   print (vam->ofp, "%=20U",
3572          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3573          mp->ip_address);
3574 }
3575
3576 static void
3577   vl_api_one_map_resolver_details_t_handler_json
3578   (vl_api_one_map_resolver_details_t * mp)
3579 {
3580   vat_main_t *vam = &vat_main;
3581   vat_json_node_t *node = NULL;
3582   struct in6_addr ip6;
3583   struct in_addr ip4;
3584
3585   if (VAT_JSON_ARRAY != vam->json_tree.type)
3586     {
3587       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3588       vat_json_init_array (&vam->json_tree);
3589     }
3590   node = vat_json_array_add (&vam->json_tree);
3591
3592   vat_json_init_object (node);
3593   if (mp->is_ipv6)
3594     {
3595       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3596       vat_json_object_add_ip6 (node, "map resolver", ip6);
3597     }
3598   else
3599     {
3600       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3601       vat_json_object_add_ip4 (node, "map resolver", ip4);
3602     }
3603 }
3604
3605 static void
3606 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
3607 {
3608   vat_main_t *vam = &vat_main;
3609   i32 retval = ntohl (mp->retval);
3610
3611   if (0 <= retval)
3612     {
3613       print (vam->ofp, "feature: %s\ngpe: %s",
3614              mp->feature_status ? "enabled" : "disabled",
3615              mp->gpe_status ? "enabled" : "disabled");
3616     }
3617
3618   vam->retval = retval;
3619   vam->result_ready = 1;
3620 }
3621
3622 static void
3623   vl_api_show_one_status_reply_t_handler_json
3624   (vl_api_show_one_status_reply_t * mp)
3625 {
3626   vat_main_t *vam = &vat_main;
3627   vat_json_node_t node;
3628   u8 *gpe_status = NULL;
3629   u8 *feature_status = NULL;
3630
3631   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
3632   feature_status = format (0, "%s",
3633                            mp->feature_status ? "enabled" : "disabled");
3634   vec_add1 (gpe_status, 0);
3635   vec_add1 (feature_status, 0);
3636
3637   vat_json_init_object (&node);
3638   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
3639   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
3640
3641   vec_free (gpe_status);
3642   vec_free (feature_status);
3643
3644   vat_json_print (vam->ofp, &node);
3645   vat_json_free (&node);
3646
3647   vam->retval = ntohl (mp->retval);
3648   vam->result_ready = 1;
3649 }
3650
3651 static void
3652   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
3653   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3654 {
3655   vat_main_t *vam = &vat_main;
3656   i32 retval = ntohl (mp->retval);
3657
3658   if (retval >= 0)
3659     {
3660       print (vam->ofp, "%=20s", mp->locator_set_name);
3661     }
3662
3663   vam->retval = retval;
3664   vam->result_ready = 1;
3665 }
3666
3667 static void
3668   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
3669   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3670 {
3671   vat_main_t *vam = &vat_main;
3672   vat_json_node_t *node = NULL;
3673
3674   if (VAT_JSON_ARRAY != vam->json_tree.type)
3675     {
3676       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3677       vat_json_init_array (&vam->json_tree);
3678     }
3679   node = vat_json_array_add (&vam->json_tree);
3680
3681   vat_json_init_object (node);
3682   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
3683
3684   vat_json_print (vam->ofp, node);
3685   vat_json_free (node);
3686
3687   vam->retval = ntohl (mp->retval);
3688   vam->result_ready = 1;
3689 }
3690
3691 static u8 *
3692 format_lisp_map_request_mode (u8 * s, va_list * args)
3693 {
3694   u32 mode = va_arg (*args, u32);
3695
3696   switch (mode)
3697     {
3698     case 0:
3699       return format (0, "dst-only");
3700     case 1:
3701       return format (0, "src-dst");
3702     }
3703   return 0;
3704 }
3705
3706 static void
3707   vl_api_show_one_map_request_mode_reply_t_handler
3708   (vl_api_show_one_map_request_mode_reply_t * mp)
3709 {
3710   vat_main_t *vam = &vat_main;
3711   i32 retval = ntohl (mp->retval);
3712
3713   if (0 <= retval)
3714     {
3715       u32 mode = mp->mode;
3716       print (vam->ofp, "map_request_mode: %U",
3717              format_lisp_map_request_mode, mode);
3718     }
3719
3720   vam->retval = retval;
3721   vam->result_ready = 1;
3722 }
3723
3724 static void
3725   vl_api_show_one_map_request_mode_reply_t_handler_json
3726   (vl_api_show_one_map_request_mode_reply_t * mp)
3727 {
3728   vat_main_t *vam = &vat_main;
3729   vat_json_node_t node;
3730   u8 *s = 0;
3731   u32 mode;
3732
3733   mode = mp->mode;
3734   s = format (0, "%U", format_lisp_map_request_mode, mode);
3735   vec_add1 (s, 0);
3736
3737   vat_json_init_object (&node);
3738   vat_json_object_add_string_copy (&node, "map_request_mode", s);
3739   vat_json_print (vam->ofp, &node);
3740   vat_json_free (&node);
3741
3742   vec_free (s);
3743   vam->retval = ntohl (mp->retval);
3744   vam->result_ready = 1;
3745 }
3746
3747 static void
3748   vl_api_show_one_use_petr_reply_t_handler
3749   (vl_api_show_one_use_petr_reply_t * mp)
3750 {
3751   vat_main_t *vam = &vat_main;
3752   i32 retval = ntohl (mp->retval);
3753
3754   if (0 <= retval)
3755     {
3756       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
3757       if (mp->status)
3758         {
3759           print (vam->ofp, "Proxy-ETR address; %U",
3760                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
3761                  mp->address);
3762         }
3763     }
3764
3765   vam->retval = retval;
3766   vam->result_ready = 1;
3767 }
3768
3769 static void
3770   vl_api_show_one_use_petr_reply_t_handler_json
3771   (vl_api_show_one_use_petr_reply_t * mp)
3772 {
3773   vat_main_t *vam = &vat_main;
3774   vat_json_node_t node;
3775   u8 *status = 0;
3776   struct in_addr ip4;
3777   struct in6_addr ip6;
3778
3779   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3780   vec_add1 (status, 0);
3781
3782   vat_json_init_object (&node);
3783   vat_json_object_add_string_copy (&node, "status", status);
3784   if (mp->status)
3785     {
3786       if (mp->is_ip4)
3787         {
3788           clib_memcpy (&ip6, mp->address, sizeof (ip6));
3789           vat_json_object_add_ip6 (&node, "address", ip6);
3790         }
3791       else
3792         {
3793           clib_memcpy (&ip4, mp->address, sizeof (ip4));
3794           vat_json_object_add_ip4 (&node, "address", ip4);
3795         }
3796     }
3797
3798   vec_free (status);
3799
3800   vat_json_print (vam->ofp, &node);
3801   vat_json_free (&node);
3802
3803   vam->retval = ntohl (mp->retval);
3804   vam->result_ready = 1;
3805 }
3806
3807 static void
3808   vl_api_show_one_nsh_mapping_reply_t_handler
3809   (vl_api_show_one_nsh_mapping_reply_t * mp)
3810 {
3811   vat_main_t *vam = &vat_main;
3812   i32 retval = ntohl (mp->retval);
3813
3814   if (0 <= retval)
3815     {
3816       print (vam->ofp, "%-20s%-16s",
3817              mp->is_set ? "set" : "not-set",
3818              mp->is_set ? (char *) mp->locator_set_name : "");
3819     }
3820
3821   vam->retval = retval;
3822   vam->result_ready = 1;
3823 }
3824
3825 static void
3826   vl_api_show_one_nsh_mapping_reply_t_handler_json
3827   (vl_api_show_one_nsh_mapping_reply_t * mp)
3828 {
3829   vat_main_t *vam = &vat_main;
3830   vat_json_node_t node;
3831   u8 *status = 0;
3832
3833   status = format (0, "%s", mp->is_set ? "yes" : "no");
3834   vec_add1 (status, 0);
3835
3836   vat_json_init_object (&node);
3837   vat_json_object_add_string_copy (&node, "is_set", status);
3838   if (mp->is_set)
3839     {
3840       vat_json_object_add_string_copy (&node, "locator_set",
3841                                        mp->locator_set_name);
3842     }
3843
3844   vec_free (status);
3845
3846   vat_json_print (vam->ofp, &node);
3847   vat_json_free (&node);
3848
3849   vam->retval = ntohl (mp->retval);
3850   vam->result_ready = 1;
3851 }
3852
3853 static void
3854   vl_api_show_one_map_register_ttl_reply_t_handler
3855   (vl_api_show_one_map_register_ttl_reply_t * mp)
3856 {
3857   vat_main_t *vam = &vat_main;
3858   i32 retval = ntohl (mp->retval);
3859
3860   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
3861
3862   if (0 <= retval)
3863     {
3864       print (vam->ofp, "ttl: %u", mp->ttl);
3865     }
3866
3867   vam->retval = retval;
3868   vam->result_ready = 1;
3869 }
3870
3871 static void
3872   vl_api_show_one_map_register_ttl_reply_t_handler_json
3873   (vl_api_show_one_map_register_ttl_reply_t * mp)
3874 {
3875   vat_main_t *vam = &vat_main;
3876   vat_json_node_t node;
3877
3878   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
3879   vat_json_init_object (&node);
3880   vat_json_object_add_uint (&node, "ttl", mp->ttl);
3881
3882   vat_json_print (vam->ofp, &node);
3883   vat_json_free (&node);
3884
3885   vam->retval = ntohl (mp->retval);
3886   vam->result_ready = 1;
3887 }
3888
3889 static void
3890 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
3891 {
3892   vat_main_t *vam = &vat_main;
3893   i32 retval = ntohl (mp->retval);
3894
3895   if (0 <= retval)
3896     {
3897       print (vam->ofp, "%-20s%-16s",
3898              mp->status ? "enabled" : "disabled",
3899              mp->status ? (char *) mp->locator_set_name : "");
3900     }
3901
3902   vam->retval = retval;
3903   vam->result_ready = 1;
3904 }
3905
3906 static void
3907 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
3908 {
3909   vat_main_t *vam = &vat_main;
3910   vat_json_node_t node;
3911   u8 *status = 0;
3912
3913   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3914   vec_add1 (status, 0);
3915
3916   vat_json_init_object (&node);
3917   vat_json_object_add_string_copy (&node, "status", status);
3918   if (mp->status)
3919     {
3920       vat_json_object_add_string_copy (&node, "locator_set",
3921                                        mp->locator_set_name);
3922     }
3923
3924   vec_free (status);
3925
3926   vat_json_print (vam->ofp, &node);
3927   vat_json_free (&node);
3928
3929   vam->retval = ntohl (mp->retval);
3930   vam->result_ready = 1;
3931 }
3932
3933 static u8 *
3934 format_policer_type (u8 * s, va_list * va)
3935 {
3936   u32 i = va_arg (*va, u32);
3937
3938   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
3939     s = format (s, "1r2c");
3940   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
3941     s = format (s, "1r3c");
3942   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
3943     s = format (s, "2r3c-2698");
3944   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
3945     s = format (s, "2r3c-4115");
3946   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
3947     s = format (s, "2r3c-mef5cf1");
3948   else
3949     s = format (s, "ILLEGAL");
3950   return s;
3951 }
3952
3953 static u8 *
3954 format_policer_rate_type (u8 * s, va_list * va)
3955 {
3956   u32 i = va_arg (*va, u32);
3957
3958   if (i == SSE2_QOS_RATE_KBPS)
3959     s = format (s, "kbps");
3960   else if (i == SSE2_QOS_RATE_PPS)
3961     s = format (s, "pps");
3962   else
3963     s = format (s, "ILLEGAL");
3964   return s;
3965 }
3966
3967 static u8 *
3968 format_policer_round_type (u8 * s, va_list * va)
3969 {
3970   u32 i = va_arg (*va, u32);
3971
3972   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3973     s = format (s, "closest");
3974   else if (i == SSE2_QOS_ROUND_TO_UP)
3975     s = format (s, "up");
3976   else if (i == SSE2_QOS_ROUND_TO_DOWN)
3977     s = format (s, "down");
3978   else
3979     s = format (s, "ILLEGAL");
3980   return s;
3981 }
3982
3983 static u8 *
3984 format_policer_action_type (u8 * s, va_list * va)
3985 {
3986   u32 i = va_arg (*va, u32);
3987
3988   if (i == SSE2_QOS_ACTION_DROP)
3989     s = format (s, "drop");
3990   else if (i == SSE2_QOS_ACTION_TRANSMIT)
3991     s = format (s, "transmit");
3992   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3993     s = format (s, "mark-and-transmit");
3994   else
3995     s = format (s, "ILLEGAL");
3996   return s;
3997 }
3998
3999 static u8 *
4000 format_dscp (u8 * s, va_list * va)
4001 {
4002   u32 i = va_arg (*va, u32);
4003   char *t = 0;
4004
4005   switch (i)
4006     {
4007 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4008       foreach_vnet_dscp
4009 #undef _
4010     default:
4011       return format (s, "ILLEGAL");
4012     }
4013   s = format (s, "%s", t);
4014   return s;
4015 }
4016
4017 static void
4018 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4019 {
4020   vat_main_t *vam = &vat_main;
4021   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4022
4023   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4024     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4025   else
4026     conform_dscp_str = format (0, "");
4027
4028   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4029     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4030   else
4031     exceed_dscp_str = format (0, "");
4032
4033   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4034     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4035   else
4036     violate_dscp_str = format (0, "");
4037
4038   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4039          "rate type %U, round type %U, %s rate, %s color-aware, "
4040          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4041          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4042          "conform action %U%s, exceed action %U%s, violate action %U%s",
4043          mp->name,
4044          format_policer_type, mp->type,
4045          ntohl (mp->cir),
4046          ntohl (mp->eir),
4047          clib_net_to_host_u64 (mp->cb),
4048          clib_net_to_host_u64 (mp->eb),
4049          format_policer_rate_type, mp->rate_type,
4050          format_policer_round_type, mp->round_type,
4051          mp->single_rate ? "single" : "dual",
4052          mp->color_aware ? "is" : "not",
4053          ntohl (mp->cir_tokens_per_period),
4054          ntohl (mp->pir_tokens_per_period),
4055          ntohl (mp->scale),
4056          ntohl (mp->current_limit),
4057          ntohl (mp->current_bucket),
4058          ntohl (mp->extended_limit),
4059          ntohl (mp->extended_bucket),
4060          clib_net_to_host_u64 (mp->last_update_time),
4061          format_policer_action_type, mp->conform_action_type,
4062          conform_dscp_str,
4063          format_policer_action_type, mp->exceed_action_type,
4064          exceed_dscp_str,
4065          format_policer_action_type, mp->violate_action_type,
4066          violate_dscp_str);
4067
4068   vec_free (conform_dscp_str);
4069   vec_free (exceed_dscp_str);
4070   vec_free (violate_dscp_str);
4071 }
4072
4073 static void vl_api_policer_details_t_handler_json
4074   (vl_api_policer_details_t * mp)
4075 {
4076   vat_main_t *vam = &vat_main;
4077   vat_json_node_t *node;
4078   u8 *rate_type_str, *round_type_str, *type_str;
4079   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4080
4081   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4082   round_type_str =
4083     format (0, "%U", format_policer_round_type, mp->round_type);
4084   type_str = format (0, "%U", format_policer_type, mp->type);
4085   conform_action_str = format (0, "%U", format_policer_action_type,
4086                                mp->conform_action_type);
4087   exceed_action_str = format (0, "%U", format_policer_action_type,
4088                               mp->exceed_action_type);
4089   violate_action_str = format (0, "%U", format_policer_action_type,
4090                                mp->violate_action_type);
4091
4092   if (VAT_JSON_ARRAY != vam->json_tree.type)
4093     {
4094       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4095       vat_json_init_array (&vam->json_tree);
4096     }
4097   node = vat_json_array_add (&vam->json_tree);
4098
4099   vat_json_init_object (node);
4100   vat_json_object_add_string_copy (node, "name", mp->name);
4101   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4102   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4103   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4104   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4105   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4106   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4107   vat_json_object_add_string_copy (node, "type", type_str);
4108   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4109   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4110   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4111   vat_json_object_add_uint (node, "cir_tokens_per_period",
4112                             ntohl (mp->cir_tokens_per_period));
4113   vat_json_object_add_uint (node, "eir_tokens_per_period",
4114                             ntohl (mp->pir_tokens_per_period));
4115   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4116   vat_json_object_add_uint (node, "current_bucket",
4117                             ntohl (mp->current_bucket));
4118   vat_json_object_add_uint (node, "extended_limit",
4119                             ntohl (mp->extended_limit));
4120   vat_json_object_add_uint (node, "extended_bucket",
4121                             ntohl (mp->extended_bucket));
4122   vat_json_object_add_uint (node, "last_update_time",
4123                             ntohl (mp->last_update_time));
4124   vat_json_object_add_string_copy (node, "conform_action",
4125                                    conform_action_str);
4126   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4127     {
4128       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4129       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4130       vec_free (dscp_str);
4131     }
4132   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4133   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4134     {
4135       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4136       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4137       vec_free (dscp_str);
4138     }
4139   vat_json_object_add_string_copy (node, "violate_action",
4140                                    violate_action_str);
4141   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4142     {
4143       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4144       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4145       vec_free (dscp_str);
4146     }
4147
4148   vec_free (rate_type_str);
4149   vec_free (round_type_str);
4150   vec_free (type_str);
4151   vec_free (conform_action_str);
4152   vec_free (exceed_action_str);
4153   vec_free (violate_action_str);
4154 }
4155
4156 static void
4157 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4158                                            mp)
4159 {
4160   vat_main_t *vam = &vat_main;
4161   int i, count = ntohl (mp->count);
4162
4163   if (count > 0)
4164     print (vam->ofp, "classify table ids (%d) : ", count);
4165   for (i = 0; i < count; i++)
4166     {
4167       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4168       print (vam->ofp, (i < count - 1) ? "," : "");
4169     }
4170   vam->retval = ntohl (mp->retval);
4171   vam->result_ready = 1;
4172 }
4173
4174 static void
4175   vl_api_classify_table_ids_reply_t_handler_json
4176   (vl_api_classify_table_ids_reply_t * mp)
4177 {
4178   vat_main_t *vam = &vat_main;
4179   int i, count = ntohl (mp->count);
4180
4181   if (count > 0)
4182     {
4183       vat_json_node_t node;
4184
4185       vat_json_init_object (&node);
4186       for (i = 0; i < count; i++)
4187         {
4188           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4189         }
4190       vat_json_print (vam->ofp, &node);
4191       vat_json_free (&node);
4192     }
4193   vam->retval = ntohl (mp->retval);
4194   vam->result_ready = 1;
4195 }
4196
4197 static void
4198   vl_api_classify_table_by_interface_reply_t_handler
4199   (vl_api_classify_table_by_interface_reply_t * mp)
4200 {
4201   vat_main_t *vam = &vat_main;
4202   u32 table_id;
4203
4204   table_id = ntohl (mp->l2_table_id);
4205   if (table_id != ~0)
4206     print (vam->ofp, "l2 table id : %d", table_id);
4207   else
4208     print (vam->ofp, "l2 table id : No input ACL tables configured");
4209   table_id = ntohl (mp->ip4_table_id);
4210   if (table_id != ~0)
4211     print (vam->ofp, "ip4 table id : %d", table_id);
4212   else
4213     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4214   table_id = ntohl (mp->ip6_table_id);
4215   if (table_id != ~0)
4216     print (vam->ofp, "ip6 table id : %d", table_id);
4217   else
4218     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4219   vam->retval = ntohl (mp->retval);
4220   vam->result_ready = 1;
4221 }
4222
4223 static void
4224   vl_api_classify_table_by_interface_reply_t_handler_json
4225   (vl_api_classify_table_by_interface_reply_t * mp)
4226 {
4227   vat_main_t *vam = &vat_main;
4228   vat_json_node_t node;
4229
4230   vat_json_init_object (&node);
4231
4232   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4233   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4234   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4235
4236   vat_json_print (vam->ofp, &node);
4237   vat_json_free (&node);
4238
4239   vam->retval = ntohl (mp->retval);
4240   vam->result_ready = 1;
4241 }
4242
4243 static void vl_api_policer_add_del_reply_t_handler
4244   (vl_api_policer_add_del_reply_t * mp)
4245 {
4246   vat_main_t *vam = &vat_main;
4247   i32 retval = ntohl (mp->retval);
4248   if (vam->async_mode)
4249     {
4250       vam->async_errors += (retval < 0);
4251     }
4252   else
4253     {
4254       vam->retval = retval;
4255       vam->result_ready = 1;
4256       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4257         /*
4258          * Note: this is just barely thread-safe, depends on
4259          * the main thread spinning waiting for an answer...
4260          */
4261         errmsg ("policer index %d", ntohl (mp->policer_index));
4262     }
4263 }
4264
4265 static void vl_api_policer_add_del_reply_t_handler_json
4266   (vl_api_policer_add_del_reply_t * mp)
4267 {
4268   vat_main_t *vam = &vat_main;
4269   vat_json_node_t node;
4270
4271   vat_json_init_object (&node);
4272   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4273   vat_json_object_add_uint (&node, "policer_index",
4274                             ntohl (mp->policer_index));
4275
4276   vat_json_print (vam->ofp, &node);
4277   vat_json_free (&node);
4278
4279   vam->retval = ntohl (mp->retval);
4280   vam->result_ready = 1;
4281 }
4282
4283 /* Format hex dump. */
4284 u8 *
4285 format_hex_bytes (u8 * s, va_list * va)
4286 {
4287   u8 *bytes = va_arg (*va, u8 *);
4288   int n_bytes = va_arg (*va, int);
4289   uword i;
4290
4291   /* Print short or long form depending on byte count. */
4292   uword short_form = n_bytes <= 32;
4293   uword indent = format_get_indent (s);
4294
4295   if (n_bytes == 0)
4296     return s;
4297
4298   for (i = 0; i < n_bytes; i++)
4299     {
4300       if (!short_form && (i % 32) == 0)
4301         s = format (s, "%08x: ", i);
4302       s = format (s, "%02x", bytes[i]);
4303       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4304         s = format (s, "\n%U", format_white_space, indent);
4305     }
4306
4307   return s;
4308 }
4309
4310 static void
4311 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4312                                             * mp)
4313 {
4314   vat_main_t *vam = &vat_main;
4315   i32 retval = ntohl (mp->retval);
4316   if (retval == 0)
4317     {
4318       print (vam->ofp, "classify table info :");
4319       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4320              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4321              ntohl (mp->miss_next_index));
4322       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4323              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4324              ntohl (mp->match_n_vectors));
4325       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4326              ntohl (mp->mask_length));
4327     }
4328   vam->retval = retval;
4329   vam->result_ready = 1;
4330 }
4331
4332 static void
4333   vl_api_classify_table_info_reply_t_handler_json
4334   (vl_api_classify_table_info_reply_t * mp)
4335 {
4336   vat_main_t *vam = &vat_main;
4337   vat_json_node_t node;
4338
4339   i32 retval = ntohl (mp->retval);
4340   if (retval == 0)
4341     {
4342       vat_json_init_object (&node);
4343
4344       vat_json_object_add_int (&node, "sessions",
4345                                ntohl (mp->active_sessions));
4346       vat_json_object_add_int (&node, "nexttbl",
4347                                ntohl (mp->next_table_index));
4348       vat_json_object_add_int (&node, "nextnode",
4349                                ntohl (mp->miss_next_index));
4350       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4351       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4352       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4353       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4354                       ntohl (mp->mask_length), 0);
4355       vat_json_object_add_string_copy (&node, "mask", s);
4356
4357       vat_json_print (vam->ofp, &node);
4358       vat_json_free (&node);
4359     }
4360   vam->retval = ntohl (mp->retval);
4361   vam->result_ready = 1;
4362 }
4363
4364 static void
4365 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4366                                            mp)
4367 {
4368   vat_main_t *vam = &vat_main;
4369
4370   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4371          ntohl (mp->hit_next_index), ntohl (mp->advance),
4372          ntohl (mp->opaque_index));
4373   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4374          ntohl (mp->match_length));
4375 }
4376
4377 static void
4378   vl_api_classify_session_details_t_handler_json
4379   (vl_api_classify_session_details_t * mp)
4380 {
4381   vat_main_t *vam = &vat_main;
4382   vat_json_node_t *node = NULL;
4383
4384   if (VAT_JSON_ARRAY != vam->json_tree.type)
4385     {
4386       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4387       vat_json_init_array (&vam->json_tree);
4388     }
4389   node = vat_json_array_add (&vam->json_tree);
4390
4391   vat_json_init_object (node);
4392   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4393   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4394   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4395   u8 *s =
4396     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4397             0);
4398   vat_json_object_add_string_copy (node, "match", s);
4399 }
4400
4401 static void vl_api_pg_create_interface_reply_t_handler
4402   (vl_api_pg_create_interface_reply_t * mp)
4403 {
4404   vat_main_t *vam = &vat_main;
4405
4406   vam->retval = ntohl (mp->retval);
4407   vam->result_ready = 1;
4408 }
4409
4410 static void vl_api_pg_create_interface_reply_t_handler_json
4411   (vl_api_pg_create_interface_reply_t * mp)
4412 {
4413   vat_main_t *vam = &vat_main;
4414   vat_json_node_t node;
4415
4416   i32 retval = ntohl (mp->retval);
4417   if (retval == 0)
4418     {
4419       vat_json_init_object (&node);
4420
4421       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4422
4423       vat_json_print (vam->ofp, &node);
4424       vat_json_free (&node);
4425     }
4426   vam->retval = ntohl (mp->retval);
4427   vam->result_ready = 1;
4428 }
4429
4430 static void vl_api_policer_classify_details_t_handler
4431   (vl_api_policer_classify_details_t * mp)
4432 {
4433   vat_main_t *vam = &vat_main;
4434
4435   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4436          ntohl (mp->table_index));
4437 }
4438
4439 static void vl_api_policer_classify_details_t_handler_json
4440   (vl_api_policer_classify_details_t * mp)
4441 {
4442   vat_main_t *vam = &vat_main;
4443   vat_json_node_t *node;
4444
4445   if (VAT_JSON_ARRAY != vam->json_tree.type)
4446     {
4447       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4448       vat_json_init_array (&vam->json_tree);
4449     }
4450   node = vat_json_array_add (&vam->json_tree);
4451
4452   vat_json_init_object (node);
4453   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4454   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4455 }
4456
4457 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
4458   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4459 {
4460   vat_main_t *vam = &vat_main;
4461   i32 retval = ntohl (mp->retval);
4462   if (vam->async_mode)
4463     {
4464       vam->async_errors += (retval < 0);
4465     }
4466   else
4467     {
4468       vam->retval = retval;
4469       vam->sw_if_index = ntohl (mp->sw_if_index);
4470       vam->result_ready = 1;
4471     }
4472 }
4473
4474 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
4475   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4476 {
4477   vat_main_t *vam = &vat_main;
4478   vat_json_node_t node;
4479
4480   vat_json_init_object (&node);
4481   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4482   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
4483
4484   vat_json_print (vam->ofp, &node);
4485   vat_json_free (&node);
4486
4487   vam->retval = ntohl (mp->retval);
4488   vam->result_ready = 1;
4489 }
4490
4491 static void vl_api_flow_classify_details_t_handler
4492   (vl_api_flow_classify_details_t * mp)
4493 {
4494   vat_main_t *vam = &vat_main;
4495
4496   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4497          ntohl (mp->table_index));
4498 }
4499
4500 static void vl_api_flow_classify_details_t_handler_json
4501   (vl_api_flow_classify_details_t * mp)
4502 {
4503   vat_main_t *vam = &vat_main;
4504   vat_json_node_t *node;
4505
4506   if (VAT_JSON_ARRAY != vam->json_tree.type)
4507     {
4508       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4509       vat_json_init_array (&vam->json_tree);
4510     }
4511   node = vat_json_array_add (&vam->json_tree);
4512
4513   vat_json_init_object (node);
4514   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4515   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4516 }
4517
4518 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
4519 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
4520 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
4521 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
4522 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
4523 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
4524 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
4525 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
4526 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
4527 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
4528 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
4529 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
4530 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
4531 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
4532 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
4533 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
4534 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
4535 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
4536
4537 /*
4538  * Generate boilerplate reply handlers, which
4539  * dig the return value out of the xxx_reply_t API message,
4540  * stick it into vam->retval, and set vam->result_ready
4541  *
4542  * Could also do this by pointing N message decode slots at
4543  * a single function, but that could break in subtle ways.
4544  */
4545
4546 #define foreach_standard_reply_retval_handler           \
4547 _(sw_interface_set_flags_reply)                         \
4548 _(sw_interface_add_del_address_reply)                   \
4549 _(sw_interface_set_table_reply)                         \
4550 _(sw_interface_set_mpls_enable_reply)                   \
4551 _(sw_interface_set_vpath_reply)                         \
4552 _(sw_interface_set_vxlan_bypass_reply)                  \
4553 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
4554 _(sw_interface_set_l2_bridge_reply)                     \
4555 _(bridge_domain_add_del_reply)                          \
4556 _(sw_interface_set_l2_xconnect_reply)                   \
4557 _(l2fib_add_del_reply)                                  \
4558 _(l2fib_flush_int_reply)                                \
4559 _(l2fib_flush_bd_reply)                                 \
4560 _(ip_add_del_route_reply)                               \
4561 _(ip_mroute_add_del_reply)                              \
4562 _(mpls_route_add_del_reply)                             \
4563 _(mpls_ip_bind_unbind_reply)                            \
4564 _(proxy_arp_add_del_reply)                              \
4565 _(proxy_arp_intfc_enable_disable_reply)                 \
4566 _(sw_interface_set_unnumbered_reply)                    \
4567 _(ip_neighbor_add_del_reply)                            \
4568 _(reset_vrf_reply)                                      \
4569 _(oam_add_del_reply)                                    \
4570 _(reset_fib_reply)                                      \
4571 _(dhcp_proxy_config_reply)                              \
4572 _(dhcp_proxy_set_vss_reply)                             \
4573 _(dhcp_client_config_reply)                             \
4574 _(set_ip_flow_hash_reply)                               \
4575 _(sw_interface_ip6_enable_disable_reply)                \
4576 _(sw_interface_ip6_set_link_local_address_reply)        \
4577 _(ip6nd_proxy_add_del_reply)                            \
4578 _(sw_interface_ip6nd_ra_prefix_reply)                   \
4579 _(sw_interface_ip6nd_ra_config_reply)                   \
4580 _(set_arp_neighbor_limit_reply)                         \
4581 _(l2_patch_add_del_reply)                               \
4582 _(sr_policy_add_reply)                                  \
4583 _(sr_policy_mod_reply)                                  \
4584 _(sr_policy_del_reply)                                  \
4585 _(sr_localsid_add_del_reply)                            \
4586 _(sr_steering_add_del_reply)                            \
4587 _(classify_add_del_session_reply)                       \
4588 _(classify_set_interface_ip_table_reply)                \
4589 _(classify_set_interface_l2_tables_reply)               \
4590 _(l2tpv3_set_tunnel_cookies_reply)                      \
4591 _(l2tpv3_interface_enable_disable_reply)                \
4592 _(l2tpv3_set_lookup_key_reply)                          \
4593 _(l2_fib_clear_table_reply)                             \
4594 _(l2_interface_efp_filter_reply)                        \
4595 _(l2_interface_vlan_tag_rewrite_reply)                  \
4596 _(modify_vhost_user_if_reply)                           \
4597 _(delete_vhost_user_if_reply)                           \
4598 _(want_ip4_arp_events_reply)                            \
4599 _(want_ip6_nd_events_reply)                             \
4600 _(input_acl_set_interface_reply)                        \
4601 _(ipsec_spd_add_del_reply)                              \
4602 _(ipsec_interface_add_del_spd_reply)                    \
4603 _(ipsec_spd_add_del_entry_reply)                        \
4604 _(ipsec_sad_add_del_entry_reply)                        \
4605 _(ipsec_sa_set_key_reply)                               \
4606 _(ipsec_tunnel_if_add_del_reply)                        \
4607 _(ikev2_profile_add_del_reply)                          \
4608 _(ikev2_profile_set_auth_reply)                         \
4609 _(ikev2_profile_set_id_reply)                           \
4610 _(ikev2_profile_set_ts_reply)                           \
4611 _(ikev2_set_local_key_reply)                            \
4612 _(ikev2_set_responder_reply)                            \
4613 _(ikev2_set_ike_transforms_reply)                       \
4614 _(ikev2_set_esp_transforms_reply)                       \
4615 _(ikev2_set_sa_lifetime_reply)                          \
4616 _(ikev2_initiate_sa_init_reply)                         \
4617 _(ikev2_initiate_del_ike_sa_reply)                      \
4618 _(ikev2_initiate_del_child_sa_reply)                    \
4619 _(ikev2_initiate_rekey_child_sa_reply)                  \
4620 _(delete_loopback_reply)                                \
4621 _(bd_ip_mac_add_del_reply)                              \
4622 _(map_del_domain_reply)                                 \
4623 _(map_add_del_rule_reply)                               \
4624 _(want_interface_events_reply)                          \
4625 _(want_stats_reply)                                     \
4626 _(cop_interface_enable_disable_reply)                   \
4627 _(cop_whitelist_enable_disable_reply)                   \
4628 _(sw_interface_clear_stats_reply)                       \
4629 _(ioam_enable_reply)                              \
4630 _(ioam_disable_reply)                              \
4631 _(one_add_del_locator_reply)                            \
4632 _(one_add_del_local_eid_reply)                          \
4633 _(one_add_del_remote_mapping_reply)                     \
4634 _(one_add_del_adjacency_reply)                          \
4635 _(one_add_del_map_resolver_reply)                       \
4636 _(one_add_del_map_server_reply)                         \
4637 _(one_enable_disable_reply)                             \
4638 _(one_rloc_probe_enable_disable_reply)                  \
4639 _(one_map_register_enable_disable_reply)                \
4640 _(one_map_register_set_ttl_reply)                       \
4641 _(one_pitr_set_locator_set_reply)                       \
4642 _(one_map_request_mode_reply)                           \
4643 _(one_add_del_map_request_itr_rlocs_reply)              \
4644 _(one_eid_table_add_del_map_reply)                      \
4645 _(one_use_petr_reply)                                   \
4646 _(one_stats_enable_disable_reply)                       \
4647 _(one_add_del_l2_arp_entry_reply)                       \
4648 _(one_stats_flush_reply)                                \
4649 _(gpe_enable_disable_reply)                             \
4650 _(gpe_set_encap_mode_reply)                             \
4651 _(gpe_add_del_iface_reply)                              \
4652 _(gpe_add_del_native_fwd_rpath_reply)                   \
4653 _(af_packet_delete_reply)                               \
4654 _(policer_classify_set_interface_reply)                 \
4655 _(netmap_create_reply)                                  \
4656 _(netmap_delete_reply)                                  \
4657 _(set_ipfix_exporter_reply)                             \
4658 _(set_ipfix_classify_stream_reply)                      \
4659 _(ipfix_classify_table_add_del_reply)                   \
4660 _(flow_classify_set_interface_reply)                    \
4661 _(sw_interface_span_enable_disable_reply)               \
4662 _(pg_capture_reply)                                     \
4663 _(pg_enable_disable_reply)                              \
4664 _(ip_source_and_port_range_check_add_del_reply)         \
4665 _(ip_source_and_port_range_check_interface_add_del_reply)\
4666 _(delete_subif_reply)                                   \
4667 _(l2_interface_pbb_tag_rewrite_reply)                   \
4668 _(punt_reply)                                           \
4669 _(feature_enable_disable_reply)                         \
4670 _(sw_interface_tag_add_del_reply)                       \
4671 _(sw_interface_set_mtu_reply)                           \
4672 _(p2p_ethernet_add_reply)                               \
4673 _(p2p_ethernet_del_reply)                               \
4674 _(lldp_config_reply)                                    \
4675 _(sw_interface_set_lldp_reply)
4676
4677 #define _(n)                                    \
4678     static void vl_api_##n##_t_handler          \
4679     (vl_api_##n##_t * mp)                       \
4680     {                                           \
4681         vat_main_t * vam = &vat_main;           \
4682         i32 retval = ntohl(mp->retval);         \
4683         if (vam->async_mode) {                  \
4684             vam->async_errors += (retval < 0);  \
4685         } else {                                \
4686             vam->retval = retval;               \
4687             vam->result_ready = 1;              \
4688         }                                       \
4689     }
4690 foreach_standard_reply_retval_handler;
4691 #undef _
4692
4693 #define _(n)                                    \
4694     static void vl_api_##n##_t_handler_json     \
4695     (vl_api_##n##_t * mp)                       \
4696     {                                           \
4697         vat_main_t * vam = &vat_main;           \
4698         vat_json_node_t node;                   \
4699         vat_json_init_object(&node);            \
4700         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
4701         vat_json_print(vam->ofp, &node);        \
4702         vam->retval = ntohl(mp->retval);        \
4703         vam->result_ready = 1;                  \
4704     }
4705 foreach_standard_reply_retval_handler;
4706 #undef _
4707
4708 /*
4709  * Table of message reply handlers, must include boilerplate handlers
4710  * we just generated
4711  */
4712
4713 #define foreach_vpe_api_reply_msg                                       \
4714 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
4715 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
4716 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
4717 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
4718 _(CONTROL_PING_REPLY, control_ping_reply)                               \
4719 _(CLI_REPLY, cli_reply)                                                 \
4720 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
4721 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
4722   sw_interface_add_del_address_reply)                                   \
4723 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
4724 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
4725 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
4726 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
4727 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
4728 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
4729   sw_interface_set_l2_xconnect_reply)                                   \
4730 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
4731   sw_interface_set_l2_bridge_reply)                                     \
4732 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
4733 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
4734 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
4735 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
4736 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
4737 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
4738 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
4739 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
4740 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
4741 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
4742 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
4743 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
4744 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
4745 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
4746 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
4747 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
4748 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
4749 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
4750   proxy_arp_intfc_enable_disable_reply)                                 \
4751 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
4752 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
4753   sw_interface_set_unnumbered_reply)                                    \
4754 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
4755 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
4756 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
4757 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
4758 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
4759 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
4760 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
4761 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
4762 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
4763 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
4764 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
4765 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
4766   sw_interface_ip6_enable_disable_reply)                                \
4767 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
4768   sw_interface_ip6_set_link_local_address_reply)                        \
4769 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
4770 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
4771 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
4772   sw_interface_ip6nd_ra_prefix_reply)                                   \
4773 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
4774   sw_interface_ip6nd_ra_config_reply)                                   \
4775 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
4776 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
4777 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
4778 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
4779 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
4780 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
4781 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
4782 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
4783 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
4784 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
4785 classify_set_interface_ip_table_reply)                                  \
4786 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
4787   classify_set_interface_l2_tables_reply)                               \
4788 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
4789 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
4790 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
4791 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
4792 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
4793   l2tpv3_interface_enable_disable_reply)                                \
4794 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
4795 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
4796 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
4797 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
4798 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
4799 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
4800 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
4801 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
4802 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4803 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
4804 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
4805 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
4806 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
4807 _(SHOW_VERSION_REPLY, show_version_reply)                               \
4808 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
4809 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
4810 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
4811 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
4812 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
4813 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
4814 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
4815 _(IP6_ND_EVENT, ip6_nd_event)                                           \
4816 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
4817 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
4818 _(IP_DETAILS, ip_details)                                               \
4819 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
4820 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4821 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
4822 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
4823 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
4824 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
4825 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
4826 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
4827 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
4828 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
4829 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
4830 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
4831 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
4832 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
4833 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
4834 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
4835 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
4836 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
4837 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
4838 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
4839 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
4840 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
4841 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
4842 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
4843 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
4844 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
4845 _(MAP_RULE_DETAILS, map_rule_details)                                   \
4846 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
4847 _(WANT_STATS_REPLY, want_stats_reply)                                   \
4848 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
4849 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4850 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4851 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
4852 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
4853 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
4854 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
4855 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
4856 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
4857 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
4858 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
4859 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
4860 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
4861 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
4862 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
4863 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
4864   one_map_register_enable_disable_reply)                                \
4865 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
4866 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
4867   one_rloc_probe_enable_disable_reply)                                  \
4868 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
4869 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
4870 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
4871 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
4872 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
4873 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
4874 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
4875 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
4876 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
4877 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
4878 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
4879 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
4880 _(ONE_STATS_DETAILS, one_stats_details)                                 \
4881 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
4882 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
4883 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
4884   show_one_stats_enable_disable_reply)                                  \
4885 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
4886 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
4887 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
4888 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
4889 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
4890 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
4891 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
4892 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
4893 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
4894 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
4895 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
4896 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
4897   gpe_add_del_native_fwd_rpath_reply)                                   \
4898 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
4899   gpe_fwd_entry_path_details)                                           \
4900 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
4901 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
4902   one_add_del_map_request_itr_rlocs_reply)                              \
4903 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
4904   one_get_map_request_itr_rlocs_reply)                                  \
4905 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
4906 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
4907 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
4908 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
4909 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
4910 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
4911   show_one_map_register_state_reply)                                    \
4912 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
4913 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
4914 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
4915 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
4916 _(POLICER_DETAILS, policer_details)                                     \
4917 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4918 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
4919 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
4920 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
4921 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
4922 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
4923 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
4924 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4925 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
4926 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
4927 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
4928 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
4929 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
4930 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
4931 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4932 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
4933 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4934 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
4935 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
4936 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
4937 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
4938 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
4939 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
4940 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
4941 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
4942  ip_source_and_port_range_check_add_del_reply)                          \
4943 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
4944  ip_source_and_port_range_check_interface_add_del_reply)                \
4945 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
4946 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
4947 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
4948 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
4949 _(PUNT_REPLY, punt_reply)                                               \
4950 _(IP_FIB_DETAILS, ip_fib_details)                                       \
4951 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
4952 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
4953 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
4954 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
4955 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
4956 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
4957 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
4958 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
4959 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
4960 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
4961 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)
4962
4963 #define foreach_standalone_reply_msg                                    \
4964 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
4965 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
4966 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
4967 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
4968 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
4969 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
4970 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
4971
4972 typedef struct
4973 {
4974   u8 *name;
4975   u32 value;
4976 } name_sort_t;
4977
4978
4979 #define STR_VTR_OP_CASE(op)     \
4980     case L2_VTR_ ## op:         \
4981         return "" # op;
4982
4983 static const char *
4984 str_vtr_op (u32 vtr_op)
4985 {
4986   switch (vtr_op)
4987     {
4988       STR_VTR_OP_CASE (DISABLED);
4989       STR_VTR_OP_CASE (PUSH_1);
4990       STR_VTR_OP_CASE (PUSH_2);
4991       STR_VTR_OP_CASE (POP_1);
4992       STR_VTR_OP_CASE (POP_2);
4993       STR_VTR_OP_CASE (TRANSLATE_1_1);
4994       STR_VTR_OP_CASE (TRANSLATE_1_2);
4995       STR_VTR_OP_CASE (TRANSLATE_2_1);
4996       STR_VTR_OP_CASE (TRANSLATE_2_2);
4997     }
4998
4999   return "UNKNOWN";
5000 }
5001
5002 static int
5003 dump_sub_interface_table (vat_main_t * vam)
5004 {
5005   const sw_interface_subif_t *sub = NULL;
5006
5007   if (vam->json_output)
5008     {
5009       clib_warning
5010         ("JSON output supported only for VPE API calls and dump_stats_table");
5011       return -99;
5012     }
5013
5014   print (vam->ofp,
5015          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5016          "Interface", "sw_if_index",
5017          "sub id", "dot1ad", "tags", "outer id",
5018          "inner id", "exact", "default", "outer any", "inner any");
5019
5020   vec_foreach (sub, vam->sw_if_subif_table)
5021   {
5022     print (vam->ofp,
5023            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5024            sub->interface_name,
5025            sub->sw_if_index,
5026            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5027            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5028            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5029            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5030     if (sub->vtr_op != L2_VTR_DISABLED)
5031       {
5032         print (vam->ofp,
5033                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5034                "tag1: %d tag2: %d ]",
5035                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5036                sub->vtr_tag1, sub->vtr_tag2);
5037       }
5038   }
5039
5040   return 0;
5041 }
5042
5043 static int
5044 name_sort_cmp (void *a1, void *a2)
5045 {
5046   name_sort_t *n1 = a1;
5047   name_sort_t *n2 = a2;
5048
5049   return strcmp ((char *) n1->name, (char *) n2->name);
5050 }
5051
5052 static int
5053 dump_interface_table (vat_main_t * vam)
5054 {
5055   hash_pair_t *p;
5056   name_sort_t *nses = 0, *ns;
5057
5058   if (vam->json_output)
5059     {
5060       clib_warning
5061         ("JSON output supported only for VPE API calls and dump_stats_table");
5062       return -99;
5063     }
5064
5065   /* *INDENT-OFF* */
5066   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5067   ({
5068     vec_add2 (nses, ns, 1);
5069     ns->name = (u8 *)(p->key);
5070     ns->value = (u32) p->value[0];
5071   }));
5072   /* *INDENT-ON* */
5073
5074   vec_sort_with_function (nses, name_sort_cmp);
5075
5076   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5077   vec_foreach (ns, nses)
5078   {
5079     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5080   }
5081   vec_free (nses);
5082   return 0;
5083 }
5084
5085 static int
5086 dump_ip_table (vat_main_t * vam, int is_ipv6)
5087 {
5088   const ip_details_t *det = NULL;
5089   const ip_address_details_t *address = NULL;
5090   u32 i = ~0;
5091
5092   print (vam->ofp, "%-12s", "sw_if_index");
5093
5094   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5095   {
5096     i++;
5097     if (!det->present)
5098       {
5099         continue;
5100       }
5101     print (vam->ofp, "%-12d", i);
5102     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5103     if (!det->addr)
5104       {
5105         continue;
5106       }
5107     vec_foreach (address, det->addr)
5108     {
5109       print (vam->ofp,
5110              "            %-30U%-13d",
5111              is_ipv6 ? format_ip6_address : format_ip4_address,
5112              address->ip, address->prefix_length);
5113     }
5114   }
5115
5116   return 0;
5117 }
5118
5119 static int
5120 dump_ipv4_table (vat_main_t * vam)
5121 {
5122   if (vam->json_output)
5123     {
5124       clib_warning
5125         ("JSON output supported only for VPE API calls and dump_stats_table");
5126       return -99;
5127     }
5128
5129   return dump_ip_table (vam, 0);
5130 }
5131
5132 static int
5133 dump_ipv6_table (vat_main_t * vam)
5134 {
5135   if (vam->json_output)
5136     {
5137       clib_warning
5138         ("JSON output supported only for VPE API calls and dump_stats_table");
5139       return -99;
5140     }
5141
5142   return dump_ip_table (vam, 1);
5143 }
5144
5145 static char *
5146 counter_type_to_str (u8 counter_type, u8 is_combined)
5147 {
5148   if (!is_combined)
5149     {
5150       switch (counter_type)
5151         {
5152         case VNET_INTERFACE_COUNTER_DROP:
5153           return "drop";
5154         case VNET_INTERFACE_COUNTER_PUNT:
5155           return "punt";
5156         case VNET_INTERFACE_COUNTER_IP4:
5157           return "ip4";
5158         case VNET_INTERFACE_COUNTER_IP6:
5159           return "ip6";
5160         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
5161           return "rx-no-buf";
5162         case VNET_INTERFACE_COUNTER_RX_MISS:
5163           return "rx-miss";
5164         case VNET_INTERFACE_COUNTER_RX_ERROR:
5165           return "rx-error";
5166         case VNET_INTERFACE_COUNTER_TX_ERROR:
5167           return "tx-error";
5168         default:
5169           return "INVALID-COUNTER-TYPE";
5170         }
5171     }
5172   else
5173     {
5174       switch (counter_type)
5175         {
5176         case VNET_INTERFACE_COUNTER_RX:
5177           return "rx";
5178         case VNET_INTERFACE_COUNTER_TX:
5179           return "tx";
5180         default:
5181           return "INVALID-COUNTER-TYPE";
5182         }
5183     }
5184 }
5185
5186 static int
5187 dump_stats_table (vat_main_t * vam)
5188 {
5189   vat_json_node_t node;
5190   vat_json_node_t *msg_array;
5191   vat_json_node_t *msg;
5192   vat_json_node_t *counter_array;
5193   vat_json_node_t *counter;
5194   interface_counter_t c;
5195   u64 packets;
5196   ip4_fib_counter_t *c4;
5197   ip6_fib_counter_t *c6;
5198   ip4_nbr_counter_t *n4;
5199   ip6_nbr_counter_t *n6;
5200   int i, j;
5201
5202   if (!vam->json_output)
5203     {
5204       clib_warning ("dump_stats_table supported only in JSON format");
5205       return -99;
5206     }
5207
5208   vat_json_init_object (&node);
5209
5210   /* interface counters */
5211   msg_array = vat_json_object_add (&node, "interface_counters");
5212   vat_json_init_array (msg_array);
5213   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
5214     {
5215       msg = vat_json_array_add (msg_array);
5216       vat_json_init_object (msg);
5217       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5218                                        (u8 *) counter_type_to_str (i, 0));
5219       vat_json_object_add_int (msg, "is_combined", 0);
5220       counter_array = vat_json_object_add (msg, "data");
5221       vat_json_init_array (counter_array);
5222       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
5223         {
5224           packets = vam->simple_interface_counters[i][j];
5225           vat_json_array_add_uint (counter_array, packets);
5226         }
5227     }
5228   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
5229     {
5230       msg = vat_json_array_add (msg_array);
5231       vat_json_init_object (msg);
5232       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5233                                        (u8 *) counter_type_to_str (i, 1));
5234       vat_json_object_add_int (msg, "is_combined", 1);
5235       counter_array = vat_json_object_add (msg, "data");
5236       vat_json_init_array (counter_array);
5237       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
5238         {
5239           c = vam->combined_interface_counters[i][j];
5240           counter = vat_json_array_add (counter_array);
5241           vat_json_init_object (counter);
5242           vat_json_object_add_uint (counter, "packets", c.packets);
5243           vat_json_object_add_uint (counter, "bytes", c.bytes);
5244         }
5245     }
5246
5247   /* ip4 fib counters */
5248   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
5249   vat_json_init_array (msg_array);
5250   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
5251     {
5252       msg = vat_json_array_add (msg_array);
5253       vat_json_init_object (msg);
5254       vat_json_object_add_uint (msg, "vrf_id",
5255                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
5256       counter_array = vat_json_object_add (msg, "c");
5257       vat_json_init_array (counter_array);
5258       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
5259         {
5260           counter = vat_json_array_add (counter_array);
5261           vat_json_init_object (counter);
5262           c4 = &vam->ip4_fib_counters[i][j];
5263           vat_json_object_add_ip4 (counter, "address", c4->address);
5264           vat_json_object_add_uint (counter, "address_length",
5265                                     c4->address_length);
5266           vat_json_object_add_uint (counter, "packets", c4->packets);
5267           vat_json_object_add_uint (counter, "bytes", c4->bytes);
5268         }
5269     }
5270
5271   /* ip6 fib counters */
5272   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
5273   vat_json_init_array (msg_array);
5274   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
5275     {
5276       msg = vat_json_array_add (msg_array);
5277       vat_json_init_object (msg);
5278       vat_json_object_add_uint (msg, "vrf_id",
5279                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
5280       counter_array = vat_json_object_add (msg, "c");
5281       vat_json_init_array (counter_array);
5282       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
5283         {
5284           counter = vat_json_array_add (counter_array);
5285           vat_json_init_object (counter);
5286           c6 = &vam->ip6_fib_counters[i][j];
5287           vat_json_object_add_ip6 (counter, "address", c6->address);
5288           vat_json_object_add_uint (counter, "address_length",
5289                                     c6->address_length);
5290           vat_json_object_add_uint (counter, "packets", c6->packets);
5291           vat_json_object_add_uint (counter, "bytes", c6->bytes);
5292         }
5293     }
5294
5295   /* ip4 nbr counters */
5296   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
5297   vat_json_init_array (msg_array);
5298   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
5299     {
5300       msg = vat_json_array_add (msg_array);
5301       vat_json_init_object (msg);
5302       vat_json_object_add_uint (msg, "sw_if_index", i);
5303       counter_array = vat_json_object_add (msg, "c");
5304       vat_json_init_array (counter_array);
5305       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
5306         {
5307           counter = vat_json_array_add (counter_array);
5308           vat_json_init_object (counter);
5309           n4 = &vam->ip4_nbr_counters[i][j];
5310           vat_json_object_add_ip4 (counter, "address", n4->address);
5311           vat_json_object_add_uint (counter, "link-type", n4->linkt);
5312           vat_json_object_add_uint (counter, "packets", n4->packets);
5313           vat_json_object_add_uint (counter, "bytes", n4->bytes);
5314         }
5315     }
5316
5317   /* ip6 nbr counters */
5318   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
5319   vat_json_init_array (msg_array);
5320   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
5321     {
5322       msg = vat_json_array_add (msg_array);
5323       vat_json_init_object (msg);
5324       vat_json_object_add_uint (msg, "sw_if_index", i);
5325       counter_array = vat_json_object_add (msg, "c");
5326       vat_json_init_array (counter_array);
5327       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
5328         {
5329           counter = vat_json_array_add (counter_array);
5330           vat_json_init_object (counter);
5331           n6 = &vam->ip6_nbr_counters[i][j];
5332           vat_json_object_add_ip6 (counter, "address", n6->address);
5333           vat_json_object_add_uint (counter, "packets", n6->packets);
5334           vat_json_object_add_uint (counter, "bytes", n6->bytes);
5335         }
5336     }
5337
5338   vat_json_print (vam->ofp, &node);
5339   vat_json_free (&node);
5340
5341   return 0;
5342 }
5343
5344 int
5345 exec (vat_main_t * vam)
5346 {
5347   api_main_t *am = &api_main;
5348   vl_api_cli_t *mp;
5349   f64 timeout;
5350   void *oldheap;
5351   u8 *cmd = 0;
5352   unformat_input_t *i = vam->input;
5353
5354   if (vec_len (i->buffer) == 0)
5355     return -1;
5356
5357   if (vam->exec_mode == 0 && unformat (i, "mode"))
5358     {
5359       vam->exec_mode = 1;
5360       return 0;
5361     }
5362   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5363     {
5364       vam->exec_mode = 0;
5365       return 0;
5366     }
5367
5368
5369   M (CLI, mp);
5370
5371   /*
5372    * Copy cmd into shared memory.
5373    * In order for the CLI command to work, it
5374    * must be a vector ending in \n, not a C-string ending
5375    * in \n\0.
5376    */
5377   pthread_mutex_lock (&am->vlib_rp->mutex);
5378   oldheap = svm_push_data_heap (am->vlib_rp);
5379
5380   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
5381   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
5382
5383   svm_pop_heap (oldheap);
5384   pthread_mutex_unlock (&am->vlib_rp->mutex);
5385
5386   mp->cmd_in_shmem = pointer_to_uword (cmd);
5387   S (mp);
5388   timeout = vat_time_now (vam) + 10.0;
5389
5390   while (vat_time_now (vam) < timeout)
5391     {
5392       if (vam->result_ready == 1)
5393         {
5394           u8 *free_me;
5395           if (vam->shmem_result != NULL)
5396             print (vam->ofp, "%s", vam->shmem_result);
5397           pthread_mutex_lock (&am->vlib_rp->mutex);
5398           oldheap = svm_push_data_heap (am->vlib_rp);
5399
5400           free_me = (u8 *) vam->shmem_result;
5401           vec_free (free_me);
5402
5403           svm_pop_heap (oldheap);
5404           pthread_mutex_unlock (&am->vlib_rp->mutex);
5405           return 0;
5406         }
5407     }
5408   return -99;
5409 }
5410
5411 /*
5412  * Future replacement of exec() that passes CLI buffers directly in
5413  * the API messages instead of an additional shared memory area.
5414  */
5415 static int
5416 exec_inband (vat_main_t * vam)
5417 {
5418   vl_api_cli_inband_t *mp;
5419   unformat_input_t *i = vam->input;
5420   int ret;
5421
5422   if (vec_len (i->buffer) == 0)
5423     return -1;
5424
5425   if (vam->exec_mode == 0 && unformat (i, "mode"))
5426     {
5427       vam->exec_mode = 1;
5428       return 0;
5429     }
5430   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5431     {
5432       vam->exec_mode = 0;
5433       return 0;
5434     }
5435
5436   /*
5437    * In order for the CLI command to work, it
5438    * must be a vector ending in \n, not a C-string ending
5439    * in \n\0.
5440    */
5441   u32 len = vec_len (vam->input->buffer);
5442   M2 (CLI_INBAND, mp, len);
5443   clib_memcpy (mp->cmd, vam->input->buffer, len);
5444   mp->length = htonl (len);
5445
5446   S (mp);
5447   W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
5448   return ret;
5449 }
5450
5451 static int
5452 api_create_loopback (vat_main_t * vam)
5453 {
5454   unformat_input_t *i = vam->input;
5455   vl_api_create_loopback_t *mp;
5456   vl_api_create_loopback_instance_t *mp_lbi;
5457   u8 mac_address[6];
5458   u8 mac_set = 0;
5459   u8 is_specified = 0;
5460   u32 user_instance = 0;
5461   int ret;
5462
5463   memset (mac_address, 0, sizeof (mac_address));
5464
5465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5466     {
5467       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5468         mac_set = 1;
5469       if (unformat (i, "instance %d", &user_instance))
5470         is_specified = 1;
5471       else
5472         break;
5473     }
5474
5475   if (is_specified)
5476     {
5477       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5478       mp_lbi->is_specified = is_specified;
5479       if (is_specified)
5480         mp_lbi->user_instance = htonl (user_instance);
5481       if (mac_set)
5482         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5483       S (mp_lbi);
5484     }
5485   else
5486     {
5487       /* Construct the API message */
5488       M (CREATE_LOOPBACK, mp);
5489       if (mac_set)
5490         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5491       S (mp);
5492     }
5493
5494   W (ret);
5495   return ret;
5496 }
5497
5498 static int
5499 api_delete_loopback (vat_main_t * vam)
5500 {
5501   unformat_input_t *i = vam->input;
5502   vl_api_delete_loopback_t *mp;
5503   u32 sw_if_index = ~0;
5504   int ret;
5505
5506   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5507     {
5508       if (unformat (i, "sw_if_index %d", &sw_if_index))
5509         ;
5510       else
5511         break;
5512     }
5513
5514   if (sw_if_index == ~0)
5515     {
5516       errmsg ("missing sw_if_index");
5517       return -99;
5518     }
5519
5520   /* Construct the API message */
5521   M (DELETE_LOOPBACK, mp);
5522   mp->sw_if_index = ntohl (sw_if_index);
5523
5524   S (mp);
5525   W (ret);
5526   return ret;
5527 }
5528
5529 static int
5530 api_want_stats (vat_main_t * vam)
5531 {
5532   unformat_input_t *i = vam->input;
5533   vl_api_want_stats_t *mp;
5534   int enable = -1;
5535   int ret;
5536
5537   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5538     {
5539       if (unformat (i, "enable"))
5540         enable = 1;
5541       else if (unformat (i, "disable"))
5542         enable = 0;
5543       else
5544         break;
5545     }
5546
5547   if (enable == -1)
5548     {
5549       errmsg ("missing enable|disable");
5550       return -99;
5551     }
5552
5553   M (WANT_STATS, mp);
5554   mp->enable_disable = enable;
5555
5556   S (mp);
5557   W (ret);
5558   return ret;
5559 }
5560
5561 static int
5562 api_want_interface_events (vat_main_t * vam)
5563 {
5564   unformat_input_t *i = vam->input;
5565   vl_api_want_interface_events_t *mp;
5566   int enable = -1;
5567   int ret;
5568
5569   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5570     {
5571       if (unformat (i, "enable"))
5572         enable = 1;
5573       else if (unformat (i, "disable"))
5574         enable = 0;
5575       else
5576         break;
5577     }
5578
5579   if (enable == -1)
5580     {
5581       errmsg ("missing enable|disable");
5582       return -99;
5583     }
5584
5585   M (WANT_INTERFACE_EVENTS, mp);
5586   mp->enable_disable = enable;
5587
5588   vam->interface_event_display = enable;
5589
5590   S (mp);
5591   W (ret);
5592   return ret;
5593 }
5594
5595
5596 /* Note: non-static, called once to set up the initial intfc table */
5597 int
5598 api_sw_interface_dump (vat_main_t * vam)
5599 {
5600   vl_api_sw_interface_dump_t *mp;
5601   vl_api_control_ping_t *mp_ping;
5602   hash_pair_t *p;
5603   name_sort_t *nses = 0, *ns;
5604   sw_interface_subif_t *sub = NULL;
5605   int ret;
5606
5607   /* Toss the old name table */
5608   /* *INDENT-OFF* */
5609   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5610   ({
5611     vec_add2 (nses, ns, 1);
5612     ns->name = (u8 *)(p->key);
5613     ns->value = (u32) p->value[0];
5614   }));
5615   /* *INDENT-ON* */
5616
5617   hash_free (vam->sw_if_index_by_interface_name);
5618
5619   vec_foreach (ns, nses) vec_free (ns->name);
5620
5621   vec_free (nses);
5622
5623   vec_foreach (sub, vam->sw_if_subif_table)
5624   {
5625     vec_free (sub->interface_name);
5626   }
5627   vec_free (vam->sw_if_subif_table);
5628
5629   /* recreate the interface name hash table */
5630   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5631
5632   /* Get list of ethernets */
5633   M (SW_INTERFACE_DUMP, mp);
5634   mp->name_filter_valid = 1;
5635   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
5636   S (mp);
5637
5638   /* and local / loopback interfaces */
5639   M (SW_INTERFACE_DUMP, mp);
5640   mp->name_filter_valid = 1;
5641   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
5642   S (mp);
5643
5644   /* and packet-generator interfaces */
5645   M (SW_INTERFACE_DUMP, mp);
5646   mp->name_filter_valid = 1;
5647   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
5648   S (mp);
5649
5650   /* and vxlan-gpe tunnel interfaces */
5651   M (SW_INTERFACE_DUMP, mp);
5652   mp->name_filter_valid = 1;
5653   strncpy ((char *) mp->name_filter, "vxlan_gpe",
5654            sizeof (mp->name_filter) - 1);
5655   S (mp);
5656
5657   /* and vxlan tunnel interfaces */
5658   M (SW_INTERFACE_DUMP, mp);
5659   mp->name_filter_valid = 1;
5660   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
5661   S (mp);
5662
5663   /* and host (af_packet) interfaces */
5664   M (SW_INTERFACE_DUMP, mp);
5665   mp->name_filter_valid = 1;
5666   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
5667   S (mp);
5668
5669   /* and l2tpv3 tunnel interfaces */
5670   M (SW_INTERFACE_DUMP, mp);
5671   mp->name_filter_valid = 1;
5672   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
5673            sizeof (mp->name_filter) - 1);
5674   S (mp);
5675
5676   /* and GRE tunnel interfaces */
5677   M (SW_INTERFACE_DUMP, mp);
5678   mp->name_filter_valid = 1;
5679   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
5680   S (mp);
5681
5682   /* and LISP-GPE interfaces */
5683   M (SW_INTERFACE_DUMP, mp);
5684   mp->name_filter_valid = 1;
5685   strncpy ((char *) mp->name_filter, "lisp_gpe",
5686            sizeof (mp->name_filter) - 1);
5687   S (mp);
5688
5689   /* and IPSEC tunnel interfaces */
5690   M (SW_INTERFACE_DUMP, mp);
5691   mp->name_filter_valid = 1;
5692   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
5693   S (mp);
5694
5695   /* Use a control ping for synchronization */
5696   M (CONTROL_PING, mp_ping);
5697   S (mp_ping);
5698
5699   W (ret);
5700   return ret;
5701 }
5702
5703 static int
5704 api_sw_interface_set_flags (vat_main_t * vam)
5705 {
5706   unformat_input_t *i = vam->input;
5707   vl_api_sw_interface_set_flags_t *mp;
5708   u32 sw_if_index;
5709   u8 sw_if_index_set = 0;
5710   u8 admin_up = 0, link_up = 0;
5711   int ret;
5712
5713   /* Parse args required to build the message */
5714   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5715     {
5716       if (unformat (i, "admin-up"))
5717         admin_up = 1;
5718       else if (unformat (i, "admin-down"))
5719         admin_up = 0;
5720       else if (unformat (i, "link-up"))
5721         link_up = 1;
5722       else if (unformat (i, "link-down"))
5723         link_up = 0;
5724       else
5725         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5726         sw_if_index_set = 1;
5727       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5728         sw_if_index_set = 1;
5729       else
5730         break;
5731     }
5732
5733   if (sw_if_index_set == 0)
5734     {
5735       errmsg ("missing interface name or sw_if_index");
5736       return -99;
5737     }
5738
5739   /* Construct the API message */
5740   M (SW_INTERFACE_SET_FLAGS, mp);
5741   mp->sw_if_index = ntohl (sw_if_index);
5742   mp->admin_up_down = admin_up;
5743   mp->link_up_down = link_up;
5744
5745   /* send it... */
5746   S (mp);
5747
5748   /* Wait for a reply, return the good/bad news... */
5749   W (ret);
5750   return ret;
5751 }
5752
5753 static int
5754 api_sw_interface_clear_stats (vat_main_t * vam)
5755 {
5756   unformat_input_t *i = vam->input;
5757   vl_api_sw_interface_clear_stats_t *mp;
5758   u32 sw_if_index;
5759   u8 sw_if_index_set = 0;
5760   int ret;
5761
5762   /* Parse args required to build the message */
5763   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5764     {
5765       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5766         sw_if_index_set = 1;
5767       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5768         sw_if_index_set = 1;
5769       else
5770         break;
5771     }
5772
5773   /* Construct the API message */
5774   M (SW_INTERFACE_CLEAR_STATS, mp);
5775
5776   if (sw_if_index_set == 1)
5777     mp->sw_if_index = ntohl (sw_if_index);
5778   else
5779     mp->sw_if_index = ~0;
5780
5781   /* send it... */
5782   S (mp);
5783
5784   /* Wait for a reply, return the good/bad news... */
5785   W (ret);
5786   return ret;
5787 }
5788
5789 static int
5790 api_sw_interface_add_del_address (vat_main_t * vam)
5791 {
5792   unformat_input_t *i = vam->input;
5793   vl_api_sw_interface_add_del_address_t *mp;
5794   u32 sw_if_index;
5795   u8 sw_if_index_set = 0;
5796   u8 is_add = 1, del_all = 0;
5797   u32 address_length = 0;
5798   u8 v4_address_set = 0;
5799   u8 v6_address_set = 0;
5800   ip4_address_t v4address;
5801   ip6_address_t v6address;
5802   int ret;
5803
5804   /* Parse args required to build the message */
5805   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5806     {
5807       if (unformat (i, "del-all"))
5808         del_all = 1;
5809       else if (unformat (i, "del"))
5810         is_add = 0;
5811       else
5812         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5813         sw_if_index_set = 1;
5814       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5815         sw_if_index_set = 1;
5816       else if (unformat (i, "%U/%d",
5817                          unformat_ip4_address, &v4address, &address_length))
5818         v4_address_set = 1;
5819       else if (unformat (i, "%U/%d",
5820                          unformat_ip6_address, &v6address, &address_length))
5821         v6_address_set = 1;
5822       else
5823         break;
5824     }
5825
5826   if (sw_if_index_set == 0)
5827     {
5828       errmsg ("missing interface name or sw_if_index");
5829       return -99;
5830     }
5831   if (v4_address_set && v6_address_set)
5832     {
5833       errmsg ("both v4 and v6 addresses set");
5834       return -99;
5835     }
5836   if (!v4_address_set && !v6_address_set && !del_all)
5837     {
5838       errmsg ("no addresses set");
5839       return -99;
5840     }
5841
5842   /* Construct the API message */
5843   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
5844
5845   mp->sw_if_index = ntohl (sw_if_index);
5846   mp->is_add = is_add;
5847   mp->del_all = del_all;
5848   if (v6_address_set)
5849     {
5850       mp->is_ipv6 = 1;
5851       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5852     }
5853   else
5854     {
5855       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5856     }
5857   mp->address_length = address_length;
5858
5859   /* send it... */
5860   S (mp);
5861
5862   /* Wait for a reply, return good/bad news  */
5863   W (ret);
5864   return ret;
5865 }
5866
5867 static int
5868 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5869 {
5870   unformat_input_t *i = vam->input;
5871   vl_api_sw_interface_set_mpls_enable_t *mp;
5872   u32 sw_if_index;
5873   u8 sw_if_index_set = 0;
5874   u8 enable = 1;
5875   int ret;
5876
5877   /* Parse args required to build the message */
5878   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5879     {
5880       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5881         sw_if_index_set = 1;
5882       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5883         sw_if_index_set = 1;
5884       else if (unformat (i, "disable"))
5885         enable = 0;
5886       else if (unformat (i, "dis"))
5887         enable = 0;
5888       else
5889         break;
5890     }
5891
5892   if (sw_if_index_set == 0)
5893     {
5894       errmsg ("missing interface name or sw_if_index");
5895       return -99;
5896     }
5897
5898   /* Construct the API message */
5899   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
5900
5901   mp->sw_if_index = ntohl (sw_if_index);
5902   mp->enable = enable;
5903
5904   /* send it... */
5905   S (mp);
5906
5907   /* Wait for a reply... */
5908   W (ret);
5909   return ret;
5910 }
5911
5912 static int
5913 api_sw_interface_set_table (vat_main_t * vam)
5914 {
5915   unformat_input_t *i = vam->input;
5916   vl_api_sw_interface_set_table_t *mp;
5917   u32 sw_if_index, vrf_id = 0;
5918   u8 sw_if_index_set = 0;
5919   u8 is_ipv6 = 0;
5920   int ret;
5921
5922   /* Parse args required to build the message */
5923   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5924     {
5925       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5926         sw_if_index_set = 1;
5927       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5928         sw_if_index_set = 1;
5929       else if (unformat (i, "vrf %d", &vrf_id))
5930         ;
5931       else if (unformat (i, "ipv6"))
5932         is_ipv6 = 1;
5933       else
5934         break;
5935     }
5936
5937   if (sw_if_index_set == 0)
5938     {
5939       errmsg ("missing interface name or sw_if_index");
5940       return -99;
5941     }
5942
5943   /* Construct the API message */
5944   M (SW_INTERFACE_SET_TABLE, mp);
5945
5946   mp->sw_if_index = ntohl (sw_if_index);
5947   mp->is_ipv6 = is_ipv6;
5948   mp->vrf_id = ntohl (vrf_id);
5949
5950   /* send it... */
5951   S (mp);
5952
5953   /* Wait for a reply... */
5954   W (ret);
5955   return ret;
5956 }
5957
5958 static void vl_api_sw_interface_get_table_reply_t_handler
5959   (vl_api_sw_interface_get_table_reply_t * mp)
5960 {
5961   vat_main_t *vam = &vat_main;
5962
5963   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5964
5965   vam->retval = ntohl (mp->retval);
5966   vam->result_ready = 1;
5967
5968 }
5969
5970 static void vl_api_sw_interface_get_table_reply_t_handler_json
5971   (vl_api_sw_interface_get_table_reply_t * mp)
5972 {
5973   vat_main_t *vam = &vat_main;
5974   vat_json_node_t node;
5975
5976   vat_json_init_object (&node);
5977   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5978   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5979
5980   vat_json_print (vam->ofp, &node);
5981   vat_json_free (&node);
5982
5983   vam->retval = ntohl (mp->retval);
5984   vam->result_ready = 1;
5985 }
5986
5987 static int
5988 api_sw_interface_get_table (vat_main_t * vam)
5989 {
5990   unformat_input_t *i = vam->input;
5991   vl_api_sw_interface_get_table_t *mp;
5992   u32 sw_if_index;
5993   u8 sw_if_index_set = 0;
5994   u8 is_ipv6 = 0;
5995   int ret;
5996
5997   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5998     {
5999       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6000         sw_if_index_set = 1;
6001       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6002         sw_if_index_set = 1;
6003       else if (unformat (i, "ipv6"))
6004         is_ipv6 = 1;
6005       else
6006         break;
6007     }
6008
6009   if (sw_if_index_set == 0)
6010     {
6011       errmsg ("missing interface name or sw_if_index");
6012       return -99;
6013     }
6014
6015   M (SW_INTERFACE_GET_TABLE, mp);
6016   mp->sw_if_index = htonl (sw_if_index);
6017   mp->is_ipv6 = is_ipv6;
6018
6019   S (mp);
6020   W (ret);
6021   return ret;
6022 }
6023
6024 static int
6025 api_sw_interface_set_vpath (vat_main_t * vam)
6026 {
6027   unformat_input_t *i = vam->input;
6028   vl_api_sw_interface_set_vpath_t *mp;
6029   u32 sw_if_index = 0;
6030   u8 sw_if_index_set = 0;
6031   u8 is_enable = 0;
6032   int ret;
6033
6034   /* Parse args required to build the message */
6035   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6036     {
6037       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6038         sw_if_index_set = 1;
6039       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6040         sw_if_index_set = 1;
6041       else if (unformat (i, "enable"))
6042         is_enable = 1;
6043       else if (unformat (i, "disable"))
6044         is_enable = 0;
6045       else
6046         break;
6047     }
6048
6049   if (sw_if_index_set == 0)
6050     {
6051       errmsg ("missing interface name or sw_if_index");
6052       return -99;
6053     }
6054
6055   /* Construct the API message */
6056   M (SW_INTERFACE_SET_VPATH, mp);
6057
6058   mp->sw_if_index = ntohl (sw_if_index);
6059   mp->enable = is_enable;
6060
6061   /* send it... */
6062   S (mp);
6063
6064   /* Wait for a reply... */
6065   W (ret);
6066   return ret;
6067 }
6068
6069 static int
6070 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6071 {
6072   unformat_input_t *i = vam->input;
6073   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6074   u32 sw_if_index = 0;
6075   u8 sw_if_index_set = 0;
6076   u8 is_enable = 1;
6077   u8 is_ipv6 = 0;
6078   int ret;
6079
6080   /* Parse args required to build the message */
6081   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6082     {
6083       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6084         sw_if_index_set = 1;
6085       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6086         sw_if_index_set = 1;
6087       else if (unformat (i, "enable"))
6088         is_enable = 1;
6089       else if (unformat (i, "disable"))
6090         is_enable = 0;
6091       else if (unformat (i, "ip4"))
6092         is_ipv6 = 0;
6093       else if (unformat (i, "ip6"))
6094         is_ipv6 = 1;
6095       else
6096         break;
6097     }
6098
6099   if (sw_if_index_set == 0)
6100     {
6101       errmsg ("missing interface name or sw_if_index");
6102       return -99;
6103     }
6104
6105   /* Construct the API message */
6106   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6107
6108   mp->sw_if_index = ntohl (sw_if_index);
6109   mp->enable = is_enable;
6110   mp->is_ipv6 = is_ipv6;
6111
6112   /* send it... */
6113   S (mp);
6114
6115   /* Wait for a reply... */
6116   W (ret);
6117   return ret;
6118 }
6119
6120
6121 static int
6122 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6123 {
6124   unformat_input_t *i = vam->input;
6125   vl_api_sw_interface_set_l2_xconnect_t *mp;
6126   u32 rx_sw_if_index;
6127   u8 rx_sw_if_index_set = 0;
6128   u32 tx_sw_if_index;
6129   u8 tx_sw_if_index_set = 0;
6130   u8 enable = 1;
6131   int ret;
6132
6133   /* Parse args required to build the message */
6134   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6135     {
6136       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6137         rx_sw_if_index_set = 1;
6138       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6139         tx_sw_if_index_set = 1;
6140       else if (unformat (i, "rx"))
6141         {
6142           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6143             {
6144               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6145                             &rx_sw_if_index))
6146                 rx_sw_if_index_set = 1;
6147             }
6148           else
6149             break;
6150         }
6151       else if (unformat (i, "tx"))
6152         {
6153           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6154             {
6155               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6156                             &tx_sw_if_index))
6157                 tx_sw_if_index_set = 1;
6158             }
6159           else
6160             break;
6161         }
6162       else if (unformat (i, "enable"))
6163         enable = 1;
6164       else if (unformat (i, "disable"))
6165         enable = 0;
6166       else
6167         break;
6168     }
6169
6170   if (rx_sw_if_index_set == 0)
6171     {
6172       errmsg ("missing rx interface name or rx_sw_if_index");
6173       return -99;
6174     }
6175
6176   if (enable && (tx_sw_if_index_set == 0))
6177     {
6178       errmsg ("missing tx interface name or tx_sw_if_index");
6179       return -99;
6180     }
6181
6182   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6183
6184   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6185   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6186   mp->enable = enable;
6187
6188   S (mp);
6189   W (ret);
6190   return ret;
6191 }
6192
6193 static int
6194 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6195 {
6196   unformat_input_t *i = vam->input;
6197   vl_api_sw_interface_set_l2_bridge_t *mp;
6198   u32 rx_sw_if_index;
6199   u8 rx_sw_if_index_set = 0;
6200   u32 bd_id;
6201   u8 bd_id_set = 0;
6202   u8 bvi = 0;
6203   u32 shg = 0;
6204   u8 enable = 1;
6205   int ret;
6206
6207   /* Parse args required to build the message */
6208   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6209     {
6210       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6211         rx_sw_if_index_set = 1;
6212       else if (unformat (i, "bd_id %d", &bd_id))
6213         bd_id_set = 1;
6214       else
6215         if (unformat
6216             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6217         rx_sw_if_index_set = 1;
6218       else if (unformat (i, "shg %d", &shg))
6219         ;
6220       else if (unformat (i, "bvi"))
6221         bvi = 1;
6222       else if (unformat (i, "enable"))
6223         enable = 1;
6224       else if (unformat (i, "disable"))
6225         enable = 0;
6226       else
6227         break;
6228     }
6229
6230   if (rx_sw_if_index_set == 0)
6231     {
6232       errmsg ("missing rx interface name or sw_if_index");
6233       return -99;
6234     }
6235
6236   if (enable && (bd_id_set == 0))
6237     {
6238       errmsg ("missing bridge domain");
6239       return -99;
6240     }
6241
6242   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6243
6244   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6245   mp->bd_id = ntohl (bd_id);
6246   mp->shg = (u8) shg;
6247   mp->bvi = bvi;
6248   mp->enable = enable;
6249
6250   S (mp);
6251   W (ret);
6252   return ret;
6253 }
6254
6255 static int
6256 api_bridge_domain_dump (vat_main_t * vam)
6257 {
6258   unformat_input_t *i = vam->input;
6259   vl_api_bridge_domain_dump_t *mp;
6260   vl_api_control_ping_t *mp_ping;
6261   u32 bd_id = ~0;
6262   int ret;
6263
6264   /* Parse args required to build the message */
6265   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6266     {
6267       if (unformat (i, "bd_id %d", &bd_id))
6268         ;
6269       else
6270         break;
6271     }
6272
6273   M (BRIDGE_DOMAIN_DUMP, mp);
6274   mp->bd_id = ntohl (bd_id);
6275   S (mp);
6276
6277   /* Use a control ping for synchronization */
6278   M (CONTROL_PING, mp_ping);
6279   S (mp_ping);
6280
6281   W (ret);
6282   return ret;
6283 }
6284
6285 static int
6286 api_bridge_domain_add_del (vat_main_t * vam)
6287 {
6288   unformat_input_t *i = vam->input;
6289   vl_api_bridge_domain_add_del_t *mp;
6290   u32 bd_id = ~0;
6291   u8 is_add = 1;
6292   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6293   u32 mac_age = 0;
6294   int ret;
6295
6296   /* Parse args required to build the message */
6297   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6298     {
6299       if (unformat (i, "bd_id %d", &bd_id))
6300         ;
6301       else if (unformat (i, "flood %d", &flood))
6302         ;
6303       else if (unformat (i, "uu-flood %d", &uu_flood))
6304         ;
6305       else if (unformat (i, "forward %d", &forward))
6306         ;
6307       else if (unformat (i, "learn %d", &learn))
6308         ;
6309       else if (unformat (i, "arp-term %d", &arp_term))
6310         ;
6311       else if (unformat (i, "mac-age %d", &mac_age))
6312         ;
6313       else if (unformat (i, "del"))
6314         {
6315           is_add = 0;
6316           flood = uu_flood = forward = learn = 0;
6317         }
6318       else
6319         break;
6320     }
6321
6322   if (bd_id == ~0)
6323     {
6324       errmsg ("missing bridge domain");
6325       return -99;
6326     }
6327
6328   if (mac_age > 255)
6329     {
6330       errmsg ("mac age must be less than 256 ");
6331       return -99;
6332     }
6333
6334   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6335
6336   mp->bd_id = ntohl (bd_id);
6337   mp->flood = flood;
6338   mp->uu_flood = uu_flood;
6339   mp->forward = forward;
6340   mp->learn = learn;
6341   mp->arp_term = arp_term;
6342   mp->is_add = is_add;
6343   mp->mac_age = (u8) mac_age;
6344
6345   S (mp);
6346   W (ret);
6347   return ret;
6348 }
6349
6350 static int
6351 api_l2fib_flush_bd (vat_main_t * vam)
6352 {
6353   unformat_input_t *i = vam->input;
6354   vl_api_l2fib_flush_bd_t *mp;
6355   u32 bd_id = ~0;
6356   int ret;
6357
6358   /* Parse args required to build the message */
6359   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6360     {
6361       if (unformat (i, "bd_id %d", &bd_id));
6362       else
6363         break;
6364     }
6365
6366   if (bd_id == ~0)
6367     {
6368       errmsg ("missing bridge domain");
6369       return -99;
6370     }
6371
6372   M (L2FIB_FLUSH_BD, mp);
6373
6374   mp->bd_id = htonl (bd_id);
6375
6376   S (mp);
6377   W (ret);
6378   return ret;
6379 }
6380
6381 static int
6382 api_l2fib_flush_int (vat_main_t * vam)
6383 {
6384   unformat_input_t *i = vam->input;
6385   vl_api_l2fib_flush_int_t *mp;
6386   u32 sw_if_index = ~0;
6387   int ret;
6388
6389   /* Parse args required to build the message */
6390   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6391     {
6392       if (unformat (i, "sw_if_index %d", &sw_if_index));
6393       else
6394         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6395       else
6396         break;
6397     }
6398
6399   if (sw_if_index == ~0)
6400     {
6401       errmsg ("missing interface name or sw_if_index");
6402       return -99;
6403     }
6404
6405   M (L2FIB_FLUSH_INT, mp);
6406
6407   mp->sw_if_index = ntohl (sw_if_index);
6408
6409   S (mp);
6410   W (ret);
6411   return ret;
6412 }
6413
6414 static int
6415 api_l2fib_add_del (vat_main_t * vam)
6416 {
6417   unformat_input_t *i = vam->input;
6418   vl_api_l2fib_add_del_t *mp;
6419   f64 timeout;
6420   u64 mac = 0;
6421   u8 mac_set = 0;
6422   u32 bd_id;
6423   u8 bd_id_set = 0;
6424   u32 sw_if_index = ~0;
6425   u8 sw_if_index_set = 0;
6426   u8 is_add = 1;
6427   u8 static_mac = 0;
6428   u8 filter_mac = 0;
6429   u8 bvi_mac = 0;
6430   int count = 1;
6431   f64 before = 0;
6432   int j;
6433
6434   /* Parse args required to build the message */
6435   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6436     {
6437       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
6438         mac_set = 1;
6439       else if (unformat (i, "bd_id %d", &bd_id))
6440         bd_id_set = 1;
6441       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6442         sw_if_index_set = 1;
6443       else if (unformat (i, "sw_if"))
6444         {
6445           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6446             {
6447               if (unformat
6448                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6449                 sw_if_index_set = 1;
6450             }
6451           else
6452             break;
6453         }
6454       else if (unformat (i, "static"))
6455         static_mac = 1;
6456       else if (unformat (i, "filter"))
6457         {
6458           filter_mac = 1;
6459           static_mac = 1;
6460         }
6461       else if (unformat (i, "bvi"))
6462         {
6463           bvi_mac = 1;
6464           static_mac = 1;
6465         }
6466       else if (unformat (i, "del"))
6467         is_add = 0;
6468       else if (unformat (i, "count %d", &count))
6469         ;
6470       else
6471         break;
6472     }
6473
6474   if (mac_set == 0)
6475     {
6476       errmsg ("missing mac address");
6477       return -99;
6478     }
6479
6480   if (bd_id_set == 0)
6481     {
6482       errmsg ("missing bridge domain");
6483       return -99;
6484     }
6485
6486   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6487     {
6488       errmsg ("missing interface name or sw_if_index");
6489       return -99;
6490     }
6491
6492   if (count > 1)
6493     {
6494       /* Turn on async mode */
6495       vam->async_mode = 1;
6496       vam->async_errors = 0;
6497       before = vat_time_now (vam);
6498     }
6499
6500   for (j = 0; j < count; j++)
6501     {
6502       M (L2FIB_ADD_DEL, mp);
6503
6504       mp->mac = mac;
6505       mp->bd_id = ntohl (bd_id);
6506       mp->is_add = is_add;
6507
6508       if (is_add)
6509         {
6510           mp->sw_if_index = ntohl (sw_if_index);
6511           mp->static_mac = static_mac;
6512           mp->filter_mac = filter_mac;
6513           mp->bvi_mac = bvi_mac;
6514         }
6515       increment_mac_address (&mac);
6516       /* send it... */
6517       S (mp);
6518     }
6519
6520   if (count > 1)
6521     {
6522       vl_api_control_ping_t *mp_ping;
6523       f64 after;
6524
6525       /* Shut off async mode */
6526       vam->async_mode = 0;
6527
6528       M (CONTROL_PING, mp_ping);
6529       S (mp_ping);
6530
6531       timeout = vat_time_now (vam) + 1.0;
6532       while (vat_time_now (vam) < timeout)
6533         if (vam->result_ready == 1)
6534           goto out;
6535       vam->retval = -99;
6536
6537     out:
6538       if (vam->retval == -99)
6539         errmsg ("timeout");
6540
6541       if (vam->async_errors > 0)
6542         {
6543           errmsg ("%d asynchronous errors", vam->async_errors);
6544           vam->retval = -98;
6545         }
6546       vam->async_errors = 0;
6547       after = vat_time_now (vam);
6548
6549       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6550              count, after - before, count / (after - before));
6551     }
6552   else
6553     {
6554       int ret;
6555
6556       /* Wait for a reply... */
6557       W (ret);
6558       return ret;
6559     }
6560   /* Return the good/bad news */
6561   return (vam->retval);
6562 }
6563
6564 static int
6565 api_bridge_domain_set_mac_age (vat_main_t * vam)
6566 {
6567   unformat_input_t *i = vam->input;
6568   vl_api_bridge_domain_set_mac_age_t *mp;
6569   u32 bd_id = ~0;
6570   u32 mac_age = 0;
6571   int ret;
6572
6573   /* Parse args required to build the message */
6574   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6575     {
6576       if (unformat (i, "bd_id %d", &bd_id));
6577       else if (unformat (i, "mac-age %d", &mac_age));
6578       else
6579         break;
6580     }
6581
6582   if (bd_id == ~0)
6583     {
6584       errmsg ("missing bridge domain");
6585       return -99;
6586     }
6587
6588   if (mac_age > 255)
6589     {
6590       errmsg ("mac age must be less than 256 ");
6591       return -99;
6592     }
6593
6594   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6595
6596   mp->bd_id = htonl (bd_id);
6597   mp->mac_age = (u8) mac_age;
6598
6599   S (mp);
6600   W (ret);
6601   return ret;
6602 }
6603
6604 static int
6605 api_l2_flags (vat_main_t * vam)
6606 {
6607   unformat_input_t *i = vam->input;
6608   vl_api_l2_flags_t *mp;
6609   u32 sw_if_index;
6610   u32 feature_bitmap = 0;
6611   u8 sw_if_index_set = 0;
6612   int ret;
6613
6614   /* Parse args required to build the message */
6615   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6616     {
6617       if (unformat (i, "sw_if_index %d", &sw_if_index))
6618         sw_if_index_set = 1;
6619       else if (unformat (i, "sw_if"))
6620         {
6621           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6622             {
6623               if (unformat
6624                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6625                 sw_if_index_set = 1;
6626             }
6627           else
6628             break;
6629         }
6630       else if (unformat (i, "learn"))
6631         feature_bitmap |= L2INPUT_FEAT_LEARN;
6632       else if (unformat (i, "forward"))
6633         feature_bitmap |= L2INPUT_FEAT_FWD;
6634       else if (unformat (i, "flood"))
6635         feature_bitmap |= L2INPUT_FEAT_FLOOD;
6636       else if (unformat (i, "uu-flood"))
6637         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
6638       else
6639         break;
6640     }
6641
6642   if (sw_if_index_set == 0)
6643     {
6644       errmsg ("missing interface name or sw_if_index");
6645       return -99;
6646     }
6647
6648   M (L2_FLAGS, mp);
6649
6650   mp->sw_if_index = ntohl (sw_if_index);
6651   mp->feature_bitmap = ntohl (feature_bitmap);
6652
6653   S (mp);
6654   W (ret);
6655   return ret;
6656 }
6657
6658 static int
6659 api_bridge_flags (vat_main_t * vam)
6660 {
6661   unformat_input_t *i = vam->input;
6662   vl_api_bridge_flags_t *mp;
6663   u32 bd_id;
6664   u8 bd_id_set = 0;
6665   u8 is_set = 1;
6666   u32 flags = 0;
6667   int ret;
6668
6669   /* Parse args required to build the message */
6670   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6671     {
6672       if (unformat (i, "bd_id %d", &bd_id))
6673         bd_id_set = 1;
6674       else if (unformat (i, "learn"))
6675         flags |= L2_LEARN;
6676       else if (unformat (i, "forward"))
6677         flags |= L2_FWD;
6678       else if (unformat (i, "flood"))
6679         flags |= L2_FLOOD;
6680       else if (unformat (i, "uu-flood"))
6681         flags |= L2_UU_FLOOD;
6682       else if (unformat (i, "arp-term"))
6683         flags |= L2_ARP_TERM;
6684       else if (unformat (i, "off"))
6685         is_set = 0;
6686       else if (unformat (i, "disable"))
6687         is_set = 0;
6688       else
6689         break;
6690     }
6691
6692   if (bd_id_set == 0)
6693     {
6694       errmsg ("missing bridge domain");
6695       return -99;
6696     }
6697
6698   M (BRIDGE_FLAGS, mp);
6699
6700   mp->bd_id = ntohl (bd_id);
6701   mp->feature_bitmap = ntohl (flags);
6702   mp->is_set = is_set;
6703
6704   S (mp);
6705   W (ret);
6706   return ret;
6707 }
6708
6709 static int
6710 api_bd_ip_mac_add_del (vat_main_t * vam)
6711 {
6712   unformat_input_t *i = vam->input;
6713   vl_api_bd_ip_mac_add_del_t *mp;
6714   u32 bd_id;
6715   u8 is_ipv6 = 0;
6716   u8 is_add = 1;
6717   u8 bd_id_set = 0;
6718   u8 ip_set = 0;
6719   u8 mac_set = 0;
6720   ip4_address_t v4addr;
6721   ip6_address_t v6addr;
6722   u8 macaddr[6];
6723   int ret;
6724
6725
6726   /* Parse args required to build the message */
6727   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6728     {
6729       if (unformat (i, "bd_id %d", &bd_id))
6730         {
6731           bd_id_set++;
6732         }
6733       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
6734         {
6735           ip_set++;
6736         }
6737       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
6738         {
6739           ip_set++;
6740           is_ipv6++;
6741         }
6742       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
6743         {
6744           mac_set++;
6745         }
6746       else if (unformat (i, "del"))
6747         is_add = 0;
6748       else
6749         break;
6750     }
6751
6752   if (bd_id_set == 0)
6753     {
6754       errmsg ("missing bridge domain");
6755       return -99;
6756     }
6757   else if (ip_set == 0)
6758     {
6759       errmsg ("missing IP address");
6760       return -99;
6761     }
6762   else if (mac_set == 0)
6763     {
6764       errmsg ("missing MAC address");
6765       return -99;
6766     }
6767
6768   M (BD_IP_MAC_ADD_DEL, mp);
6769
6770   mp->bd_id = ntohl (bd_id);
6771   mp->is_ipv6 = is_ipv6;
6772   mp->is_add = is_add;
6773   if (is_ipv6)
6774     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
6775   else
6776     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
6777   clib_memcpy (mp->mac_address, macaddr, 6);
6778   S (mp);
6779   W (ret);
6780   return ret;
6781 }
6782
6783 static int
6784 api_tap_connect (vat_main_t * vam)
6785 {
6786   unformat_input_t *i = vam->input;
6787   vl_api_tap_connect_t *mp;
6788   u8 mac_address[6];
6789   u8 random_mac = 1;
6790   u8 name_set = 0;
6791   u8 *tap_name;
6792   u8 *tag = 0;
6793   ip4_address_t ip4_address;
6794   u32 ip4_mask_width;
6795   int ip4_address_set = 0;
6796   ip6_address_t ip6_address;
6797   u32 ip6_mask_width;
6798   int ip6_address_set = 0;
6799   int ret;
6800
6801   memset (mac_address, 0, sizeof (mac_address));
6802
6803   /* Parse args required to build the message */
6804   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6805     {
6806       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6807         {
6808           random_mac = 0;
6809         }
6810       else if (unformat (i, "random-mac"))
6811         random_mac = 1;
6812       else if (unformat (i, "tapname %s", &tap_name))
6813         name_set = 1;
6814       else if (unformat (i, "tag %s", &tag))
6815         ;
6816       else if (unformat (i, "address %U/%d",
6817                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
6818         ip4_address_set = 1;
6819       else if (unformat (i, "address %U/%d",
6820                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
6821         ip6_address_set = 1;
6822       else
6823         break;
6824     }
6825
6826   if (name_set == 0)
6827     {
6828       errmsg ("missing tap name");
6829       return -99;
6830     }
6831   if (vec_len (tap_name) > 63)
6832     {
6833       errmsg ("tap name too long");
6834       return -99;
6835     }
6836   vec_add1 (tap_name, 0);
6837
6838   if (vec_len (tag) > 63)
6839     {
6840       errmsg ("tag too long");
6841       return -99;
6842     }
6843
6844   /* Construct the API message */
6845   M (TAP_CONNECT, mp);
6846
6847   mp->use_random_mac = random_mac;
6848   clib_memcpy (mp->mac_address, mac_address, 6);
6849   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6850   if (tag)
6851     clib_memcpy (mp->tag, tag, vec_len (tag));
6852
6853   if (ip4_address_set)
6854     {
6855       mp->ip4_address_set = 1;
6856       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6857       mp->ip4_mask_width = ip4_mask_width;
6858     }
6859   if (ip6_address_set)
6860     {
6861       mp->ip6_address_set = 1;
6862       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6863       mp->ip6_mask_width = ip6_mask_width;
6864     }
6865
6866   vec_free (tap_name);
6867   vec_free (tag);
6868
6869   /* send it... */
6870   S (mp);
6871
6872   /* Wait for a reply... */
6873   W (ret);
6874   return ret;
6875 }
6876
6877 static int
6878 api_tap_modify (vat_main_t * vam)
6879 {
6880   unformat_input_t *i = vam->input;
6881   vl_api_tap_modify_t *mp;
6882   u8 mac_address[6];
6883   u8 random_mac = 1;
6884   u8 name_set = 0;
6885   u8 *tap_name;
6886   u32 sw_if_index = ~0;
6887   u8 sw_if_index_set = 0;
6888   int ret;
6889
6890   memset (mac_address, 0, sizeof (mac_address));
6891
6892   /* Parse args required to build the message */
6893   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6894     {
6895       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6896         sw_if_index_set = 1;
6897       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6898         sw_if_index_set = 1;
6899       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6900         {
6901           random_mac = 0;
6902         }
6903       else if (unformat (i, "random-mac"))
6904         random_mac = 1;
6905       else if (unformat (i, "tapname %s", &tap_name))
6906         name_set = 1;
6907       else
6908         break;
6909     }
6910
6911   if (sw_if_index_set == 0)
6912     {
6913       errmsg ("missing vpp interface name");
6914       return -99;
6915     }
6916   if (name_set == 0)
6917     {
6918       errmsg ("missing tap name");
6919       return -99;
6920     }
6921   if (vec_len (tap_name) > 63)
6922     {
6923       errmsg ("tap name too long");
6924     }
6925   vec_add1 (tap_name, 0);
6926
6927   /* Construct the API message */
6928   M (TAP_MODIFY, mp);
6929
6930   mp->use_random_mac = random_mac;
6931   mp->sw_if_index = ntohl (sw_if_index);
6932   clib_memcpy (mp->mac_address, mac_address, 6);
6933   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6934   vec_free (tap_name);
6935
6936   /* send it... */
6937   S (mp);
6938
6939   /* Wait for a reply... */
6940   W (ret);
6941   return ret;
6942 }
6943
6944 static int
6945 api_tap_delete (vat_main_t * vam)
6946 {
6947   unformat_input_t *i = vam->input;
6948   vl_api_tap_delete_t *mp;
6949   u32 sw_if_index = ~0;
6950   u8 sw_if_index_set = 0;
6951   int ret;
6952
6953   /* Parse args required to build the message */
6954   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6955     {
6956       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6957         sw_if_index_set = 1;
6958       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6959         sw_if_index_set = 1;
6960       else
6961         break;
6962     }
6963
6964   if (sw_if_index_set == 0)
6965     {
6966       errmsg ("missing vpp interface name");
6967       return -99;
6968     }
6969
6970   /* Construct the API message */
6971   M (TAP_DELETE, mp);
6972
6973   mp->sw_if_index = ntohl (sw_if_index);
6974
6975   /* send it... */
6976   S (mp);
6977
6978   /* Wait for a reply... */
6979   W (ret);
6980   return ret;
6981 }
6982
6983 static int
6984 api_ip_add_del_route (vat_main_t * vam)
6985 {
6986   unformat_input_t *i = vam->input;
6987   vl_api_ip_add_del_route_t *mp;
6988   u32 sw_if_index = ~0, vrf_id = 0;
6989   u8 is_ipv6 = 0;
6990   u8 is_local = 0, is_drop = 0;
6991   u8 is_unreach = 0, is_prohibit = 0;
6992   u8 create_vrf_if_needed = 0;
6993   u8 is_add = 1;
6994   u32 next_hop_weight = 1;
6995   u8 not_last = 0;
6996   u8 is_multipath = 0;
6997   u8 address_set = 0;
6998   u8 address_length_set = 0;
6999   u32 next_hop_table_id = 0;
7000   u32 resolve_attempts = 0;
7001   u32 dst_address_length = 0;
7002   u8 next_hop_set = 0;
7003   ip4_address_t v4_dst_address, v4_next_hop_address;
7004   ip6_address_t v6_dst_address, v6_next_hop_address;
7005   int count = 1;
7006   int j;
7007   f64 before = 0;
7008   u32 random_add_del = 0;
7009   u32 *random_vector = 0;
7010   uword *random_hash;
7011   u32 random_seed = 0xdeaddabe;
7012   u32 classify_table_index = ~0;
7013   u8 is_classify = 0;
7014   u8 resolve_host = 0, resolve_attached = 0;
7015   mpls_label_t *next_hop_out_label_stack = NULL;
7016   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7017   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7018
7019   /* Parse args required to build the message */
7020   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7021     {
7022       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7023         ;
7024       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7025         ;
7026       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
7027         {
7028           address_set = 1;
7029           is_ipv6 = 0;
7030         }
7031       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
7032         {
7033           address_set = 1;
7034           is_ipv6 = 1;
7035         }
7036       else if (unformat (i, "/%d", &dst_address_length))
7037         {
7038           address_length_set = 1;
7039         }
7040
7041       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
7042                                          &v4_next_hop_address))
7043         {
7044           next_hop_set = 1;
7045         }
7046       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
7047                                          &v6_next_hop_address))
7048         {
7049           next_hop_set = 1;
7050         }
7051       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
7052         ;
7053       else if (unformat (i, "weight %d", &next_hop_weight))
7054         ;
7055       else if (unformat (i, "drop"))
7056         {
7057           is_drop = 1;
7058         }
7059       else if (unformat (i, "null-send-unreach"))
7060         {
7061           is_unreach = 1;
7062         }
7063       else if (unformat (i, "null-send-prohibit"))
7064         {
7065           is_prohibit = 1;
7066         }
7067       else if (unformat (i, "local"))
7068         {
7069           is_local = 1;
7070         }
7071       else if (unformat (i, "classify %d", &classify_table_index))
7072         {
7073           is_classify = 1;
7074         }
7075       else if (unformat (i, "del"))
7076         is_add = 0;
7077       else if (unformat (i, "add"))
7078         is_add = 1;
7079       else if (unformat (i, "not-last"))
7080         not_last = 1;
7081       else if (unformat (i, "resolve-via-host"))
7082         resolve_host = 1;
7083       else if (unformat (i, "resolve-via-attached"))
7084         resolve_attached = 1;
7085       else if (unformat (i, "multipath"))
7086         is_multipath = 1;
7087       else if (unformat (i, "vrf %d", &vrf_id))
7088         ;
7089       else if (unformat (i, "create-vrf"))
7090         create_vrf_if_needed = 1;
7091       else if (unformat (i, "count %d", &count))
7092         ;
7093       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
7094         ;
7095       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7096         ;
7097       else if (unformat (i, "out-label %d", &next_hop_out_label))
7098         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7099       else if (unformat (i, "via-label %d", &next_hop_via_label))
7100         ;
7101       else if (unformat (i, "random"))
7102         random_add_del = 1;
7103       else if (unformat (i, "seed %d", &random_seed))
7104         ;
7105       else
7106         {
7107           clib_warning ("parse error '%U'", format_unformat_error, i);
7108           return -99;
7109         }
7110     }
7111
7112   if (!next_hop_set && !is_drop && !is_local &&
7113       !is_classify && !is_unreach && !is_prohibit &&
7114       MPLS_LABEL_INVALID == next_hop_via_label)
7115     {
7116       errmsg
7117         ("next hop / local / drop / unreach / prohibit / classify not set");
7118       return -99;
7119     }
7120
7121   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
7122     {
7123       errmsg ("next hop and next-hop via label set");
7124       return -99;
7125     }
7126   if (address_set == 0)
7127     {
7128       errmsg ("missing addresses");
7129       return -99;
7130     }
7131
7132   if (address_length_set == 0)
7133     {
7134       errmsg ("missing address length");
7135       return -99;
7136     }
7137
7138   /* Generate a pile of unique, random routes */
7139   if (random_add_del)
7140     {
7141       u32 this_random_address;
7142       random_hash = hash_create (count, sizeof (uword));
7143
7144       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
7145       for (j = 0; j <= count; j++)
7146         {
7147           do
7148             {
7149               this_random_address = random_u32 (&random_seed);
7150               this_random_address =
7151                 clib_host_to_net_u32 (this_random_address);
7152             }
7153           while (hash_get (random_hash, this_random_address));
7154           vec_add1 (random_vector, this_random_address);
7155           hash_set (random_hash, this_random_address, 1);
7156         }
7157       hash_free (random_hash);
7158       v4_dst_address.as_u32 = random_vector[0];
7159     }
7160
7161   if (count > 1)
7162     {
7163       /* Turn on async mode */
7164       vam->async_mode = 1;
7165       vam->async_errors = 0;
7166       before = vat_time_now (vam);
7167     }
7168
7169   for (j = 0; j < count; j++)
7170     {
7171       /* Construct the API message */
7172       M2 (IP_ADD_DEL_ROUTE, mp,
7173           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7174
7175       mp->next_hop_sw_if_index = ntohl (sw_if_index);
7176       mp->table_id = ntohl (vrf_id);
7177       mp->create_vrf_if_needed = create_vrf_if_needed;
7178
7179       mp->is_add = is_add;
7180       mp->is_drop = is_drop;
7181       mp->is_unreach = is_unreach;
7182       mp->is_prohibit = is_prohibit;
7183       mp->is_ipv6 = is_ipv6;
7184       mp->is_local = is_local;
7185       mp->is_classify = is_classify;
7186       mp->is_multipath = is_multipath;
7187       mp->is_resolve_host = resolve_host;
7188       mp->is_resolve_attached = resolve_attached;
7189       mp->not_last = not_last;
7190       mp->next_hop_weight = next_hop_weight;
7191       mp->dst_address_length = dst_address_length;
7192       mp->next_hop_table_id = ntohl (next_hop_table_id);
7193       mp->classify_table_index = ntohl (classify_table_index);
7194       mp->next_hop_via_label = ntohl (next_hop_via_label);
7195       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7196       if (0 != mp->next_hop_n_out_labels)
7197         {
7198           memcpy (mp->next_hop_out_label_stack,
7199                   next_hop_out_label_stack,
7200                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7201           vec_free (next_hop_out_label_stack);
7202         }
7203
7204       if (is_ipv6)
7205         {
7206           clib_memcpy (mp->dst_address, &v6_dst_address,
7207                        sizeof (v6_dst_address));
7208           if (next_hop_set)
7209             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
7210                          sizeof (v6_next_hop_address));
7211           increment_v6_address (&v6_dst_address);
7212         }
7213       else
7214         {
7215           clib_memcpy (mp->dst_address, &v4_dst_address,
7216                        sizeof (v4_dst_address));
7217           if (next_hop_set)
7218             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
7219                          sizeof (v4_next_hop_address));
7220           if (random_add_del)
7221             v4_dst_address.as_u32 = random_vector[j + 1];
7222           else
7223             increment_v4_address (&v4_dst_address);
7224         }
7225       /* send it... */
7226       S (mp);
7227       /* If we receive SIGTERM, stop now... */
7228       if (vam->do_exit)
7229         break;
7230     }
7231
7232   /* When testing multiple add/del ops, use a control-ping to sync */
7233   if (count > 1)
7234     {
7235       vl_api_control_ping_t *mp_ping;
7236       f64 after;
7237       f64 timeout;
7238
7239       /* Shut off async mode */
7240       vam->async_mode = 0;
7241
7242       M (CONTROL_PING, mp_ping);
7243       S (mp_ping);
7244
7245       timeout = vat_time_now (vam) + 1.0;
7246       while (vat_time_now (vam) < timeout)
7247         if (vam->result_ready == 1)
7248           goto out;
7249       vam->retval = -99;
7250
7251     out:
7252       if (vam->retval == -99)
7253         errmsg ("timeout");
7254
7255       if (vam->async_errors > 0)
7256         {
7257           errmsg ("%d asynchronous errors", vam->async_errors);
7258           vam->retval = -98;
7259         }
7260       vam->async_errors = 0;
7261       after = vat_time_now (vam);
7262
7263       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7264       if (j > 0)
7265         count = j;
7266
7267       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7268              count, after - before, count / (after - before));
7269     }
7270   else
7271     {
7272       int ret;
7273
7274       /* Wait for a reply... */
7275       W (ret);
7276       return ret;
7277     }
7278
7279   /* Return the good/bad news */
7280   return (vam->retval);
7281 }
7282
7283 static int
7284 api_ip_mroute_add_del (vat_main_t * vam)
7285 {
7286   unformat_input_t *i = vam->input;
7287   vl_api_ip_mroute_add_del_t *mp;
7288   u32 sw_if_index = ~0, vrf_id = 0;
7289   u8 is_ipv6 = 0;
7290   u8 is_local = 0;
7291   u8 create_vrf_if_needed = 0;
7292   u8 is_add = 1;
7293   u8 address_set = 0;
7294   u32 grp_address_length = 0;
7295   ip4_address_t v4_grp_address, v4_src_address;
7296   ip6_address_t v6_grp_address, v6_src_address;
7297   mfib_itf_flags_t iflags = 0;
7298   mfib_entry_flags_t eflags = 0;
7299   int ret;
7300
7301   /* Parse args required to build the message */
7302   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7303     {
7304       if (unformat (i, "sw_if_index %d", &sw_if_index))
7305         ;
7306       else if (unformat (i, "%U %U",
7307                          unformat_ip4_address, &v4_src_address,
7308                          unformat_ip4_address, &v4_grp_address))
7309         {
7310           grp_address_length = 64;
7311           address_set = 1;
7312           is_ipv6 = 0;
7313         }
7314       else if (unformat (i, "%U %U",
7315                          unformat_ip6_address, &v6_src_address,
7316                          unformat_ip6_address, &v6_grp_address))
7317         {
7318           grp_address_length = 256;
7319           address_set = 1;
7320           is_ipv6 = 1;
7321         }
7322       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
7323         {
7324           memset (&v4_src_address, 0, sizeof (v4_src_address));
7325           grp_address_length = 32;
7326           address_set = 1;
7327           is_ipv6 = 0;
7328         }
7329       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
7330         {
7331           memset (&v6_src_address, 0, sizeof (v6_src_address));
7332           grp_address_length = 128;
7333           address_set = 1;
7334           is_ipv6 = 1;
7335         }
7336       else if (unformat (i, "/%d", &grp_address_length))
7337         ;
7338       else if (unformat (i, "local"))
7339         {
7340           is_local = 1;
7341         }
7342       else if (unformat (i, "del"))
7343         is_add = 0;
7344       else if (unformat (i, "add"))
7345         is_add = 1;
7346       else if (unformat (i, "vrf %d", &vrf_id))
7347         ;
7348       else if (unformat (i, "create-vrf"))
7349         create_vrf_if_needed = 1;
7350       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
7351         ;
7352       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
7353         ;
7354       else
7355         {
7356           clib_warning ("parse error '%U'", format_unformat_error, i);
7357           return -99;
7358         }
7359     }
7360
7361   if (address_set == 0)
7362     {
7363       errmsg ("missing addresses\n");
7364       return -99;
7365     }
7366
7367   /* Construct the API message */
7368   M (IP_MROUTE_ADD_DEL, mp);
7369
7370   mp->next_hop_sw_if_index = ntohl (sw_if_index);
7371   mp->table_id = ntohl (vrf_id);
7372   mp->create_vrf_if_needed = create_vrf_if_needed;
7373
7374   mp->is_add = is_add;
7375   mp->is_ipv6 = is_ipv6;
7376   mp->is_local = is_local;
7377   mp->itf_flags = ntohl (iflags);
7378   mp->entry_flags = ntohl (eflags);
7379   mp->grp_address_length = grp_address_length;
7380   mp->grp_address_length = ntohs (mp->grp_address_length);
7381
7382   if (is_ipv6)
7383     {
7384       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
7385       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
7386     }
7387   else
7388     {
7389       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
7390       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
7391
7392     }
7393
7394   /* send it... */
7395   S (mp);
7396   /* Wait for a reply... */
7397   W (ret);
7398   return ret;
7399 }
7400
7401 static int
7402 api_mpls_route_add_del (vat_main_t * vam)
7403 {
7404   unformat_input_t *i = vam->input;
7405   vl_api_mpls_route_add_del_t *mp;
7406   u32 sw_if_index = ~0, table_id = 0;
7407   u8 create_table_if_needed = 0;
7408   u8 is_add = 1;
7409   u32 next_hop_weight = 1;
7410   u8 is_multipath = 0;
7411   u32 next_hop_table_id = 0;
7412   u8 next_hop_set = 0;
7413   ip4_address_t v4_next_hop_address = {
7414     .as_u32 = 0,
7415   };
7416   ip6_address_t v6_next_hop_address = { {0} };
7417   int count = 1;
7418   int j;
7419   f64 before = 0;
7420   u32 classify_table_index = ~0;
7421   u8 is_classify = 0;
7422   u8 resolve_host = 0, resolve_attached = 0;
7423   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7424   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7425   mpls_label_t *next_hop_out_label_stack = NULL;
7426   mpls_label_t local_label = MPLS_LABEL_INVALID;
7427   u8 is_eos = 0;
7428   u8 next_hop_proto_is_ip4 = 1;
7429
7430   /* Parse args required to build the message */
7431   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7432     {
7433       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7434         ;
7435       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7436         ;
7437       else if (unformat (i, "%d", &local_label))
7438         ;
7439       else if (unformat (i, "eos"))
7440         is_eos = 1;
7441       else if (unformat (i, "non-eos"))
7442         is_eos = 0;
7443       else if (unformat (i, "via %U", unformat_ip4_address,
7444                          &v4_next_hop_address))
7445         {
7446           next_hop_set = 1;
7447           next_hop_proto_is_ip4 = 1;
7448         }
7449       else if (unformat (i, "via %U", unformat_ip6_address,
7450                          &v6_next_hop_address))
7451         {
7452           next_hop_set = 1;
7453           next_hop_proto_is_ip4 = 0;
7454         }
7455       else if (unformat (i, "weight %d", &next_hop_weight))
7456         ;
7457       else if (unformat (i, "create-table"))
7458         create_table_if_needed = 1;
7459       else if (unformat (i, "classify %d", &classify_table_index))
7460         {
7461           is_classify = 1;
7462         }
7463       else if (unformat (i, "del"))
7464         is_add = 0;
7465       else if (unformat (i, "add"))
7466         is_add = 1;
7467       else if (unformat (i, "resolve-via-host"))
7468         resolve_host = 1;
7469       else if (unformat (i, "resolve-via-attached"))
7470         resolve_attached = 1;
7471       else if (unformat (i, "multipath"))
7472         is_multipath = 1;
7473       else if (unformat (i, "count %d", &count))
7474         ;
7475       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
7476         {
7477           next_hop_set = 1;
7478           next_hop_proto_is_ip4 = 1;
7479         }
7480       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
7481         {
7482           next_hop_set = 1;
7483           next_hop_proto_is_ip4 = 0;
7484         }
7485       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7486         ;
7487       else if (unformat (i, "via-label %d", &next_hop_via_label))
7488         ;
7489       else if (unformat (i, "out-label %d", &next_hop_out_label))
7490         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7491       else
7492         {
7493           clib_warning ("parse error '%U'", format_unformat_error, i);
7494           return -99;
7495         }
7496     }
7497
7498   if (!next_hop_set && !is_classify)
7499     {
7500       errmsg ("next hop / classify not set");
7501       return -99;
7502     }
7503
7504   if (MPLS_LABEL_INVALID == local_label)
7505     {
7506       errmsg ("missing label");
7507       return -99;
7508     }
7509
7510   if (count > 1)
7511     {
7512       /* Turn on async mode */
7513       vam->async_mode = 1;
7514       vam->async_errors = 0;
7515       before = vat_time_now (vam);
7516     }
7517
7518   for (j = 0; j < count; j++)
7519     {
7520       /* Construct the API message */
7521       M2 (MPLS_ROUTE_ADD_DEL, mp,
7522           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7523
7524       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
7525       mp->mr_table_id = ntohl (table_id);
7526       mp->mr_create_table_if_needed = create_table_if_needed;
7527
7528       mp->mr_is_add = is_add;
7529       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7530       mp->mr_is_classify = is_classify;
7531       mp->mr_is_multipath = is_multipath;
7532       mp->mr_is_resolve_host = resolve_host;
7533       mp->mr_is_resolve_attached = resolve_attached;
7534       mp->mr_next_hop_weight = next_hop_weight;
7535       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
7536       mp->mr_classify_table_index = ntohl (classify_table_index);
7537       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
7538       mp->mr_label = ntohl (local_label);
7539       mp->mr_eos = is_eos;
7540
7541       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7542       if (0 != mp->mr_next_hop_n_out_labels)
7543         {
7544           memcpy (mp->mr_next_hop_out_label_stack,
7545                   next_hop_out_label_stack,
7546                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7547           vec_free (next_hop_out_label_stack);
7548         }
7549
7550       if (next_hop_set)
7551         {
7552           if (next_hop_proto_is_ip4)
7553             {
7554               clib_memcpy (mp->mr_next_hop,
7555                            &v4_next_hop_address,
7556                            sizeof (v4_next_hop_address));
7557             }
7558           else
7559             {
7560               clib_memcpy (mp->mr_next_hop,
7561                            &v6_next_hop_address,
7562                            sizeof (v6_next_hop_address));
7563             }
7564         }
7565       local_label++;
7566
7567       /* send it... */
7568       S (mp);
7569       /* If we receive SIGTERM, stop now... */
7570       if (vam->do_exit)
7571         break;
7572     }
7573
7574   /* When testing multiple add/del ops, use a control-ping to sync */
7575   if (count > 1)
7576     {
7577       vl_api_control_ping_t *mp_ping;
7578       f64 after;
7579       f64 timeout;
7580
7581       /* Shut off async mode */
7582       vam->async_mode = 0;
7583
7584       M (CONTROL_PING, mp_ping);
7585       S (mp_ping);
7586
7587       timeout = vat_time_now (vam) + 1.0;
7588       while (vat_time_now (vam) < timeout)
7589         if (vam->result_ready == 1)
7590           goto out;
7591       vam->retval = -99;
7592
7593     out:
7594       if (vam->retval == -99)
7595         errmsg ("timeout");
7596
7597       if (vam->async_errors > 0)
7598         {
7599           errmsg ("%d asynchronous errors", vam->async_errors);
7600           vam->retval = -98;
7601         }
7602       vam->async_errors = 0;
7603       after = vat_time_now (vam);
7604
7605       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7606       if (j > 0)
7607         count = j;
7608
7609       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7610              count, after - before, count / (after - before));
7611     }
7612   else
7613     {
7614       int ret;
7615
7616       /* Wait for a reply... */
7617       W (ret);
7618       return ret;
7619     }
7620
7621   /* Return the good/bad news */
7622   return (vam->retval);
7623 }
7624
7625 static int
7626 api_mpls_ip_bind_unbind (vat_main_t * vam)
7627 {
7628   unformat_input_t *i = vam->input;
7629   vl_api_mpls_ip_bind_unbind_t *mp;
7630   u32 ip_table_id = 0;
7631   u8 create_table_if_needed = 0;
7632   u8 is_bind = 1;
7633   u8 is_ip4 = 1;
7634   ip4_address_t v4_address;
7635   ip6_address_t v6_address;
7636   u32 address_length;
7637   u8 address_set = 0;
7638   mpls_label_t local_label = MPLS_LABEL_INVALID;
7639   int ret;
7640
7641   /* Parse args required to build the message */
7642   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7643     {
7644       if (unformat (i, "%U/%d", unformat_ip4_address,
7645                     &v4_address, &address_length))
7646         {
7647           is_ip4 = 1;
7648           address_set = 1;
7649         }
7650       else if (unformat (i, "%U/%d", unformat_ip6_address,
7651                          &v6_address, &address_length))
7652         {
7653           is_ip4 = 0;
7654           address_set = 1;
7655         }
7656       else if (unformat (i, "%d", &local_label))
7657         ;
7658       else if (unformat (i, "create-table"))
7659         create_table_if_needed = 1;
7660       else if (unformat (i, "table-id %d", &ip_table_id))
7661         ;
7662       else if (unformat (i, "unbind"))
7663         is_bind = 0;
7664       else if (unformat (i, "bind"))
7665         is_bind = 1;
7666       else
7667         {
7668           clib_warning ("parse error '%U'", format_unformat_error, i);
7669           return -99;
7670         }
7671     }
7672
7673   if (!address_set)
7674     {
7675       errmsg ("IP addres not set");
7676       return -99;
7677     }
7678
7679   if (MPLS_LABEL_INVALID == local_label)
7680     {
7681       errmsg ("missing label");
7682       return -99;
7683     }
7684
7685   /* Construct the API message */
7686   M (MPLS_IP_BIND_UNBIND, mp);
7687
7688   mp->mb_create_table_if_needed = create_table_if_needed;
7689   mp->mb_is_bind = is_bind;
7690   mp->mb_is_ip4 = is_ip4;
7691   mp->mb_ip_table_id = ntohl (ip_table_id);
7692   mp->mb_mpls_table_id = 0;
7693   mp->mb_label = ntohl (local_label);
7694   mp->mb_address_length = address_length;
7695
7696   if (is_ip4)
7697     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
7698   else
7699     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
7700
7701   /* send it... */
7702   S (mp);
7703
7704   /* Wait for a reply... */
7705   W (ret);
7706   return ret;
7707 }
7708
7709 static int
7710 api_proxy_arp_add_del (vat_main_t * vam)
7711 {
7712   unformat_input_t *i = vam->input;
7713   vl_api_proxy_arp_add_del_t *mp;
7714   u32 vrf_id = 0;
7715   u8 is_add = 1;
7716   ip4_address_t lo, hi;
7717   u8 range_set = 0;
7718   int ret;
7719
7720   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7721     {
7722       if (unformat (i, "vrf %d", &vrf_id))
7723         ;
7724       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
7725                          unformat_ip4_address, &hi))
7726         range_set = 1;
7727       else if (unformat (i, "del"))
7728         is_add = 0;
7729       else
7730         {
7731           clib_warning ("parse error '%U'", format_unformat_error, i);
7732           return -99;
7733         }
7734     }
7735
7736   if (range_set == 0)
7737     {
7738       errmsg ("address range not set");
7739       return -99;
7740     }
7741
7742   M (PROXY_ARP_ADD_DEL, mp);
7743
7744   mp->vrf_id = ntohl (vrf_id);
7745   mp->is_add = is_add;
7746   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
7747   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
7748
7749   S (mp);
7750   W (ret);
7751   return ret;
7752 }
7753
7754 static int
7755 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
7756 {
7757   unformat_input_t *i = vam->input;
7758   vl_api_proxy_arp_intfc_enable_disable_t *mp;
7759   u32 sw_if_index;
7760   u8 enable = 1;
7761   u8 sw_if_index_set = 0;
7762   int ret;
7763
7764   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7765     {
7766       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7767         sw_if_index_set = 1;
7768       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7769         sw_if_index_set = 1;
7770       else if (unformat (i, "enable"))
7771         enable = 1;
7772       else if (unformat (i, "disable"))
7773         enable = 0;
7774       else
7775         {
7776           clib_warning ("parse error '%U'", format_unformat_error, i);
7777           return -99;
7778         }
7779     }
7780
7781   if (sw_if_index_set == 0)
7782     {
7783       errmsg ("missing interface name or sw_if_index");
7784       return -99;
7785     }
7786
7787   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
7788
7789   mp->sw_if_index = ntohl (sw_if_index);
7790   mp->enable_disable = enable;
7791
7792   S (mp);
7793   W (ret);
7794   return ret;
7795 }
7796
7797 static int
7798 api_mpls_tunnel_add_del (vat_main_t * vam)
7799 {
7800   unformat_input_t *i = vam->input;
7801   vl_api_mpls_tunnel_add_del_t *mp;
7802
7803   u8 is_add = 1;
7804   u8 l2_only = 0;
7805   u32 sw_if_index = ~0;
7806   u32 next_hop_sw_if_index = ~0;
7807   u32 next_hop_proto_is_ip4 = 1;
7808
7809   u32 next_hop_table_id = 0;
7810   ip4_address_t v4_next_hop_address = {
7811     .as_u32 = 0,
7812   };
7813   ip6_address_t v6_next_hop_address = { {0} };
7814   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
7815   int ret;
7816
7817   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7818     {
7819       if (unformat (i, "add"))
7820         is_add = 1;
7821       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7822         is_add = 0;
7823       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7824         ;
7825       else if (unformat (i, "via %U",
7826                          unformat_ip4_address, &v4_next_hop_address))
7827         {
7828           next_hop_proto_is_ip4 = 1;
7829         }
7830       else if (unformat (i, "via %U",
7831                          unformat_ip6_address, &v6_next_hop_address))
7832         {
7833           next_hop_proto_is_ip4 = 0;
7834         }
7835       else if (unformat (i, "l2-only"))
7836         l2_only = 1;
7837       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7838         ;
7839       else if (unformat (i, "out-label %d", &next_hop_out_label))
7840         vec_add1 (labels, ntohl (next_hop_out_label));
7841       else
7842         {
7843           clib_warning ("parse error '%U'", format_unformat_error, i);
7844           return -99;
7845         }
7846     }
7847
7848   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
7849
7850   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
7851   mp->mt_sw_if_index = ntohl (sw_if_index);
7852   mp->mt_is_add = is_add;
7853   mp->mt_l2_only = l2_only;
7854   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
7855   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7856
7857   mp->mt_next_hop_n_out_labels = vec_len (labels);
7858
7859   if (0 != mp->mt_next_hop_n_out_labels)
7860     {
7861       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7862                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7863       vec_free (labels);
7864     }
7865
7866   if (next_hop_proto_is_ip4)
7867     {
7868       clib_memcpy (mp->mt_next_hop,
7869                    &v4_next_hop_address, sizeof (v4_next_hop_address));
7870     }
7871   else
7872     {
7873       clib_memcpy (mp->mt_next_hop,
7874                    &v6_next_hop_address, sizeof (v6_next_hop_address));
7875     }
7876
7877   S (mp);
7878   W (ret);
7879   return ret;
7880 }
7881
7882 static int
7883 api_sw_interface_set_unnumbered (vat_main_t * vam)
7884 {
7885   unformat_input_t *i = vam->input;
7886   vl_api_sw_interface_set_unnumbered_t *mp;
7887   u32 sw_if_index;
7888   u32 unnum_sw_index = ~0;
7889   u8 is_add = 1;
7890   u8 sw_if_index_set = 0;
7891   int ret;
7892
7893   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7894     {
7895       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7896         sw_if_index_set = 1;
7897       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7898         sw_if_index_set = 1;
7899       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7900         ;
7901       else if (unformat (i, "del"))
7902         is_add = 0;
7903       else
7904         {
7905           clib_warning ("parse error '%U'", format_unformat_error, i);
7906           return -99;
7907         }
7908     }
7909
7910   if (sw_if_index_set == 0)
7911     {
7912       errmsg ("missing interface name or sw_if_index");
7913       return -99;
7914     }
7915
7916   M (SW_INTERFACE_SET_UNNUMBERED, mp);
7917
7918   mp->sw_if_index = ntohl (sw_if_index);
7919   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7920   mp->is_add = is_add;
7921
7922   S (mp);
7923   W (ret);
7924   return ret;
7925 }
7926
7927 static int
7928 api_ip_neighbor_add_del (vat_main_t * vam)
7929 {
7930   unformat_input_t *i = vam->input;
7931   vl_api_ip_neighbor_add_del_t *mp;
7932   u32 sw_if_index;
7933   u8 sw_if_index_set = 0;
7934   u8 is_add = 1;
7935   u8 is_static = 0;
7936   u8 is_no_fib_entry = 0;
7937   u8 mac_address[6];
7938   u8 mac_set = 0;
7939   u8 v4_address_set = 0;
7940   u8 v6_address_set = 0;
7941   ip4_address_t v4address;
7942   ip6_address_t v6address;
7943   int ret;
7944
7945   memset (mac_address, 0, sizeof (mac_address));
7946
7947   /* Parse args required to build the message */
7948   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7949     {
7950       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7951         {
7952           mac_set = 1;
7953         }
7954       else if (unformat (i, "del"))
7955         is_add = 0;
7956       else
7957         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7958         sw_if_index_set = 1;
7959       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7960         sw_if_index_set = 1;
7961       else if (unformat (i, "is_static"))
7962         is_static = 1;
7963       else if (unformat (i, "no-fib-entry"))
7964         is_no_fib_entry = 1;
7965       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
7966         v4_address_set = 1;
7967       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
7968         v6_address_set = 1;
7969       else
7970         {
7971           clib_warning ("parse error '%U'", format_unformat_error, i);
7972           return -99;
7973         }
7974     }
7975
7976   if (sw_if_index_set == 0)
7977     {
7978       errmsg ("missing interface name or sw_if_index");
7979       return -99;
7980     }
7981   if (v4_address_set && v6_address_set)
7982     {
7983       errmsg ("both v4 and v6 addresses set");
7984       return -99;
7985     }
7986   if (!v4_address_set && !v6_address_set)
7987     {
7988       errmsg ("no address set");
7989       return -99;
7990     }
7991
7992   /* Construct the API message */
7993   M (IP_NEIGHBOR_ADD_DEL, mp);
7994
7995   mp->sw_if_index = ntohl (sw_if_index);
7996   mp->is_add = is_add;
7997   mp->is_static = is_static;
7998   mp->is_no_adj_fib = is_no_fib_entry;
7999   if (mac_set)
8000     clib_memcpy (mp->mac_address, mac_address, 6);
8001   if (v6_address_set)
8002     {
8003       mp->is_ipv6 = 1;
8004       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
8005     }
8006   else
8007     {
8008       /* mp->is_ipv6 = 0; via memset in M macro above */
8009       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
8010     }
8011
8012   /* send it... */
8013   S (mp);
8014
8015   /* Wait for a reply, return good/bad news  */
8016   W (ret);
8017   return ret;
8018 }
8019
8020 static int
8021 api_reset_vrf (vat_main_t * vam)
8022 {
8023   unformat_input_t *i = vam->input;
8024   vl_api_reset_vrf_t *mp;
8025   u32 vrf_id = 0;
8026   u8 is_ipv6 = 0;
8027   u8 vrf_id_set = 0;
8028   int ret;
8029
8030   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8031     {
8032       if (unformat (i, "vrf %d", &vrf_id))
8033         vrf_id_set = 1;
8034       else if (unformat (i, "ipv6"))
8035         is_ipv6 = 1;
8036       else
8037         {
8038           clib_warning ("parse error '%U'", format_unformat_error, i);
8039           return -99;
8040         }
8041     }
8042
8043   if (vrf_id_set == 0)
8044     {
8045       errmsg ("missing vrf id");
8046       return -99;
8047     }
8048
8049   M (RESET_VRF, mp);
8050
8051   mp->vrf_id = ntohl (vrf_id);
8052   mp->is_ipv6 = is_ipv6;
8053
8054   S (mp);
8055   W (ret);
8056   return ret;
8057 }
8058
8059 static int
8060 api_create_vlan_subif (vat_main_t * vam)
8061 {
8062   unformat_input_t *i = vam->input;
8063   vl_api_create_vlan_subif_t *mp;
8064   u32 sw_if_index;
8065   u8 sw_if_index_set = 0;
8066   u32 vlan_id;
8067   u8 vlan_id_set = 0;
8068   int ret;
8069
8070   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8071     {
8072       if (unformat (i, "sw_if_index %d", &sw_if_index))
8073         sw_if_index_set = 1;
8074       else
8075         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8076         sw_if_index_set = 1;
8077       else if (unformat (i, "vlan %d", &vlan_id))
8078         vlan_id_set = 1;
8079       else
8080         {
8081           clib_warning ("parse error '%U'", format_unformat_error, i);
8082           return -99;
8083         }
8084     }
8085
8086   if (sw_if_index_set == 0)
8087     {
8088       errmsg ("missing interface name or sw_if_index");
8089       return -99;
8090     }
8091
8092   if (vlan_id_set == 0)
8093     {
8094       errmsg ("missing vlan_id");
8095       return -99;
8096     }
8097   M (CREATE_VLAN_SUBIF, mp);
8098
8099   mp->sw_if_index = ntohl (sw_if_index);
8100   mp->vlan_id = ntohl (vlan_id);
8101
8102   S (mp);
8103   W (ret);
8104   return ret;
8105 }
8106
8107 #define foreach_create_subif_bit                \
8108 _(no_tags)                                      \
8109 _(one_tag)                                      \
8110 _(two_tags)                                     \
8111 _(dot1ad)                                       \
8112 _(exact_match)                                  \
8113 _(default_sub)                                  \
8114 _(outer_vlan_id_any)                            \
8115 _(inner_vlan_id_any)
8116
8117 static int
8118 api_create_subif (vat_main_t * vam)
8119 {
8120   unformat_input_t *i = vam->input;
8121   vl_api_create_subif_t *mp;
8122   u32 sw_if_index;
8123   u8 sw_if_index_set = 0;
8124   u32 sub_id;
8125   u8 sub_id_set = 0;
8126   u32 no_tags = 0;
8127   u32 one_tag = 0;
8128   u32 two_tags = 0;
8129   u32 dot1ad = 0;
8130   u32 exact_match = 0;
8131   u32 default_sub = 0;
8132   u32 outer_vlan_id_any = 0;
8133   u32 inner_vlan_id_any = 0;
8134   u32 tmp;
8135   u16 outer_vlan_id = 0;
8136   u16 inner_vlan_id = 0;
8137   int ret;
8138
8139   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8140     {
8141       if (unformat (i, "sw_if_index %d", &sw_if_index))
8142         sw_if_index_set = 1;
8143       else
8144         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8145         sw_if_index_set = 1;
8146       else if (unformat (i, "sub_id %d", &sub_id))
8147         sub_id_set = 1;
8148       else if (unformat (i, "outer_vlan_id %d", &tmp))
8149         outer_vlan_id = tmp;
8150       else if (unformat (i, "inner_vlan_id %d", &tmp))
8151         inner_vlan_id = tmp;
8152
8153 #define _(a) else if (unformat (i, #a)) a = 1 ;
8154       foreach_create_subif_bit
8155 #undef _
8156         else
8157         {
8158           clib_warning ("parse error '%U'", format_unformat_error, i);
8159           return -99;
8160         }
8161     }
8162
8163   if (sw_if_index_set == 0)
8164     {
8165       errmsg ("missing interface name or sw_if_index");
8166       return -99;
8167     }
8168
8169   if (sub_id_set == 0)
8170     {
8171       errmsg ("missing sub_id");
8172       return -99;
8173     }
8174   M (CREATE_SUBIF, mp);
8175
8176   mp->sw_if_index = ntohl (sw_if_index);
8177   mp->sub_id = ntohl (sub_id);
8178
8179 #define _(a) mp->a = a;
8180   foreach_create_subif_bit;
8181 #undef _
8182
8183   mp->outer_vlan_id = ntohs (outer_vlan_id);
8184   mp->inner_vlan_id = ntohs (inner_vlan_id);
8185
8186   S (mp);
8187   W (ret);
8188   return ret;
8189 }
8190
8191 static int
8192 api_oam_add_del (vat_main_t * vam)
8193 {
8194   unformat_input_t *i = vam->input;
8195   vl_api_oam_add_del_t *mp;
8196   u32 vrf_id = 0;
8197   u8 is_add = 1;
8198   ip4_address_t src, dst;
8199   u8 src_set = 0;
8200   u8 dst_set = 0;
8201   int ret;
8202
8203   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8204     {
8205       if (unformat (i, "vrf %d", &vrf_id))
8206         ;
8207       else if (unformat (i, "src %U", unformat_ip4_address, &src))
8208         src_set = 1;
8209       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
8210         dst_set = 1;
8211       else if (unformat (i, "del"))
8212         is_add = 0;
8213       else
8214         {
8215           clib_warning ("parse error '%U'", format_unformat_error, i);
8216           return -99;
8217         }
8218     }
8219
8220   if (src_set == 0)
8221     {
8222       errmsg ("missing src addr");
8223       return -99;
8224     }
8225
8226   if (dst_set == 0)
8227     {
8228       errmsg ("missing dst addr");
8229       return -99;
8230     }
8231
8232   M (OAM_ADD_DEL, mp);
8233
8234   mp->vrf_id = ntohl (vrf_id);
8235   mp->is_add = is_add;
8236   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
8237   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
8238
8239   S (mp);
8240   W (ret);
8241   return ret;
8242 }
8243
8244 static int
8245 api_reset_fib (vat_main_t * vam)
8246 {
8247   unformat_input_t *i = vam->input;
8248   vl_api_reset_fib_t *mp;
8249   u32 vrf_id = 0;
8250   u8 is_ipv6 = 0;
8251   u8 vrf_id_set = 0;
8252
8253   int ret;
8254   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8255     {
8256       if (unformat (i, "vrf %d", &vrf_id))
8257         vrf_id_set = 1;
8258       else if (unformat (i, "ipv6"))
8259         is_ipv6 = 1;
8260       else
8261         {
8262           clib_warning ("parse error '%U'", format_unformat_error, i);
8263           return -99;
8264         }
8265     }
8266
8267   if (vrf_id_set == 0)
8268     {
8269       errmsg ("missing vrf id");
8270       return -99;
8271     }
8272
8273   M (RESET_FIB, mp);
8274
8275   mp->vrf_id = ntohl (vrf_id);
8276   mp->is_ipv6 = is_ipv6;
8277
8278   S (mp);
8279   W (ret);
8280   return ret;
8281 }
8282
8283 static int
8284 api_dhcp_proxy_config (vat_main_t * vam)
8285 {
8286   unformat_input_t *i = vam->input;
8287   vl_api_dhcp_proxy_config_t *mp;
8288   u32 rx_vrf_id = 0;
8289   u32 server_vrf_id = 0;
8290   u8 is_add = 1;
8291   u8 v4_address_set = 0;
8292   u8 v6_address_set = 0;
8293   ip4_address_t v4address;
8294   ip6_address_t v6address;
8295   u8 v4_src_address_set = 0;
8296   u8 v6_src_address_set = 0;
8297   ip4_address_t v4srcaddress;
8298   ip6_address_t v6srcaddress;
8299   int ret;
8300
8301   /* Parse args required to build the message */
8302   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8303     {
8304       if (unformat (i, "del"))
8305         is_add = 0;
8306       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
8307         ;
8308       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
8309         ;
8310       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
8311         v4_address_set = 1;
8312       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
8313         v6_address_set = 1;
8314       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
8315         v4_src_address_set = 1;
8316       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
8317         v6_src_address_set = 1;
8318       else
8319         break;
8320     }
8321
8322   if (v4_address_set && v6_address_set)
8323     {
8324       errmsg ("both v4 and v6 server addresses set");
8325       return -99;
8326     }
8327   if (!v4_address_set && !v6_address_set)
8328     {
8329       errmsg ("no server addresses set");
8330       return -99;
8331     }
8332
8333   if (v4_src_address_set && v6_src_address_set)
8334     {
8335       errmsg ("both v4 and v6  src addresses set");
8336       return -99;
8337     }
8338   if (!v4_src_address_set && !v6_src_address_set)
8339     {
8340       errmsg ("no src addresses set");
8341       return -99;
8342     }
8343
8344   if (!(v4_src_address_set && v4_address_set) &&
8345       !(v6_src_address_set && v6_address_set))
8346     {
8347       errmsg ("no matching server and src addresses set");
8348       return -99;
8349     }
8350
8351   /* Construct the API message */
8352   M (DHCP_PROXY_CONFIG, mp);
8353
8354   mp->is_add = is_add;
8355   mp->rx_vrf_id = ntohl (rx_vrf_id);
8356   mp->server_vrf_id = ntohl (server_vrf_id);
8357   if (v6_address_set)
8358     {
8359       mp->is_ipv6 = 1;
8360       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
8361       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
8362     }
8363   else
8364     {
8365       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
8366       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
8367     }
8368
8369   /* send it... */
8370   S (mp);
8371
8372   /* Wait for a reply, return good/bad news  */
8373   W (ret);
8374   return ret;
8375 }
8376
8377 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
8378 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
8379
8380 static void
8381 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
8382 {
8383   vat_main_t *vam = &vat_main;
8384   u32 i, count = mp->count;
8385   vl_api_dhcp_server_t *s;
8386
8387   if (mp->is_ipv6)
8388     print (vam->ofp,
8389            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8390            ntohl (mp->rx_vrf_id),
8391            format_ip6_address, mp->dhcp_src_address,
8392            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8393   else
8394     print (vam->ofp,
8395            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8396            ntohl (mp->rx_vrf_id),
8397            format_ip4_address, mp->dhcp_src_address,
8398            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8399
8400   for (i = 0; i < count; i++)
8401     {
8402       s = &mp->servers[i];
8403
8404       if (mp->is_ipv6)
8405         print (vam->ofp,
8406                " Server Table-ID %d, Server Address %U",
8407                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
8408       else
8409         print (vam->ofp,
8410                " Server Table-ID %d, Server Address %U",
8411                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
8412     }
8413 }
8414
8415 static void vl_api_dhcp_proxy_details_t_handler_json
8416   (vl_api_dhcp_proxy_details_t * mp)
8417 {
8418   vat_main_t *vam = &vat_main;
8419   vat_json_node_t *node = NULL;
8420   u32 i, count = mp->count;
8421   struct in_addr ip4;
8422   struct in6_addr ip6;
8423   vl_api_dhcp_server_t *s;
8424
8425   if (VAT_JSON_ARRAY != vam->json_tree.type)
8426     {
8427       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8428       vat_json_init_array (&vam->json_tree);
8429     }
8430   node = vat_json_array_add (&vam->json_tree);
8431
8432   vat_json_init_object (node);
8433   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
8434   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
8435   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
8436
8437   if (mp->is_ipv6)
8438     {
8439       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
8440       vat_json_object_add_ip6 (node, "src_address", ip6);
8441     }
8442   else
8443     {
8444       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
8445       vat_json_object_add_ip4 (node, "src_address", ip4);
8446     }
8447
8448   for (i = 0; i < count; i++)
8449     {
8450       s = &mp->servers[i];
8451
8452       vat_json_object_add_uint (node, "server-table-id",
8453                                 ntohl (s->server_vrf_id));
8454
8455       if (mp->is_ipv6)
8456         {
8457           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
8458           vat_json_object_add_ip4 (node, "src_address", ip4);
8459         }
8460       else
8461         {
8462           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
8463           vat_json_object_add_ip6 (node, "server_address", ip6);
8464         }
8465     }
8466 }
8467
8468 static int
8469 api_dhcp_proxy_dump (vat_main_t * vam)
8470 {
8471   unformat_input_t *i = vam->input;
8472   vl_api_control_ping_t *mp_ping;
8473   vl_api_dhcp_proxy_dump_t *mp;
8474   u8 is_ipv6 = 0;
8475   int ret;
8476
8477   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8478     {
8479       if (unformat (i, "ipv6"))
8480         is_ipv6 = 1;
8481       else
8482         {
8483           clib_warning ("parse error '%U'", format_unformat_error, i);
8484           return -99;
8485         }
8486     }
8487
8488   M (DHCP_PROXY_DUMP, mp);
8489
8490   mp->is_ip6 = is_ipv6;
8491   S (mp);
8492
8493   /* Use a control ping for synchronization */
8494   M (CONTROL_PING, mp_ping);
8495   S (mp_ping);
8496
8497   W (ret);
8498   return ret;
8499 }
8500
8501 static int
8502 api_dhcp_proxy_set_vss (vat_main_t * vam)
8503 {
8504   unformat_input_t *i = vam->input;
8505   vl_api_dhcp_proxy_set_vss_t *mp;
8506   u8 is_ipv6 = 0;
8507   u8 is_add = 1;
8508   u32 tbl_id;
8509   u8 tbl_id_set = 0;
8510   u32 oui;
8511   u8 oui_set = 0;
8512   u32 fib_id;
8513   u8 fib_id_set = 0;
8514   int ret;
8515
8516   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8517     {
8518       if (unformat (i, "tbl_id %d", &tbl_id))
8519         tbl_id_set = 1;
8520       if (unformat (i, "fib_id %d", &fib_id))
8521         fib_id_set = 1;
8522       if (unformat (i, "oui %d", &oui))
8523         oui_set = 1;
8524       else if (unformat (i, "ipv6"))
8525         is_ipv6 = 1;
8526       else if (unformat (i, "del"))
8527         is_add = 0;
8528       else
8529         {
8530           clib_warning ("parse error '%U'", format_unformat_error, i);
8531           return -99;
8532         }
8533     }
8534
8535   if (tbl_id_set == 0)
8536     {
8537       errmsg ("missing tbl id");
8538       return -99;
8539     }
8540
8541   if (fib_id_set == 0)
8542     {
8543       errmsg ("missing fib id");
8544       return -99;
8545     }
8546   if (oui_set == 0)
8547     {
8548       errmsg ("missing oui");
8549       return -99;
8550     }
8551
8552   M (DHCP_PROXY_SET_VSS, mp);
8553   mp->tbl_id = ntohl (tbl_id);
8554   mp->fib_id = ntohl (fib_id);
8555   mp->oui = ntohl (oui);
8556   mp->is_ipv6 = is_ipv6;
8557   mp->is_add = is_add;
8558
8559   S (mp);
8560   W (ret);
8561   return ret;
8562 }
8563
8564 static int
8565 api_dhcp_client_config (vat_main_t * vam)
8566 {
8567   unformat_input_t *i = vam->input;
8568   vl_api_dhcp_client_config_t *mp;
8569   u32 sw_if_index;
8570   u8 sw_if_index_set = 0;
8571   u8 is_add = 1;
8572   u8 *hostname = 0;
8573   u8 disable_event = 0;
8574   int ret;
8575
8576   /* Parse args required to build the message */
8577   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8578     {
8579       if (unformat (i, "del"))
8580         is_add = 0;
8581       else
8582         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8583         sw_if_index_set = 1;
8584       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8585         sw_if_index_set = 1;
8586       else if (unformat (i, "hostname %s", &hostname))
8587         ;
8588       else if (unformat (i, "disable_event"))
8589         disable_event = 1;
8590       else
8591         break;
8592     }
8593
8594   if (sw_if_index_set == 0)
8595     {
8596       errmsg ("missing interface name or sw_if_index");
8597       return -99;
8598     }
8599
8600   if (vec_len (hostname) > 63)
8601     {
8602       errmsg ("hostname too long");
8603     }
8604   vec_add1 (hostname, 0);
8605
8606   /* Construct the API message */
8607   M (DHCP_CLIENT_CONFIG, mp);
8608
8609   mp->sw_if_index = htonl (sw_if_index);
8610   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
8611   vec_free (hostname);
8612   mp->is_add = is_add;
8613   mp->want_dhcp_event = disable_event ? 0 : 1;
8614   mp->pid = htonl (getpid ());
8615
8616   /* send it... */
8617   S (mp);
8618
8619   /* Wait for a reply, return good/bad news  */
8620   W (ret);
8621   return ret;
8622 }
8623
8624 static int
8625 api_set_ip_flow_hash (vat_main_t * vam)
8626 {
8627   unformat_input_t *i = vam->input;
8628   vl_api_set_ip_flow_hash_t *mp;
8629   u32 vrf_id = 0;
8630   u8 is_ipv6 = 0;
8631   u8 vrf_id_set = 0;
8632   u8 src = 0;
8633   u8 dst = 0;
8634   u8 sport = 0;
8635   u8 dport = 0;
8636   u8 proto = 0;
8637   u8 reverse = 0;
8638   int ret;
8639
8640   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8641     {
8642       if (unformat (i, "vrf %d", &vrf_id))
8643         vrf_id_set = 1;
8644       else if (unformat (i, "ipv6"))
8645         is_ipv6 = 1;
8646       else if (unformat (i, "src"))
8647         src = 1;
8648       else if (unformat (i, "dst"))
8649         dst = 1;
8650       else if (unformat (i, "sport"))
8651         sport = 1;
8652       else if (unformat (i, "dport"))
8653         dport = 1;
8654       else if (unformat (i, "proto"))
8655         proto = 1;
8656       else if (unformat (i, "reverse"))
8657         reverse = 1;
8658
8659       else
8660         {
8661           clib_warning ("parse error '%U'", format_unformat_error, i);
8662           return -99;
8663         }
8664     }
8665
8666   if (vrf_id_set == 0)
8667     {
8668       errmsg ("missing vrf id");
8669       return -99;
8670     }
8671
8672   M (SET_IP_FLOW_HASH, mp);
8673   mp->src = src;
8674   mp->dst = dst;
8675   mp->sport = sport;
8676   mp->dport = dport;
8677   mp->proto = proto;
8678   mp->reverse = reverse;
8679   mp->vrf_id = ntohl (vrf_id);
8680   mp->is_ipv6 = is_ipv6;
8681
8682   S (mp);
8683   W (ret);
8684   return ret;
8685 }
8686
8687 static int
8688 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
8689 {
8690   unformat_input_t *i = vam->input;
8691   vl_api_sw_interface_ip6_enable_disable_t *mp;
8692   u32 sw_if_index;
8693   u8 sw_if_index_set = 0;
8694   u8 enable = 0;
8695   int ret;
8696
8697   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8698     {
8699       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8700         sw_if_index_set = 1;
8701       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8702         sw_if_index_set = 1;
8703       else if (unformat (i, "enable"))
8704         enable = 1;
8705       else if (unformat (i, "disable"))
8706         enable = 0;
8707       else
8708         {
8709           clib_warning ("parse error '%U'", format_unformat_error, i);
8710           return -99;
8711         }
8712     }
8713
8714   if (sw_if_index_set == 0)
8715     {
8716       errmsg ("missing interface name or sw_if_index");
8717       return -99;
8718     }
8719
8720   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
8721
8722   mp->sw_if_index = ntohl (sw_if_index);
8723   mp->enable = enable;
8724
8725   S (mp);
8726   W (ret);
8727   return ret;
8728 }
8729
8730 static int
8731 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
8732 {
8733   unformat_input_t *i = vam->input;
8734   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
8735   u32 sw_if_index;
8736   u8 sw_if_index_set = 0;
8737   u8 v6_address_set = 0;
8738   ip6_address_t v6address;
8739   int ret;
8740
8741   /* Parse args required to build the message */
8742   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8743     {
8744       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8745         sw_if_index_set = 1;
8746       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8747         sw_if_index_set = 1;
8748       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8749         v6_address_set = 1;
8750       else
8751         break;
8752     }
8753
8754   if (sw_if_index_set == 0)
8755     {
8756       errmsg ("missing interface name or sw_if_index");
8757       return -99;
8758     }
8759   if (!v6_address_set)
8760     {
8761       errmsg ("no address set");
8762       return -99;
8763     }
8764
8765   /* Construct the API message */
8766   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
8767
8768   mp->sw_if_index = ntohl (sw_if_index);
8769   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8770
8771   /* send it... */
8772   S (mp);
8773
8774   /* Wait for a reply, return good/bad news  */
8775   W (ret);
8776   return ret;
8777 }
8778
8779 static int
8780 api_ip6nd_proxy_add_del (vat_main_t * vam)
8781 {
8782   unformat_input_t *i = vam->input;
8783   vl_api_ip6nd_proxy_add_del_t *mp;
8784   u32 sw_if_index = ~0;
8785   u8 v6_address_set = 0;
8786   ip6_address_t v6address;
8787   u8 is_del = 0;
8788   int ret;
8789
8790   /* Parse args required to build the message */
8791   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8792     {
8793       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8794         ;
8795       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8796         ;
8797       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8798         v6_address_set = 1;
8799       if (unformat (i, "del"))
8800         is_del = 1;
8801       else
8802         {
8803           clib_warning ("parse error '%U'", format_unformat_error, i);
8804           return -99;
8805         }
8806     }
8807
8808   if (sw_if_index == ~0)
8809     {
8810       errmsg ("missing interface name or sw_if_index");
8811       return -99;
8812     }
8813   if (!v6_address_set)
8814     {
8815       errmsg ("no address set");
8816       return -99;
8817     }
8818
8819   /* Construct the API message */
8820   M (IP6ND_PROXY_ADD_DEL, mp);
8821
8822   mp->is_del = is_del;
8823   mp->sw_if_index = ntohl (sw_if_index);
8824   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8825
8826   /* send it... */
8827   S (mp);
8828
8829   /* Wait for a reply, return good/bad news  */
8830   W (ret);
8831   return ret;
8832 }
8833
8834 static int
8835 api_ip6nd_proxy_dump (vat_main_t * vam)
8836 {
8837   vl_api_ip6nd_proxy_dump_t *mp;
8838   vl_api_control_ping_t *mp_ping;
8839   int ret;
8840
8841   M (IP6ND_PROXY_DUMP, mp);
8842
8843   S (mp);
8844
8845   /* Use a control ping for synchronization */
8846   M (CONTROL_PING, mp_ping);
8847   S (mp_ping);
8848
8849   W (ret);
8850   return ret;
8851 }
8852
8853 static void vl_api_ip6nd_proxy_details_t_handler
8854   (vl_api_ip6nd_proxy_details_t * mp)
8855 {
8856   vat_main_t *vam = &vat_main;
8857
8858   print (vam->ofp, "host %U sw_if_index %d",
8859          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
8860 }
8861
8862 static void vl_api_ip6nd_proxy_details_t_handler_json
8863   (vl_api_ip6nd_proxy_details_t * mp)
8864 {
8865   vat_main_t *vam = &vat_main;
8866   struct in6_addr ip6;
8867   vat_json_node_t *node = NULL;
8868
8869   if (VAT_JSON_ARRAY != vam->json_tree.type)
8870     {
8871       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8872       vat_json_init_array (&vam->json_tree);
8873     }
8874   node = vat_json_array_add (&vam->json_tree);
8875
8876   vat_json_init_object (node);
8877   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
8878
8879   clib_memcpy (&ip6, mp->address, sizeof (ip6));
8880   vat_json_object_add_ip6 (node, "host", ip6);
8881 }
8882
8883 static int
8884 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
8885 {
8886   unformat_input_t *i = vam->input;
8887   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
8888   u32 sw_if_index;
8889   u8 sw_if_index_set = 0;
8890   u32 address_length = 0;
8891   u8 v6_address_set = 0;
8892   ip6_address_t v6address;
8893   u8 use_default = 0;
8894   u8 no_advertise = 0;
8895   u8 off_link = 0;
8896   u8 no_autoconfig = 0;
8897   u8 no_onlink = 0;
8898   u8 is_no = 0;
8899   u32 val_lifetime = 0;
8900   u32 pref_lifetime = 0;
8901   int ret;
8902
8903   /* Parse args required to build the message */
8904   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8905     {
8906       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8907         sw_if_index_set = 1;
8908       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8909         sw_if_index_set = 1;
8910       else if (unformat (i, "%U/%d",
8911                          unformat_ip6_address, &v6address, &address_length))
8912         v6_address_set = 1;
8913       else if (unformat (i, "val_life %d", &val_lifetime))
8914         ;
8915       else if (unformat (i, "pref_life %d", &pref_lifetime))
8916         ;
8917       else if (unformat (i, "def"))
8918         use_default = 1;
8919       else if (unformat (i, "noadv"))
8920         no_advertise = 1;
8921       else if (unformat (i, "offl"))
8922         off_link = 1;
8923       else if (unformat (i, "noauto"))
8924         no_autoconfig = 1;
8925       else if (unformat (i, "nolink"))
8926         no_onlink = 1;
8927       else if (unformat (i, "isno"))
8928         is_no = 1;
8929       else
8930         {
8931           clib_warning ("parse error '%U'", format_unformat_error, i);
8932           return -99;
8933         }
8934     }
8935
8936   if (sw_if_index_set == 0)
8937     {
8938       errmsg ("missing interface name or sw_if_index");
8939       return -99;
8940     }
8941   if (!v6_address_set)
8942     {
8943       errmsg ("no address set");
8944       return -99;
8945     }
8946
8947   /* Construct the API message */
8948   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
8949
8950   mp->sw_if_index = ntohl (sw_if_index);
8951   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8952   mp->address_length = address_length;
8953   mp->use_default = use_default;
8954   mp->no_advertise = no_advertise;
8955   mp->off_link = off_link;
8956   mp->no_autoconfig = no_autoconfig;
8957   mp->no_onlink = no_onlink;
8958   mp->is_no = is_no;
8959   mp->val_lifetime = ntohl (val_lifetime);
8960   mp->pref_lifetime = ntohl (pref_lifetime);
8961
8962   /* send it... */
8963   S (mp);
8964
8965   /* Wait for a reply, return good/bad news  */
8966   W (ret);
8967   return ret;
8968 }
8969
8970 static int
8971 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
8972 {
8973   unformat_input_t *i = vam->input;
8974   vl_api_sw_interface_ip6nd_ra_config_t *mp;
8975   u32 sw_if_index;
8976   u8 sw_if_index_set = 0;
8977   u8 suppress = 0;
8978   u8 managed = 0;
8979   u8 other = 0;
8980   u8 ll_option = 0;
8981   u8 send_unicast = 0;
8982   u8 cease = 0;
8983   u8 is_no = 0;
8984   u8 default_router = 0;
8985   u32 max_interval = 0;
8986   u32 min_interval = 0;
8987   u32 lifetime = 0;
8988   u32 initial_count = 0;
8989   u32 initial_interval = 0;
8990   int ret;
8991
8992
8993   /* Parse args required to build the message */
8994   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8995     {
8996       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8997         sw_if_index_set = 1;
8998       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8999         sw_if_index_set = 1;
9000       else if (unformat (i, "maxint %d", &max_interval))
9001         ;
9002       else if (unformat (i, "minint %d", &min_interval))
9003         ;
9004       else if (unformat (i, "life %d", &lifetime))
9005         ;
9006       else if (unformat (i, "count %d", &initial_count))
9007         ;
9008       else if (unformat (i, "interval %d", &initial_interval))
9009         ;
9010       else if (unformat (i, "suppress") || unformat (i, "surpress"))
9011         suppress = 1;
9012       else if (unformat (i, "managed"))
9013         managed = 1;
9014       else if (unformat (i, "other"))
9015         other = 1;
9016       else if (unformat (i, "ll"))
9017         ll_option = 1;
9018       else if (unformat (i, "send"))
9019         send_unicast = 1;
9020       else if (unformat (i, "cease"))
9021         cease = 1;
9022       else if (unformat (i, "isno"))
9023         is_no = 1;
9024       else if (unformat (i, "def"))
9025         default_router = 1;
9026       else
9027         {
9028           clib_warning ("parse error '%U'", format_unformat_error, i);
9029           return -99;
9030         }
9031     }
9032
9033   if (sw_if_index_set == 0)
9034     {
9035       errmsg ("missing interface name or sw_if_index");
9036       return -99;
9037     }
9038
9039   /* Construct the API message */
9040   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
9041
9042   mp->sw_if_index = ntohl (sw_if_index);
9043   mp->max_interval = ntohl (max_interval);
9044   mp->min_interval = ntohl (min_interval);
9045   mp->lifetime = ntohl (lifetime);
9046   mp->initial_count = ntohl (initial_count);
9047   mp->initial_interval = ntohl (initial_interval);
9048   mp->suppress = suppress;
9049   mp->managed = managed;
9050   mp->other = other;
9051   mp->ll_option = ll_option;
9052   mp->send_unicast = send_unicast;
9053   mp->cease = cease;
9054   mp->is_no = is_no;
9055   mp->default_router = default_router;
9056
9057   /* send it... */
9058   S (mp);
9059
9060   /* Wait for a reply, return good/bad news  */
9061   W (ret);
9062   return ret;
9063 }
9064
9065 static int
9066 api_set_arp_neighbor_limit (vat_main_t * vam)
9067 {
9068   unformat_input_t *i = vam->input;
9069   vl_api_set_arp_neighbor_limit_t *mp;
9070   u32 arp_nbr_limit;
9071   u8 limit_set = 0;
9072   u8 is_ipv6 = 0;
9073   int ret;
9074
9075   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9076     {
9077       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
9078         limit_set = 1;
9079       else if (unformat (i, "ipv6"))
9080         is_ipv6 = 1;
9081       else
9082         {
9083           clib_warning ("parse error '%U'", format_unformat_error, i);
9084           return -99;
9085         }
9086     }
9087
9088   if (limit_set == 0)
9089     {
9090       errmsg ("missing limit value");
9091       return -99;
9092     }
9093
9094   M (SET_ARP_NEIGHBOR_LIMIT, mp);
9095
9096   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
9097   mp->is_ipv6 = is_ipv6;
9098
9099   S (mp);
9100   W (ret);
9101   return ret;
9102 }
9103
9104 static int
9105 api_l2_patch_add_del (vat_main_t * vam)
9106 {
9107   unformat_input_t *i = vam->input;
9108   vl_api_l2_patch_add_del_t *mp;
9109   u32 rx_sw_if_index;
9110   u8 rx_sw_if_index_set = 0;
9111   u32 tx_sw_if_index;
9112   u8 tx_sw_if_index_set = 0;
9113   u8 is_add = 1;
9114   int ret;
9115
9116   /* Parse args required to build the message */
9117   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9118     {
9119       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9120         rx_sw_if_index_set = 1;
9121       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9122         tx_sw_if_index_set = 1;
9123       else if (unformat (i, "rx"))
9124         {
9125           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9126             {
9127               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9128                             &rx_sw_if_index))
9129                 rx_sw_if_index_set = 1;
9130             }
9131           else
9132             break;
9133         }
9134       else if (unformat (i, "tx"))
9135         {
9136           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9137             {
9138               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9139                             &tx_sw_if_index))
9140                 tx_sw_if_index_set = 1;
9141             }
9142           else
9143             break;
9144         }
9145       else if (unformat (i, "del"))
9146         is_add = 0;
9147       else
9148         break;
9149     }
9150
9151   if (rx_sw_if_index_set == 0)
9152     {
9153       errmsg ("missing rx interface name or rx_sw_if_index");
9154       return -99;
9155     }
9156
9157   if (tx_sw_if_index_set == 0)
9158     {
9159       errmsg ("missing tx interface name or tx_sw_if_index");
9160       return -99;
9161     }
9162
9163   M (L2_PATCH_ADD_DEL, mp);
9164
9165   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9166   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9167   mp->is_add = is_add;
9168
9169   S (mp);
9170   W (ret);
9171   return ret;
9172 }
9173
9174 u8 is_del;
9175 u8 localsid_addr[16];
9176 u8 end_psp;
9177 u8 behavior;
9178 u32 sw_if_index;
9179 u32 vlan_index;
9180 u32 fib_table;
9181 u8 nh_addr[16];
9182
9183 static int
9184 api_sr_localsid_add_del (vat_main_t * vam)
9185 {
9186   unformat_input_t *i = vam->input;
9187   vl_api_sr_localsid_add_del_t *mp;
9188
9189   u8 is_del;
9190   ip6_address_t localsid;
9191   u8 end_psp = 0;
9192   u8 behavior = ~0;
9193   u32 sw_if_index;
9194   u32 fib_table = ~(u32) 0;
9195   ip6_address_t next_hop;
9196
9197   bool nexthop_set = 0;
9198
9199   int ret;
9200
9201   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9202     {
9203       if (unformat (i, "del"))
9204         is_del = 1;
9205       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9206       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
9207         nexthop_set = 1;
9208       else if (unformat (i, "behavior %u", &behavior));
9209       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9210       else if (unformat (i, "fib-table %u", &fib_table));
9211       else if (unformat (i, "end.psp %u", &behavior));
9212       else
9213         break;
9214     }
9215
9216   M (SR_LOCALSID_ADD_DEL, mp);
9217
9218   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
9219   if (nexthop_set)
9220     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
9221   mp->behavior = behavior;
9222   mp->sw_if_index = ntohl (sw_if_index);
9223   mp->fib_table = ntohl (fib_table);
9224   mp->end_psp = end_psp;
9225   mp->is_del = is_del;
9226
9227   S (mp);
9228   W (ret);
9229   return ret;
9230 }
9231
9232 static int
9233 api_ioam_enable (vat_main_t * vam)
9234 {
9235   unformat_input_t *input = vam->input;
9236   vl_api_ioam_enable_t *mp;
9237   u32 id = 0;
9238   int has_trace_option = 0;
9239   int has_pot_option = 0;
9240   int has_seqno_option = 0;
9241   int has_analyse_option = 0;
9242   int ret;
9243
9244   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9245     {
9246       if (unformat (input, "trace"))
9247         has_trace_option = 1;
9248       else if (unformat (input, "pot"))
9249         has_pot_option = 1;
9250       else if (unformat (input, "seqno"))
9251         has_seqno_option = 1;
9252       else if (unformat (input, "analyse"))
9253         has_analyse_option = 1;
9254       else
9255         break;
9256     }
9257   M (IOAM_ENABLE, mp);
9258   mp->id = htons (id);
9259   mp->seqno = has_seqno_option;
9260   mp->analyse = has_analyse_option;
9261   mp->pot_enable = has_pot_option;
9262   mp->trace_enable = has_trace_option;
9263
9264   S (mp);
9265   W (ret);
9266   return ret;
9267 }
9268
9269
9270 static int
9271 api_ioam_disable (vat_main_t * vam)
9272 {
9273   vl_api_ioam_disable_t *mp;
9274   int ret;
9275
9276   M (IOAM_DISABLE, mp);
9277   S (mp);
9278   W (ret);
9279   return ret;
9280 }
9281
9282 #define foreach_tcp_proto_field                 \
9283 _(src_port)                                     \
9284 _(dst_port)
9285
9286 #define foreach_udp_proto_field                 \
9287 _(src_port)                                     \
9288 _(dst_port)
9289
9290 #define foreach_ip4_proto_field                 \
9291 _(src_address)                                  \
9292 _(dst_address)                                  \
9293 _(tos)                                          \
9294 _(length)                                       \
9295 _(fragment_id)                                  \
9296 _(ttl)                                          \
9297 _(protocol)                                     \
9298 _(checksum)
9299
9300 typedef struct
9301 {
9302   u16 src_port, dst_port;
9303 } tcpudp_header_t;
9304
9305 #if VPP_API_TEST_BUILTIN == 0
9306 uword
9307 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9308 {
9309   u8 **maskp = va_arg (*args, u8 **);
9310   u8 *mask = 0;
9311   u8 found_something = 0;
9312   tcp_header_t *tcp;
9313
9314 #define _(a) u8 a=0;
9315   foreach_tcp_proto_field;
9316 #undef _
9317
9318   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9319     {
9320       if (0);
9321 #define _(a) else if (unformat (input, #a)) a=1;
9322       foreach_tcp_proto_field
9323 #undef _
9324         else
9325         break;
9326     }
9327
9328 #define _(a) found_something += a;
9329   foreach_tcp_proto_field;
9330 #undef _
9331
9332   if (found_something == 0)
9333     return 0;
9334
9335   vec_validate (mask, sizeof (*tcp) - 1);
9336
9337   tcp = (tcp_header_t *) mask;
9338
9339 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
9340   foreach_tcp_proto_field;
9341 #undef _
9342
9343   *maskp = mask;
9344   return 1;
9345 }
9346
9347 uword
9348 unformat_udp_mask (unformat_input_t * input, va_list * args)
9349 {
9350   u8 **maskp = va_arg (*args, u8 **);
9351   u8 *mask = 0;
9352   u8 found_something = 0;
9353   udp_header_t *udp;
9354
9355 #define _(a) u8 a=0;
9356   foreach_udp_proto_field;
9357 #undef _
9358
9359   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9360     {
9361       if (0);
9362 #define _(a) else if (unformat (input, #a)) a=1;
9363       foreach_udp_proto_field
9364 #undef _
9365         else
9366         break;
9367     }
9368
9369 #define _(a) found_something += a;
9370   foreach_udp_proto_field;
9371 #undef _
9372
9373   if (found_something == 0)
9374     return 0;
9375
9376   vec_validate (mask, sizeof (*udp) - 1);
9377
9378   udp = (udp_header_t *) mask;
9379
9380 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
9381   foreach_udp_proto_field;
9382 #undef _
9383
9384   *maskp = mask;
9385   return 1;
9386 }
9387
9388 uword
9389 unformat_l4_mask (unformat_input_t * input, va_list * args)
9390 {
9391   u8 **maskp = va_arg (*args, u8 **);
9392   u16 src_port = 0, dst_port = 0;
9393   tcpudp_header_t *tcpudp;
9394
9395   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9396     {
9397       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9398         return 1;
9399       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9400         return 1;
9401       else if (unformat (input, "src_port"))
9402         src_port = 0xFFFF;
9403       else if (unformat (input, "dst_port"))
9404         dst_port = 0xFFFF;
9405       else
9406         return 0;
9407     }
9408
9409   if (!src_port && !dst_port)
9410     return 0;
9411
9412   u8 *mask = 0;
9413   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9414
9415   tcpudp = (tcpudp_header_t *) mask;
9416   tcpudp->src_port = src_port;
9417   tcpudp->dst_port = dst_port;
9418
9419   *maskp = mask;
9420
9421   return 1;
9422 }
9423
9424 uword
9425 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9426 {
9427   u8 **maskp = va_arg (*args, u8 **);
9428   u8 *mask = 0;
9429   u8 found_something = 0;
9430   ip4_header_t *ip;
9431
9432 #define _(a) u8 a=0;
9433   foreach_ip4_proto_field;
9434 #undef _
9435   u8 version = 0;
9436   u8 hdr_length = 0;
9437
9438
9439   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9440     {
9441       if (unformat (input, "version"))
9442         version = 1;
9443       else if (unformat (input, "hdr_length"))
9444         hdr_length = 1;
9445       else if (unformat (input, "src"))
9446         src_address = 1;
9447       else if (unformat (input, "dst"))
9448         dst_address = 1;
9449       else if (unformat (input, "proto"))
9450         protocol = 1;
9451
9452 #define _(a) else if (unformat (input, #a)) a=1;
9453       foreach_ip4_proto_field
9454 #undef _
9455         else
9456         break;
9457     }
9458
9459 #define _(a) found_something += a;
9460   foreach_ip4_proto_field;
9461 #undef _
9462
9463   if (found_something == 0)
9464     return 0;
9465
9466   vec_validate (mask, sizeof (*ip) - 1);
9467
9468   ip = (ip4_header_t *) mask;
9469
9470 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9471   foreach_ip4_proto_field;
9472 #undef _
9473
9474   ip->ip_version_and_header_length = 0;
9475
9476   if (version)
9477     ip->ip_version_and_header_length |= 0xF0;
9478
9479   if (hdr_length)
9480     ip->ip_version_and_header_length |= 0x0F;
9481
9482   *maskp = mask;
9483   return 1;
9484 }
9485
9486 #define foreach_ip6_proto_field                 \
9487 _(src_address)                                  \
9488 _(dst_address)                                  \
9489 _(payload_length)                               \
9490 _(hop_limit)                                    \
9491 _(protocol)
9492
9493 uword
9494 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9495 {
9496   u8 **maskp = va_arg (*args, u8 **);
9497   u8 *mask = 0;
9498   u8 found_something = 0;
9499   ip6_header_t *ip;
9500   u32 ip_version_traffic_class_and_flow_label;
9501
9502 #define _(a) u8 a=0;
9503   foreach_ip6_proto_field;
9504 #undef _
9505   u8 version = 0;
9506   u8 traffic_class = 0;
9507   u8 flow_label = 0;
9508
9509   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9510     {
9511       if (unformat (input, "version"))
9512         version = 1;
9513       else if (unformat (input, "traffic-class"))
9514         traffic_class = 1;
9515       else if (unformat (input, "flow-label"))
9516         flow_label = 1;
9517       else if (unformat (input, "src"))
9518         src_address = 1;
9519       else if (unformat (input, "dst"))
9520         dst_address = 1;
9521       else if (unformat (input, "proto"))
9522         protocol = 1;
9523
9524 #define _(a) else if (unformat (input, #a)) a=1;
9525       foreach_ip6_proto_field
9526 #undef _
9527         else
9528         break;
9529     }
9530
9531 #define _(a) found_something += a;
9532   foreach_ip6_proto_field;
9533 #undef _
9534
9535   if (found_something == 0)
9536     return 0;
9537
9538   vec_validate (mask, sizeof (*ip) - 1);
9539
9540   ip = (ip6_header_t *) mask;
9541
9542 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9543   foreach_ip6_proto_field;
9544 #undef _
9545
9546   ip_version_traffic_class_and_flow_label = 0;
9547
9548   if (version)
9549     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9550
9551   if (traffic_class)
9552     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9553
9554   if (flow_label)
9555     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9556
9557   ip->ip_version_traffic_class_and_flow_label =
9558     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9559
9560   *maskp = mask;
9561   return 1;
9562 }
9563
9564 uword
9565 unformat_l3_mask (unformat_input_t * input, va_list * args)
9566 {
9567   u8 **maskp = va_arg (*args, u8 **);
9568
9569   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9570     {
9571       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9572         return 1;
9573       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9574         return 1;
9575       else
9576         break;
9577     }
9578   return 0;
9579 }
9580
9581 uword
9582 unformat_l2_mask (unformat_input_t * input, va_list * args)
9583 {
9584   u8 **maskp = va_arg (*args, u8 **);
9585   u8 *mask = 0;
9586   u8 src = 0;
9587   u8 dst = 0;
9588   u8 proto = 0;
9589   u8 tag1 = 0;
9590   u8 tag2 = 0;
9591   u8 ignore_tag1 = 0;
9592   u8 ignore_tag2 = 0;
9593   u8 cos1 = 0;
9594   u8 cos2 = 0;
9595   u8 dot1q = 0;
9596   u8 dot1ad = 0;
9597   int len = 14;
9598
9599   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9600     {
9601       if (unformat (input, "src"))
9602         src = 1;
9603       else if (unformat (input, "dst"))
9604         dst = 1;
9605       else if (unformat (input, "proto"))
9606         proto = 1;
9607       else if (unformat (input, "tag1"))
9608         tag1 = 1;
9609       else if (unformat (input, "tag2"))
9610         tag2 = 1;
9611       else if (unformat (input, "ignore-tag1"))
9612         ignore_tag1 = 1;
9613       else if (unformat (input, "ignore-tag2"))
9614         ignore_tag2 = 1;
9615       else if (unformat (input, "cos1"))
9616         cos1 = 1;
9617       else if (unformat (input, "cos2"))
9618         cos2 = 1;
9619       else if (unformat (input, "dot1q"))
9620         dot1q = 1;
9621       else if (unformat (input, "dot1ad"))
9622         dot1ad = 1;
9623       else
9624         break;
9625     }
9626   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9627        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9628     return 0;
9629
9630   if (tag1 || ignore_tag1 || cos1 || dot1q)
9631     len = 18;
9632   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9633     len = 22;
9634
9635   vec_validate (mask, len - 1);
9636
9637   if (dst)
9638     memset (mask, 0xff, 6);
9639
9640   if (src)
9641     memset (mask + 6, 0xff, 6);
9642
9643   if (tag2 || dot1ad)
9644     {
9645       /* inner vlan tag */
9646       if (tag2)
9647         {
9648           mask[19] = 0xff;
9649           mask[18] = 0x0f;
9650         }
9651       if (cos2)
9652         mask[18] |= 0xe0;
9653       if (proto)
9654         mask[21] = mask[20] = 0xff;
9655       if (tag1)
9656         {
9657           mask[15] = 0xff;
9658           mask[14] = 0x0f;
9659         }
9660       if (cos1)
9661         mask[14] |= 0xe0;
9662       *maskp = mask;
9663       return 1;
9664     }
9665   if (tag1 | dot1q)
9666     {
9667       if (tag1)
9668         {
9669           mask[15] = 0xff;
9670           mask[14] = 0x0f;
9671         }
9672       if (cos1)
9673         mask[14] |= 0xe0;
9674       if (proto)
9675         mask[16] = mask[17] = 0xff;
9676
9677       *maskp = mask;
9678       return 1;
9679     }
9680   if (cos2)
9681     mask[18] |= 0xe0;
9682   if (cos1)
9683     mask[14] |= 0xe0;
9684   if (proto)
9685     mask[12] = mask[13] = 0xff;
9686
9687   *maskp = mask;
9688   return 1;
9689 }
9690
9691 uword
9692 unformat_classify_mask (unformat_input_t * input, va_list * args)
9693 {
9694   u8 **maskp = va_arg (*args, u8 **);
9695   u32 *skipp = va_arg (*args, u32 *);
9696   u32 *matchp = va_arg (*args, u32 *);
9697   u32 match;
9698   u8 *mask = 0;
9699   u8 *l2 = 0;
9700   u8 *l3 = 0;
9701   u8 *l4 = 0;
9702   int i;
9703
9704   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9705     {
9706       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9707         ;
9708       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9709         ;
9710       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9711         ;
9712       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9713         ;
9714       else
9715         break;
9716     }
9717
9718   if (l4 && !l3)
9719     {
9720       vec_free (mask);
9721       vec_free (l2);
9722       vec_free (l4);
9723       return 0;
9724     }
9725
9726   if (mask || l2 || l3 || l4)
9727     {
9728       if (l2 || l3 || l4)
9729         {
9730           /* "With a free Ethernet header in every package" */
9731           if (l2 == 0)
9732             vec_validate (l2, 13);
9733           mask = l2;
9734           if (vec_len (l3))
9735             {
9736               vec_append (mask, l3);
9737               vec_free (l3);
9738             }
9739           if (vec_len (l4))
9740             {
9741               vec_append (mask, l4);
9742               vec_free (l4);
9743             }
9744         }
9745
9746       /* Scan forward looking for the first significant mask octet */
9747       for (i = 0; i < vec_len (mask); i++)
9748         if (mask[i])
9749           break;
9750
9751       /* compute (skip, match) params */
9752       *skipp = i / sizeof (u32x4);
9753       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9754
9755       /* Pad mask to an even multiple of the vector size */
9756       while (vec_len (mask) % sizeof (u32x4))
9757         vec_add1 (mask, 0);
9758
9759       match = vec_len (mask) / sizeof (u32x4);
9760
9761       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9762         {
9763           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9764           if (*tmp || *(tmp + 1))
9765             break;
9766           match--;
9767         }
9768       if (match == 0)
9769         clib_warning ("BUG: match 0");
9770
9771       _vec_len (mask) = match * sizeof (u32x4);
9772
9773       *matchp = match;
9774       *maskp = mask;
9775
9776       return 1;
9777     }
9778
9779   return 0;
9780 }
9781 #endif /* VPP_API_TEST_BUILTIN */
9782
9783 #define foreach_l2_next                         \
9784 _(drop, DROP)                                   \
9785 _(ethernet, ETHERNET_INPUT)                     \
9786 _(ip4, IP4_INPUT)                               \
9787 _(ip6, IP6_INPUT)
9788
9789 uword
9790 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9791 {
9792   u32 *miss_next_indexp = va_arg (*args, u32 *);
9793   u32 next_index = 0;
9794   u32 tmp;
9795
9796 #define _(n,N) \
9797   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9798   foreach_l2_next;
9799 #undef _
9800
9801   if (unformat (input, "%d", &tmp))
9802     {
9803       next_index = tmp;
9804       goto out;
9805     }
9806
9807   return 0;
9808
9809 out:
9810   *miss_next_indexp = next_index;
9811   return 1;
9812 }
9813
9814 #define foreach_ip_next                         \
9815 _(drop, DROP)                                   \
9816 _(local, LOCAL)                                 \
9817 _(rewrite, REWRITE)
9818
9819 uword
9820 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9821 {
9822   u32 *miss_next_indexp = va_arg (*args, u32 *);
9823   u32 next_index = 0;
9824   u32 tmp;
9825
9826 #define _(n,N) \
9827   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9828   foreach_ip_next;
9829 #undef _
9830
9831   if (unformat (input, "%d", &tmp))
9832     {
9833       next_index = tmp;
9834       goto out;
9835     }
9836
9837   return 0;
9838
9839 out:
9840   *miss_next_indexp = next_index;
9841   return 1;
9842 }
9843
9844 #define foreach_acl_next                        \
9845 _(deny, DENY)
9846
9847 uword
9848 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9849 {
9850   u32 *miss_next_indexp = va_arg (*args, u32 *);
9851   u32 next_index = 0;
9852   u32 tmp;
9853
9854 #define _(n,N) \
9855   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9856   foreach_acl_next;
9857 #undef _
9858
9859   if (unformat (input, "permit"))
9860     {
9861       next_index = ~0;
9862       goto out;
9863     }
9864   else if (unformat (input, "%d", &tmp))
9865     {
9866       next_index = tmp;
9867       goto out;
9868     }
9869
9870   return 0;
9871
9872 out:
9873   *miss_next_indexp = next_index;
9874   return 1;
9875 }
9876
9877 uword
9878 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9879 {
9880   u32 *r = va_arg (*args, u32 *);
9881
9882   if (unformat (input, "conform-color"))
9883     *r = POLICE_CONFORM;
9884   else if (unformat (input, "exceed-color"))
9885     *r = POLICE_EXCEED;
9886   else
9887     return 0;
9888
9889   return 1;
9890 }
9891
9892 static int
9893 api_classify_add_del_table (vat_main_t * vam)
9894 {
9895   unformat_input_t *i = vam->input;
9896   vl_api_classify_add_del_table_t *mp;
9897
9898   u32 nbuckets = 2;
9899   u32 skip = ~0;
9900   u32 match = ~0;
9901   int is_add = 1;
9902   int del_chain = 0;
9903   u32 table_index = ~0;
9904   u32 next_table_index = ~0;
9905   u32 miss_next_index = ~0;
9906   u32 memory_size = 32 << 20;
9907   u8 *mask = 0;
9908   u32 current_data_flag = 0;
9909   int current_data_offset = 0;
9910   int ret;
9911
9912   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9913     {
9914       if (unformat (i, "del"))
9915         is_add = 0;
9916       else if (unformat (i, "del-chain"))
9917         {
9918           is_add = 0;
9919           del_chain = 1;
9920         }
9921       else if (unformat (i, "buckets %d", &nbuckets))
9922         ;
9923       else if (unformat (i, "memory_size %d", &memory_size))
9924         ;
9925       else if (unformat (i, "skip %d", &skip))
9926         ;
9927       else if (unformat (i, "match %d", &match))
9928         ;
9929       else if (unformat (i, "table %d", &table_index))
9930         ;
9931       else if (unformat (i, "mask %U", unformat_classify_mask,
9932                          &mask, &skip, &match))
9933         ;
9934       else if (unformat (i, "next-table %d", &next_table_index))
9935         ;
9936       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
9937                          &miss_next_index))
9938         ;
9939       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
9940                          &miss_next_index))
9941         ;
9942       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
9943                          &miss_next_index))
9944         ;
9945       else if (unformat (i, "current-data-flag %d", &current_data_flag))
9946         ;
9947       else if (unformat (i, "current-data-offset %d", &current_data_offset))
9948         ;
9949       else
9950         break;
9951     }
9952
9953   if (is_add && mask == 0)
9954     {
9955       errmsg ("Mask required");
9956       return -99;
9957     }
9958
9959   if (is_add && skip == ~0)
9960     {
9961       errmsg ("skip count required");
9962       return -99;
9963     }
9964
9965   if (is_add && match == ~0)
9966     {
9967       errmsg ("match count required");
9968       return -99;
9969     }
9970
9971   if (!is_add && table_index == ~0)
9972     {
9973       errmsg ("table index required for delete");
9974       return -99;
9975     }
9976
9977   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
9978
9979   mp->is_add = is_add;
9980   mp->del_chain = del_chain;
9981   mp->table_index = ntohl (table_index);
9982   mp->nbuckets = ntohl (nbuckets);
9983   mp->memory_size = ntohl (memory_size);
9984   mp->skip_n_vectors = ntohl (skip);
9985   mp->match_n_vectors = ntohl (match);
9986   mp->next_table_index = ntohl (next_table_index);
9987   mp->miss_next_index = ntohl (miss_next_index);
9988   mp->current_data_flag = ntohl (current_data_flag);
9989   mp->current_data_offset = ntohl (current_data_offset);
9990   clib_memcpy (mp->mask, mask, vec_len (mask));
9991
9992   vec_free (mask);
9993
9994   S (mp);
9995   W (ret);
9996   return ret;
9997 }
9998
9999 #if VPP_API_TEST_BUILTIN == 0
10000 uword
10001 unformat_l4_match (unformat_input_t * input, va_list * args)
10002 {
10003   u8 **matchp = va_arg (*args, u8 **);
10004
10005   u8 *proto_header = 0;
10006   int src_port = 0;
10007   int dst_port = 0;
10008
10009   tcpudp_header_t h;
10010
10011   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10012     {
10013       if (unformat (input, "src_port %d", &src_port))
10014         ;
10015       else if (unformat (input, "dst_port %d", &dst_port))
10016         ;
10017       else
10018         return 0;
10019     }
10020
10021   h.src_port = clib_host_to_net_u16 (src_port);
10022   h.dst_port = clib_host_to_net_u16 (dst_port);
10023   vec_validate (proto_header, sizeof (h) - 1);
10024   memcpy (proto_header, &h, sizeof (h));
10025
10026   *matchp = proto_header;
10027
10028   return 1;
10029 }
10030
10031 uword
10032 unformat_ip4_match (unformat_input_t * input, va_list * args)
10033 {
10034   u8 **matchp = va_arg (*args, u8 **);
10035   u8 *match = 0;
10036   ip4_header_t *ip;
10037   int version = 0;
10038   u32 version_val;
10039   int hdr_length = 0;
10040   u32 hdr_length_val;
10041   int src = 0, dst = 0;
10042   ip4_address_t src_val, dst_val;
10043   int proto = 0;
10044   u32 proto_val;
10045   int tos = 0;
10046   u32 tos_val;
10047   int length = 0;
10048   u32 length_val;
10049   int fragment_id = 0;
10050   u32 fragment_id_val;
10051   int ttl = 0;
10052   int ttl_val;
10053   int checksum = 0;
10054   u32 checksum_val;
10055
10056   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10057     {
10058       if (unformat (input, "version %d", &version_val))
10059         version = 1;
10060       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10061         hdr_length = 1;
10062       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10063         src = 1;
10064       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10065         dst = 1;
10066       else if (unformat (input, "proto %d", &proto_val))
10067         proto = 1;
10068       else if (unformat (input, "tos %d", &tos_val))
10069         tos = 1;
10070       else if (unformat (input, "length %d", &length_val))
10071         length = 1;
10072       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10073         fragment_id = 1;
10074       else if (unformat (input, "ttl %d", &ttl_val))
10075         ttl = 1;
10076       else if (unformat (input, "checksum %d", &checksum_val))
10077         checksum = 1;
10078       else
10079         break;
10080     }
10081
10082   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10083       + ttl + checksum == 0)
10084     return 0;
10085
10086   /*
10087    * Aligned because we use the real comparison functions
10088    */
10089   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10090
10091   ip = (ip4_header_t *) match;
10092
10093   /* These are realistically matched in practice */
10094   if (src)
10095     ip->src_address.as_u32 = src_val.as_u32;
10096
10097   if (dst)
10098     ip->dst_address.as_u32 = dst_val.as_u32;
10099
10100   if (proto)
10101     ip->protocol = proto_val;
10102
10103
10104   /* These are not, but they're included for completeness */
10105   if (version)
10106     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10107
10108   if (hdr_length)
10109     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10110
10111   if (tos)
10112     ip->tos = tos_val;
10113
10114   if (length)
10115     ip->length = clib_host_to_net_u16 (length_val);
10116
10117   if (ttl)
10118     ip->ttl = ttl_val;
10119
10120   if (checksum)
10121     ip->checksum = clib_host_to_net_u16 (checksum_val);
10122
10123   *matchp = match;
10124   return 1;
10125 }
10126
10127 uword
10128 unformat_ip6_match (unformat_input_t * input, va_list * args)
10129 {
10130   u8 **matchp = va_arg (*args, u8 **);
10131   u8 *match = 0;
10132   ip6_header_t *ip;
10133   int version = 0;
10134   u32 version_val;
10135   u8 traffic_class = 0;
10136   u32 traffic_class_val = 0;
10137   u8 flow_label = 0;
10138   u8 flow_label_val;
10139   int src = 0, dst = 0;
10140   ip6_address_t src_val, dst_val;
10141   int proto = 0;
10142   u32 proto_val;
10143   int payload_length = 0;
10144   u32 payload_length_val;
10145   int hop_limit = 0;
10146   int hop_limit_val;
10147   u32 ip_version_traffic_class_and_flow_label;
10148
10149   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10150     {
10151       if (unformat (input, "version %d", &version_val))
10152         version = 1;
10153       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10154         traffic_class = 1;
10155       else if (unformat (input, "flow_label %d", &flow_label_val))
10156         flow_label = 1;
10157       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10158         src = 1;
10159       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10160         dst = 1;
10161       else if (unformat (input, "proto %d", &proto_val))
10162         proto = 1;
10163       else if (unformat (input, "payload_length %d", &payload_length_val))
10164         payload_length = 1;
10165       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10166         hop_limit = 1;
10167       else
10168         break;
10169     }
10170
10171   if (version + traffic_class + flow_label + src + dst + proto +
10172       payload_length + hop_limit == 0)
10173     return 0;
10174
10175   /*
10176    * Aligned because we use the real comparison functions
10177    */
10178   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10179
10180   ip = (ip6_header_t *) match;
10181
10182   if (src)
10183     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10184
10185   if (dst)
10186     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10187
10188   if (proto)
10189     ip->protocol = proto_val;
10190
10191   ip_version_traffic_class_and_flow_label = 0;
10192
10193   if (version)
10194     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10195
10196   if (traffic_class)
10197     ip_version_traffic_class_and_flow_label |=
10198       (traffic_class_val & 0xFF) << 20;
10199
10200   if (flow_label)
10201     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10202
10203   ip->ip_version_traffic_class_and_flow_label =
10204     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10205
10206   if (payload_length)
10207     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10208
10209   if (hop_limit)
10210     ip->hop_limit = hop_limit_val;
10211
10212   *matchp = match;
10213   return 1;
10214 }
10215
10216 uword
10217 unformat_l3_match (unformat_input_t * input, va_list * args)
10218 {
10219   u8 **matchp = va_arg (*args, u8 **);
10220
10221   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10222     {
10223       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10224         return 1;
10225       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10226         return 1;
10227       else
10228         break;
10229     }
10230   return 0;
10231 }
10232
10233 uword
10234 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10235 {
10236   u8 *tagp = va_arg (*args, u8 *);
10237   u32 tag;
10238
10239   if (unformat (input, "%d", &tag))
10240     {
10241       tagp[0] = (tag >> 8) & 0x0F;
10242       tagp[1] = tag & 0xFF;
10243       return 1;
10244     }
10245
10246   return 0;
10247 }
10248
10249 uword
10250 unformat_l2_match (unformat_input_t * input, va_list * args)
10251 {
10252   u8 **matchp = va_arg (*args, u8 **);
10253   u8 *match = 0;
10254   u8 src = 0;
10255   u8 src_val[6];
10256   u8 dst = 0;
10257   u8 dst_val[6];
10258   u8 proto = 0;
10259   u16 proto_val;
10260   u8 tag1 = 0;
10261   u8 tag1_val[2];
10262   u8 tag2 = 0;
10263   u8 tag2_val[2];
10264   int len = 14;
10265   u8 ignore_tag1 = 0;
10266   u8 ignore_tag2 = 0;
10267   u8 cos1 = 0;
10268   u8 cos2 = 0;
10269   u32 cos1_val = 0;
10270   u32 cos2_val = 0;
10271
10272   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10273     {
10274       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10275         src = 1;
10276       else
10277         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10278         dst = 1;
10279       else if (unformat (input, "proto %U",
10280                          unformat_ethernet_type_host_byte_order, &proto_val))
10281         proto = 1;
10282       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10283         tag1 = 1;
10284       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10285         tag2 = 1;
10286       else if (unformat (input, "ignore-tag1"))
10287         ignore_tag1 = 1;
10288       else if (unformat (input, "ignore-tag2"))
10289         ignore_tag2 = 1;
10290       else if (unformat (input, "cos1 %d", &cos1_val))
10291         cos1 = 1;
10292       else if (unformat (input, "cos2 %d", &cos2_val))
10293         cos2 = 1;
10294       else
10295         break;
10296     }
10297   if ((src + dst + proto + tag1 + tag2 +
10298        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10299     return 0;
10300
10301   if (tag1 || ignore_tag1 || cos1)
10302     len = 18;
10303   if (tag2 || ignore_tag2 || cos2)
10304     len = 22;
10305
10306   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10307
10308   if (dst)
10309     clib_memcpy (match, dst_val, 6);
10310
10311   if (src)
10312     clib_memcpy (match + 6, src_val, 6);
10313
10314   if (tag2)
10315     {
10316       /* inner vlan tag */
10317       match[19] = tag2_val[1];
10318       match[18] = tag2_val[0];
10319       if (cos2)
10320         match[18] |= (cos2_val & 0x7) << 5;
10321       if (proto)
10322         {
10323           match[21] = proto_val & 0xff;
10324           match[20] = proto_val >> 8;
10325         }
10326       if (tag1)
10327         {
10328           match[15] = tag1_val[1];
10329           match[14] = tag1_val[0];
10330         }
10331       if (cos1)
10332         match[14] |= (cos1_val & 0x7) << 5;
10333       *matchp = match;
10334       return 1;
10335     }
10336   if (tag1)
10337     {
10338       match[15] = tag1_val[1];
10339       match[14] = tag1_val[0];
10340       if (proto)
10341         {
10342           match[17] = proto_val & 0xff;
10343           match[16] = proto_val >> 8;
10344         }
10345       if (cos1)
10346         match[14] |= (cos1_val & 0x7) << 5;
10347
10348       *matchp = match;
10349       return 1;
10350     }
10351   if (cos2)
10352     match[18] |= (cos2_val & 0x7) << 5;
10353   if (cos1)
10354     match[14] |= (cos1_val & 0x7) << 5;
10355   if (proto)
10356     {
10357       match[13] = proto_val & 0xff;
10358       match[12] = proto_val >> 8;
10359     }
10360
10361   *matchp = match;
10362   return 1;
10363 }
10364 #endif
10365
10366 uword
10367 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10368 {
10369   u8 **matchp = va_arg (*args, u8 **);
10370   u32 skip_n_vectors = va_arg (*args, u32);
10371   u32 match_n_vectors = va_arg (*args, u32);
10372
10373   u8 *match = 0;
10374   u8 *l2 = 0;
10375   u8 *l3 = 0;
10376   u8 *l4 = 0;
10377
10378   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10379     {
10380       if (unformat (input, "hex %U", unformat_hex_string, &match))
10381         ;
10382       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10383         ;
10384       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10385         ;
10386       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10387         ;
10388       else
10389         break;
10390     }
10391
10392   if (l4 && !l3)
10393     {
10394       vec_free (match);
10395       vec_free (l2);
10396       vec_free (l4);
10397       return 0;
10398     }
10399
10400   if (match || l2 || l3 || l4)
10401     {
10402       if (l2 || l3 || l4)
10403         {
10404           /* "Win a free Ethernet header in every packet" */
10405           if (l2 == 0)
10406             vec_validate_aligned (l2, 13, sizeof (u32x4));
10407           match = l2;
10408           if (vec_len (l3))
10409             {
10410               vec_append_aligned (match, l3, sizeof (u32x4));
10411               vec_free (l3);
10412             }
10413           if (vec_len (l4))
10414             {
10415               vec_append_aligned (match, l4, sizeof (u32x4));
10416               vec_free (l4);
10417             }
10418         }
10419
10420       /* Make sure the vector is big enough even if key is all 0's */
10421       vec_validate_aligned
10422         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10423          sizeof (u32x4));
10424
10425       /* Set size, include skipped vectors */
10426       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10427
10428       *matchp = match;
10429
10430       return 1;
10431     }
10432
10433   return 0;
10434 }
10435
10436 static int
10437 api_classify_add_del_session (vat_main_t * vam)
10438 {
10439   unformat_input_t *i = vam->input;
10440   vl_api_classify_add_del_session_t *mp;
10441   int is_add = 1;
10442   u32 table_index = ~0;
10443   u32 hit_next_index = ~0;
10444   u32 opaque_index = ~0;
10445   u8 *match = 0;
10446   i32 advance = 0;
10447   u32 skip_n_vectors = 0;
10448   u32 match_n_vectors = 0;
10449   u32 action = 0;
10450   u32 metadata = 0;
10451   int ret;
10452
10453   /*
10454    * Warning: you have to supply skip_n and match_n
10455    * because the API client cant simply look at the classify
10456    * table object.
10457    */
10458
10459   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10460     {
10461       if (unformat (i, "del"))
10462         is_add = 0;
10463       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10464                          &hit_next_index))
10465         ;
10466       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10467                          &hit_next_index))
10468         ;
10469       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10470                          &hit_next_index))
10471         ;
10472       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10473         ;
10474       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10475         ;
10476       else if (unformat (i, "opaque-index %d", &opaque_index))
10477         ;
10478       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10479         ;
10480       else if (unformat (i, "match_n %d", &match_n_vectors))
10481         ;
10482       else if (unformat (i, "match %U", api_unformat_classify_match,
10483                          &match, skip_n_vectors, match_n_vectors))
10484         ;
10485       else if (unformat (i, "advance %d", &advance))
10486         ;
10487       else if (unformat (i, "table-index %d", &table_index))
10488         ;
10489       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10490         action = 1;
10491       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10492         action = 2;
10493       else if (unformat (i, "action %d", &action))
10494         ;
10495       else if (unformat (i, "metadata %d", &metadata))
10496         ;
10497       else
10498         break;
10499     }
10500
10501   if (table_index == ~0)
10502     {
10503       errmsg ("Table index required");
10504       return -99;
10505     }
10506
10507   if (is_add && match == 0)
10508     {
10509       errmsg ("Match value required");
10510       return -99;
10511     }
10512
10513   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10514
10515   mp->is_add = is_add;
10516   mp->table_index = ntohl (table_index);
10517   mp->hit_next_index = ntohl (hit_next_index);
10518   mp->opaque_index = ntohl (opaque_index);
10519   mp->advance = ntohl (advance);
10520   mp->action = action;
10521   mp->metadata = ntohl (metadata);
10522   clib_memcpy (mp->match, match, vec_len (match));
10523   vec_free (match);
10524
10525   S (mp);
10526   W (ret);
10527   return ret;
10528 }
10529
10530 static int
10531 api_classify_set_interface_ip_table (vat_main_t * vam)
10532 {
10533   unformat_input_t *i = vam->input;
10534   vl_api_classify_set_interface_ip_table_t *mp;
10535   u32 sw_if_index;
10536   int sw_if_index_set;
10537   u32 table_index = ~0;
10538   u8 is_ipv6 = 0;
10539   int ret;
10540
10541   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10542     {
10543       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10544         sw_if_index_set = 1;
10545       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10546         sw_if_index_set = 1;
10547       else if (unformat (i, "table %d", &table_index))
10548         ;
10549       else
10550         {
10551           clib_warning ("parse error '%U'", format_unformat_error, i);
10552           return -99;
10553         }
10554     }
10555
10556   if (sw_if_index_set == 0)
10557     {
10558       errmsg ("missing interface name or sw_if_index");
10559       return -99;
10560     }
10561
10562
10563   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10564
10565   mp->sw_if_index = ntohl (sw_if_index);
10566   mp->table_index = ntohl (table_index);
10567   mp->is_ipv6 = is_ipv6;
10568
10569   S (mp);
10570   W (ret);
10571   return ret;
10572 }
10573
10574 static int
10575 api_classify_set_interface_l2_tables (vat_main_t * vam)
10576 {
10577   unformat_input_t *i = vam->input;
10578   vl_api_classify_set_interface_l2_tables_t *mp;
10579   u32 sw_if_index;
10580   int sw_if_index_set;
10581   u32 ip4_table_index = ~0;
10582   u32 ip6_table_index = ~0;
10583   u32 other_table_index = ~0;
10584   u32 is_input = 1;
10585   int ret;
10586
10587   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10588     {
10589       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10590         sw_if_index_set = 1;
10591       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10592         sw_if_index_set = 1;
10593       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10594         ;
10595       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10596         ;
10597       else if (unformat (i, "other-table %d", &other_table_index))
10598         ;
10599       else if (unformat (i, "is-input %d", &is_input))
10600         ;
10601       else
10602         {
10603           clib_warning ("parse error '%U'", format_unformat_error, i);
10604           return -99;
10605         }
10606     }
10607
10608   if (sw_if_index_set == 0)
10609     {
10610       errmsg ("missing interface name or sw_if_index");
10611       return -99;
10612     }
10613
10614
10615   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10616
10617   mp->sw_if_index = ntohl (sw_if_index);
10618   mp->ip4_table_index = ntohl (ip4_table_index);
10619   mp->ip6_table_index = ntohl (ip6_table_index);
10620   mp->other_table_index = ntohl (other_table_index);
10621   mp->is_input = (u8) is_input;
10622
10623   S (mp);
10624   W (ret);
10625   return ret;
10626 }
10627
10628 static int
10629 api_set_ipfix_exporter (vat_main_t * vam)
10630 {
10631   unformat_input_t *i = vam->input;
10632   vl_api_set_ipfix_exporter_t *mp;
10633   ip4_address_t collector_address;
10634   u8 collector_address_set = 0;
10635   u32 collector_port = ~0;
10636   ip4_address_t src_address;
10637   u8 src_address_set = 0;
10638   u32 vrf_id = ~0;
10639   u32 path_mtu = ~0;
10640   u32 template_interval = ~0;
10641   u8 udp_checksum = 0;
10642   int ret;
10643
10644   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10645     {
10646       if (unformat (i, "collector_address %U", unformat_ip4_address,
10647                     &collector_address))
10648         collector_address_set = 1;
10649       else if (unformat (i, "collector_port %d", &collector_port))
10650         ;
10651       else if (unformat (i, "src_address %U", unformat_ip4_address,
10652                          &src_address))
10653         src_address_set = 1;
10654       else if (unformat (i, "vrf_id %d", &vrf_id))
10655         ;
10656       else if (unformat (i, "path_mtu %d", &path_mtu))
10657         ;
10658       else if (unformat (i, "template_interval %d", &template_interval))
10659         ;
10660       else if (unformat (i, "udp_checksum"))
10661         udp_checksum = 1;
10662       else
10663         break;
10664     }
10665
10666   if (collector_address_set == 0)
10667     {
10668       errmsg ("collector_address required");
10669       return -99;
10670     }
10671
10672   if (src_address_set == 0)
10673     {
10674       errmsg ("src_address required");
10675       return -99;
10676     }
10677
10678   M (SET_IPFIX_EXPORTER, mp);
10679
10680   memcpy (mp->collector_address, collector_address.data,
10681           sizeof (collector_address.data));
10682   mp->collector_port = htons ((u16) collector_port);
10683   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
10684   mp->vrf_id = htonl (vrf_id);
10685   mp->path_mtu = htonl (path_mtu);
10686   mp->template_interval = htonl (template_interval);
10687   mp->udp_checksum = udp_checksum;
10688
10689   S (mp);
10690   W (ret);
10691   return ret;
10692 }
10693
10694 static int
10695 api_set_ipfix_classify_stream (vat_main_t * vam)
10696 {
10697   unformat_input_t *i = vam->input;
10698   vl_api_set_ipfix_classify_stream_t *mp;
10699   u32 domain_id = 0;
10700   u32 src_port = UDP_DST_PORT_ipfix;
10701   int ret;
10702
10703   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10704     {
10705       if (unformat (i, "domain %d", &domain_id))
10706         ;
10707       else if (unformat (i, "src_port %d", &src_port))
10708         ;
10709       else
10710         {
10711           errmsg ("unknown input `%U'", format_unformat_error, i);
10712           return -99;
10713         }
10714     }
10715
10716   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10717
10718   mp->domain_id = htonl (domain_id);
10719   mp->src_port = htons ((u16) src_port);
10720
10721   S (mp);
10722   W (ret);
10723   return ret;
10724 }
10725
10726 static int
10727 api_ipfix_classify_table_add_del (vat_main_t * vam)
10728 {
10729   unformat_input_t *i = vam->input;
10730   vl_api_ipfix_classify_table_add_del_t *mp;
10731   int is_add = -1;
10732   u32 classify_table_index = ~0;
10733   u8 ip_version = 0;
10734   u8 transport_protocol = 255;
10735   int ret;
10736
10737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10738     {
10739       if (unformat (i, "add"))
10740         is_add = 1;
10741       else if (unformat (i, "del"))
10742         is_add = 0;
10743       else if (unformat (i, "table %d", &classify_table_index))
10744         ;
10745       else if (unformat (i, "ip4"))
10746         ip_version = 4;
10747       else if (unformat (i, "ip6"))
10748         ip_version = 6;
10749       else if (unformat (i, "tcp"))
10750         transport_protocol = 6;
10751       else if (unformat (i, "udp"))
10752         transport_protocol = 17;
10753       else
10754         {
10755           errmsg ("unknown input `%U'", format_unformat_error, i);
10756           return -99;
10757         }
10758     }
10759
10760   if (is_add == -1)
10761     {
10762       errmsg ("expecting: add|del");
10763       return -99;
10764     }
10765   if (classify_table_index == ~0)
10766     {
10767       errmsg ("classifier table not specified");
10768       return -99;
10769     }
10770   if (ip_version == 0)
10771     {
10772       errmsg ("IP version not specified");
10773       return -99;
10774     }
10775
10776   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10777
10778   mp->is_add = is_add;
10779   mp->table_id = htonl (classify_table_index);
10780   mp->ip_version = ip_version;
10781   mp->transport_protocol = transport_protocol;
10782
10783   S (mp);
10784   W (ret);
10785   return ret;
10786 }
10787
10788 static int
10789 api_get_node_index (vat_main_t * vam)
10790 {
10791   unformat_input_t *i = vam->input;
10792   vl_api_get_node_index_t *mp;
10793   u8 *name = 0;
10794   int ret;
10795
10796   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10797     {
10798       if (unformat (i, "node %s", &name))
10799         ;
10800       else
10801         break;
10802     }
10803   if (name == 0)
10804     {
10805       errmsg ("node name required");
10806       return -99;
10807     }
10808   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10809     {
10810       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10811       return -99;
10812     }
10813
10814   M (GET_NODE_INDEX, mp);
10815   clib_memcpy (mp->node_name, name, vec_len (name));
10816   vec_free (name);
10817
10818   S (mp);
10819   W (ret);
10820   return ret;
10821 }
10822
10823 static int
10824 api_get_next_index (vat_main_t * vam)
10825 {
10826   unformat_input_t *i = vam->input;
10827   vl_api_get_next_index_t *mp;
10828   u8 *node_name = 0, *next_node_name = 0;
10829   int ret;
10830
10831   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10832     {
10833       if (unformat (i, "node-name %s", &node_name))
10834         ;
10835       else if (unformat (i, "next-node-name %s", &next_node_name))
10836         break;
10837     }
10838
10839   if (node_name == 0)
10840     {
10841       errmsg ("node name required");
10842       return -99;
10843     }
10844   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10845     {
10846       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10847       return -99;
10848     }
10849
10850   if (next_node_name == 0)
10851     {
10852       errmsg ("next node name required");
10853       return -99;
10854     }
10855   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10856     {
10857       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10858       return -99;
10859     }
10860
10861   M (GET_NEXT_INDEX, mp);
10862   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10863   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10864   vec_free (node_name);
10865   vec_free (next_node_name);
10866
10867   S (mp);
10868   W (ret);
10869   return ret;
10870 }
10871
10872 static int
10873 api_add_node_next (vat_main_t * vam)
10874 {
10875   unformat_input_t *i = vam->input;
10876   vl_api_add_node_next_t *mp;
10877   u8 *name = 0;
10878   u8 *next = 0;
10879   int ret;
10880
10881   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10882     {
10883       if (unformat (i, "node %s", &name))
10884         ;
10885       else if (unformat (i, "next %s", &next))
10886         ;
10887       else
10888         break;
10889     }
10890   if (name == 0)
10891     {
10892       errmsg ("node name required");
10893       return -99;
10894     }
10895   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10896     {
10897       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10898       return -99;
10899     }
10900   if (next == 0)
10901     {
10902       errmsg ("next node required");
10903       return -99;
10904     }
10905   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10906     {
10907       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10908       return -99;
10909     }
10910
10911   M (ADD_NODE_NEXT, mp);
10912   clib_memcpy (mp->node_name, name, vec_len (name));
10913   clib_memcpy (mp->next_name, next, vec_len (next));
10914   vec_free (name);
10915   vec_free (next);
10916
10917   S (mp);
10918   W (ret);
10919   return ret;
10920 }
10921
10922 static int
10923 api_l2tpv3_create_tunnel (vat_main_t * vam)
10924 {
10925   unformat_input_t *i = vam->input;
10926   ip6_address_t client_address, our_address;
10927   int client_address_set = 0;
10928   int our_address_set = 0;
10929   u32 local_session_id = 0;
10930   u32 remote_session_id = 0;
10931   u64 local_cookie = 0;
10932   u64 remote_cookie = 0;
10933   u8 l2_sublayer_present = 0;
10934   vl_api_l2tpv3_create_tunnel_t *mp;
10935   int ret;
10936
10937   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10938     {
10939       if (unformat (i, "client_address %U", unformat_ip6_address,
10940                     &client_address))
10941         client_address_set = 1;
10942       else if (unformat (i, "our_address %U", unformat_ip6_address,
10943                          &our_address))
10944         our_address_set = 1;
10945       else if (unformat (i, "local_session_id %d", &local_session_id))
10946         ;
10947       else if (unformat (i, "remote_session_id %d", &remote_session_id))
10948         ;
10949       else if (unformat (i, "local_cookie %lld", &local_cookie))
10950         ;
10951       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10952         ;
10953       else if (unformat (i, "l2-sublayer-present"))
10954         l2_sublayer_present = 1;
10955       else
10956         break;
10957     }
10958
10959   if (client_address_set == 0)
10960     {
10961       errmsg ("client_address required");
10962       return -99;
10963     }
10964
10965   if (our_address_set == 0)
10966     {
10967       errmsg ("our_address required");
10968       return -99;
10969     }
10970
10971   M (L2TPV3_CREATE_TUNNEL, mp);
10972
10973   clib_memcpy (mp->client_address, client_address.as_u8,
10974                sizeof (mp->client_address));
10975
10976   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10977
10978   mp->local_session_id = ntohl (local_session_id);
10979   mp->remote_session_id = ntohl (remote_session_id);
10980   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10981   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10982   mp->l2_sublayer_present = l2_sublayer_present;
10983   mp->is_ipv6 = 1;
10984
10985   S (mp);
10986   W (ret);
10987   return ret;
10988 }
10989
10990 static int
10991 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10992 {
10993   unformat_input_t *i = vam->input;
10994   u32 sw_if_index;
10995   u8 sw_if_index_set = 0;
10996   u64 new_local_cookie = 0;
10997   u64 new_remote_cookie = 0;
10998   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10999   int ret;
11000
11001   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11002     {
11003       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11004         sw_if_index_set = 1;
11005       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11006         sw_if_index_set = 1;
11007       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11008         ;
11009       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11010         ;
11011       else
11012         break;
11013     }
11014
11015   if (sw_if_index_set == 0)
11016     {
11017       errmsg ("missing interface name or sw_if_index");
11018       return -99;
11019     }
11020
11021   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11022
11023   mp->sw_if_index = ntohl (sw_if_index);
11024   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11025   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11026
11027   S (mp);
11028   W (ret);
11029   return ret;
11030 }
11031
11032 static int
11033 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11034 {
11035   unformat_input_t *i = vam->input;
11036   vl_api_l2tpv3_interface_enable_disable_t *mp;
11037   u32 sw_if_index;
11038   u8 sw_if_index_set = 0;
11039   u8 enable_disable = 1;
11040   int ret;
11041
11042   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11043     {
11044       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11045         sw_if_index_set = 1;
11046       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11047         sw_if_index_set = 1;
11048       else if (unformat (i, "enable"))
11049         enable_disable = 1;
11050       else if (unformat (i, "disable"))
11051         enable_disable = 0;
11052       else
11053         break;
11054     }
11055
11056   if (sw_if_index_set == 0)
11057     {
11058       errmsg ("missing interface name or sw_if_index");
11059       return -99;
11060     }
11061
11062   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11063
11064   mp->sw_if_index = ntohl (sw_if_index);
11065   mp->enable_disable = enable_disable;
11066
11067   S (mp);
11068   W (ret);
11069   return ret;
11070 }
11071
11072 static int
11073 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11074 {
11075   unformat_input_t *i = vam->input;
11076   vl_api_l2tpv3_set_lookup_key_t *mp;
11077   u8 key = ~0;
11078   int ret;
11079
11080   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11081     {
11082       if (unformat (i, "lookup_v6_src"))
11083         key = L2T_LOOKUP_SRC_ADDRESS;
11084       else if (unformat (i, "lookup_v6_dst"))
11085         key = L2T_LOOKUP_DST_ADDRESS;
11086       else if (unformat (i, "lookup_session_id"))
11087         key = L2T_LOOKUP_SESSION_ID;
11088       else
11089         break;
11090     }
11091
11092   if (key == (u8) ~ 0)
11093     {
11094       errmsg ("l2tp session lookup key unset");
11095       return -99;
11096     }
11097
11098   M (L2TPV3_SET_LOOKUP_KEY, mp);
11099
11100   mp->key = key;
11101
11102   S (mp);
11103   W (ret);
11104   return ret;
11105 }
11106
11107 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11108   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11109 {
11110   vat_main_t *vam = &vat_main;
11111
11112   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11113          format_ip6_address, mp->our_address,
11114          format_ip6_address, mp->client_address,
11115          clib_net_to_host_u32 (mp->sw_if_index));
11116
11117   print (vam->ofp,
11118          "   local cookies %016llx %016llx remote cookie %016llx",
11119          clib_net_to_host_u64 (mp->local_cookie[0]),
11120          clib_net_to_host_u64 (mp->local_cookie[1]),
11121          clib_net_to_host_u64 (mp->remote_cookie));
11122
11123   print (vam->ofp, "   local session-id %d remote session-id %d",
11124          clib_net_to_host_u32 (mp->local_session_id),
11125          clib_net_to_host_u32 (mp->remote_session_id));
11126
11127   print (vam->ofp, "   l2 specific sublayer %s\n",
11128          mp->l2_sublayer_present ? "preset" : "absent");
11129
11130 }
11131
11132 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11133   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11134 {
11135   vat_main_t *vam = &vat_main;
11136   vat_json_node_t *node = NULL;
11137   struct in6_addr addr;
11138
11139   if (VAT_JSON_ARRAY != vam->json_tree.type)
11140     {
11141       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11142       vat_json_init_array (&vam->json_tree);
11143     }
11144   node = vat_json_array_add (&vam->json_tree);
11145
11146   vat_json_init_object (node);
11147
11148   clib_memcpy (&addr, mp->our_address, sizeof (addr));
11149   vat_json_object_add_ip6 (node, "our_address", addr);
11150   clib_memcpy (&addr, mp->client_address, sizeof (addr));
11151   vat_json_object_add_ip6 (node, "client_address", addr);
11152
11153   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11154   vat_json_init_array (lc);
11155   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11156   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11157   vat_json_object_add_uint (node, "remote_cookie",
11158                             clib_net_to_host_u64 (mp->remote_cookie));
11159
11160   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11161   vat_json_object_add_uint (node, "local_session_id",
11162                             clib_net_to_host_u32 (mp->local_session_id));
11163   vat_json_object_add_uint (node, "remote_session_id",
11164                             clib_net_to_host_u32 (mp->remote_session_id));
11165   vat_json_object_add_string_copy (node, "l2_sublayer",
11166                                    mp->l2_sublayer_present ? (u8 *) "present"
11167                                    : (u8 *) "absent");
11168 }
11169
11170 static int
11171 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11172 {
11173   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11174   vl_api_control_ping_t *mp_ping;
11175   int ret;
11176
11177   /* Get list of l2tpv3-tunnel interfaces */
11178   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11179   S (mp);
11180
11181   /* Use a control ping for synchronization */
11182   M (CONTROL_PING, mp_ping);
11183   S (mp_ping);
11184
11185   W (ret);
11186   return ret;
11187 }
11188
11189
11190 static void vl_api_sw_interface_tap_details_t_handler
11191   (vl_api_sw_interface_tap_details_t * mp)
11192 {
11193   vat_main_t *vam = &vat_main;
11194
11195   print (vam->ofp, "%-16s %d",
11196          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
11197 }
11198
11199 static void vl_api_sw_interface_tap_details_t_handler_json
11200   (vl_api_sw_interface_tap_details_t * mp)
11201 {
11202   vat_main_t *vam = &vat_main;
11203   vat_json_node_t *node = NULL;
11204
11205   if (VAT_JSON_ARRAY != vam->json_tree.type)
11206     {
11207       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11208       vat_json_init_array (&vam->json_tree);
11209     }
11210   node = vat_json_array_add (&vam->json_tree);
11211
11212   vat_json_init_object (node);
11213   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11214   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11215 }
11216
11217 static int
11218 api_sw_interface_tap_dump (vat_main_t * vam)
11219 {
11220   vl_api_sw_interface_tap_dump_t *mp;
11221   vl_api_control_ping_t *mp_ping;
11222   int ret;
11223
11224   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
11225   /* Get list of tap interfaces */
11226   M (SW_INTERFACE_TAP_DUMP, mp);
11227   S (mp);
11228
11229   /* Use a control ping for synchronization */
11230   M (CONTROL_PING, mp_ping);
11231   S (mp_ping);
11232
11233   W (ret);
11234   return ret;
11235 }
11236
11237 static uword unformat_vxlan_decap_next
11238   (unformat_input_t * input, va_list * args)
11239 {
11240   u32 *result = va_arg (*args, u32 *);
11241   u32 tmp;
11242
11243   if (unformat (input, "l2"))
11244     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11245   else if (unformat (input, "%d", &tmp))
11246     *result = tmp;
11247   else
11248     return 0;
11249   return 1;
11250 }
11251
11252 static int
11253 api_vxlan_add_del_tunnel (vat_main_t * vam)
11254 {
11255   unformat_input_t *line_input = vam->input;
11256   vl_api_vxlan_add_del_tunnel_t *mp;
11257   ip46_address_t src, dst;
11258   u8 is_add = 1;
11259   u8 ipv4_set = 0, ipv6_set = 0;
11260   u8 src_set = 0;
11261   u8 dst_set = 0;
11262   u8 grp_set = 0;
11263   u32 mcast_sw_if_index = ~0;
11264   u32 encap_vrf_id = 0;
11265   u32 decap_next_index = ~0;
11266   u32 vni = 0;
11267   int ret;
11268
11269   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11270   memset (&src, 0, sizeof src);
11271   memset (&dst, 0, sizeof dst);
11272
11273   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11274     {
11275       if (unformat (line_input, "del"))
11276         is_add = 0;
11277       else
11278         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11279         {
11280           ipv4_set = 1;
11281           src_set = 1;
11282         }
11283       else
11284         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11285         {
11286           ipv4_set = 1;
11287           dst_set = 1;
11288         }
11289       else
11290         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11291         {
11292           ipv6_set = 1;
11293           src_set = 1;
11294         }
11295       else
11296         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11297         {
11298           ipv6_set = 1;
11299           dst_set = 1;
11300         }
11301       else if (unformat (line_input, "group %U %U",
11302                          unformat_ip4_address, &dst.ip4,
11303                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11304         {
11305           grp_set = dst_set = 1;
11306           ipv4_set = 1;
11307         }
11308       else if (unformat (line_input, "group %U",
11309                          unformat_ip4_address, &dst.ip4))
11310         {
11311           grp_set = dst_set = 1;
11312           ipv4_set = 1;
11313         }
11314       else if (unformat (line_input, "group %U %U",
11315                          unformat_ip6_address, &dst.ip6,
11316                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11317         {
11318           grp_set = dst_set = 1;
11319           ipv6_set = 1;
11320         }
11321       else if (unformat (line_input, "group %U",
11322                          unformat_ip6_address, &dst.ip6))
11323         {
11324           grp_set = dst_set = 1;
11325           ipv6_set = 1;
11326         }
11327       else
11328         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11329         ;
11330       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11331         ;
11332       else if (unformat (line_input, "decap-next %U",
11333                          unformat_vxlan_decap_next, &decap_next_index))
11334         ;
11335       else if (unformat (line_input, "vni %d", &vni))
11336         ;
11337       else
11338         {
11339           errmsg ("parse error '%U'", format_unformat_error, line_input);
11340           return -99;
11341         }
11342     }
11343
11344   if (src_set == 0)
11345     {
11346       errmsg ("tunnel src address not specified");
11347       return -99;
11348     }
11349   if (dst_set == 0)
11350     {
11351       errmsg ("tunnel dst address not specified");
11352       return -99;
11353     }
11354
11355   if (grp_set && !ip46_address_is_multicast (&dst))
11356     {
11357       errmsg ("tunnel group address not multicast");
11358       return -99;
11359     }
11360   if (grp_set && mcast_sw_if_index == ~0)
11361     {
11362       errmsg ("tunnel nonexistent multicast device");
11363       return -99;
11364     }
11365   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11366     {
11367       errmsg ("tunnel dst address must be unicast");
11368       return -99;
11369     }
11370
11371
11372   if (ipv4_set && ipv6_set)
11373     {
11374       errmsg ("both IPv4 and IPv6 addresses specified");
11375       return -99;
11376     }
11377
11378   if ((vni == 0) || (vni >> 24))
11379     {
11380       errmsg ("vni not specified or out of range");
11381       return -99;
11382     }
11383
11384   M (VXLAN_ADD_DEL_TUNNEL, mp);
11385
11386   if (ipv6_set)
11387     {
11388       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
11389       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
11390     }
11391   else
11392     {
11393       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
11394       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
11395     }
11396   mp->encap_vrf_id = ntohl (encap_vrf_id);
11397   mp->decap_next_index = ntohl (decap_next_index);
11398   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11399   mp->vni = ntohl (vni);
11400   mp->is_add = is_add;
11401   mp->is_ipv6 = ipv6_set;
11402
11403   S (mp);
11404   W (ret);
11405   return ret;
11406 }
11407
11408 static void vl_api_vxlan_tunnel_details_t_handler
11409   (vl_api_vxlan_tunnel_details_t * mp)
11410 {
11411   vat_main_t *vam = &vat_main;
11412   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
11413   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
11414
11415   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
11416          ntohl (mp->sw_if_index),
11417          format_ip46_address, &src, IP46_TYPE_ANY,
11418          format_ip46_address, &dst, IP46_TYPE_ANY,
11419          ntohl (mp->encap_vrf_id),
11420          ntohl (mp->decap_next_index), ntohl (mp->vni),
11421          ntohl (mp->mcast_sw_if_index));
11422 }
11423
11424 static void vl_api_vxlan_tunnel_details_t_handler_json
11425   (vl_api_vxlan_tunnel_details_t * mp)
11426 {
11427   vat_main_t *vam = &vat_main;
11428   vat_json_node_t *node = NULL;
11429
11430   if (VAT_JSON_ARRAY != vam->json_tree.type)
11431     {
11432       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11433       vat_json_init_array (&vam->json_tree);
11434     }
11435   node = vat_json_array_add (&vam->json_tree);
11436
11437   vat_json_init_object (node);
11438   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11439   if (mp->is_ipv6)
11440     {
11441       struct in6_addr ip6;
11442
11443       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
11444       vat_json_object_add_ip6 (node, "src_address", ip6);
11445       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
11446       vat_json_object_add_ip6 (node, "dst_address", ip6);
11447     }
11448   else
11449     {
11450       struct in_addr ip4;
11451
11452       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
11453       vat_json_object_add_ip4 (node, "src_address", ip4);
11454       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
11455       vat_json_object_add_ip4 (node, "dst_address", ip4);
11456     }
11457   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11458   vat_json_object_add_uint (node, "decap_next_index",
11459                             ntohl (mp->decap_next_index));
11460   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11461   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11462   vat_json_object_add_uint (node, "mcast_sw_if_index",
11463                             ntohl (mp->mcast_sw_if_index));
11464 }
11465
11466 static int
11467 api_vxlan_tunnel_dump (vat_main_t * vam)
11468 {
11469   unformat_input_t *i = vam->input;
11470   vl_api_vxlan_tunnel_dump_t *mp;
11471   vl_api_control_ping_t *mp_ping;
11472   u32 sw_if_index;
11473   u8 sw_if_index_set = 0;
11474   int ret;
11475
11476   /* Parse args required to build the message */
11477   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11478     {
11479       if (unformat (i, "sw_if_index %d", &sw_if_index))
11480         sw_if_index_set = 1;
11481       else
11482         break;
11483     }
11484
11485   if (sw_if_index_set == 0)
11486     {
11487       sw_if_index = ~0;
11488     }
11489
11490   if (!vam->json_output)
11491     {
11492       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
11493              "sw_if_index", "src_address", "dst_address",
11494              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11495     }
11496
11497   /* Get list of vxlan-tunnel interfaces */
11498   M (VXLAN_TUNNEL_DUMP, mp);
11499
11500   mp->sw_if_index = htonl (sw_if_index);
11501
11502   S (mp);
11503
11504   /* Use a control ping for synchronization */
11505   M (CONTROL_PING, mp_ping);
11506   S (mp_ping);
11507
11508   W (ret);
11509   return ret;
11510 }
11511
11512 static int
11513 api_gre_add_del_tunnel (vat_main_t * vam)
11514 {
11515   unformat_input_t *line_input = vam->input;
11516   vl_api_gre_add_del_tunnel_t *mp;
11517   ip4_address_t src4, dst4;
11518   ip6_address_t src6, dst6;
11519   u8 is_add = 1;
11520   u8 ipv4_set = 0;
11521   u8 ipv6_set = 0;
11522   u8 teb = 0;
11523   u8 src_set = 0;
11524   u8 dst_set = 0;
11525   u32 outer_fib_id = 0;
11526   int ret;
11527
11528   memset (&src4, 0, sizeof src4);
11529   memset (&dst4, 0, sizeof dst4);
11530   memset (&src6, 0, sizeof src6);
11531   memset (&dst6, 0, sizeof dst6);
11532
11533   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11534     {
11535       if (unformat (line_input, "del"))
11536         is_add = 0;
11537       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
11538         {
11539           src_set = 1;
11540           ipv4_set = 1;
11541         }
11542       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
11543         {
11544           dst_set = 1;
11545           ipv4_set = 1;
11546         }
11547       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
11548         {
11549           src_set = 1;
11550           ipv6_set = 1;
11551         }
11552       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
11553         {
11554           dst_set = 1;
11555           ipv6_set = 1;
11556         }
11557       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
11558         ;
11559       else if (unformat (line_input, "teb"))
11560         teb = 1;
11561       else
11562         {
11563           errmsg ("parse error '%U'", format_unformat_error, line_input);
11564           return -99;
11565         }
11566     }
11567
11568   if (src_set == 0)
11569     {
11570       errmsg ("tunnel src address not specified");
11571       return -99;
11572     }
11573   if (dst_set == 0)
11574     {
11575       errmsg ("tunnel dst address not specified");
11576       return -99;
11577     }
11578   if (ipv4_set && ipv6_set)
11579     {
11580       errmsg ("both IPv4 and IPv6 addresses specified");
11581       return -99;
11582     }
11583
11584
11585   M (GRE_ADD_DEL_TUNNEL, mp);
11586
11587   if (ipv4_set)
11588     {
11589       clib_memcpy (&mp->src_address, &src4, 4);
11590       clib_memcpy (&mp->dst_address, &dst4, 4);
11591     }
11592   else
11593     {
11594       clib_memcpy (&mp->src_address, &src6, 16);
11595       clib_memcpy (&mp->dst_address, &dst6, 16);
11596     }
11597   mp->outer_fib_id = ntohl (outer_fib_id);
11598   mp->is_add = is_add;
11599   mp->teb = teb;
11600   mp->is_ipv6 = ipv6_set;
11601
11602   S (mp);
11603   W (ret);
11604   return ret;
11605 }
11606
11607 static void vl_api_gre_tunnel_details_t_handler
11608   (vl_api_gre_tunnel_details_t * mp)
11609 {
11610   vat_main_t *vam = &vat_main;
11611   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
11612   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
11613
11614   print (vam->ofp, "%11d%24U%24U%6d%14d",
11615          ntohl (mp->sw_if_index),
11616          format_ip46_address, &src, IP46_TYPE_ANY,
11617          format_ip46_address, &dst, IP46_TYPE_ANY,
11618          mp->teb, ntohl (mp->outer_fib_id));
11619 }
11620
11621 static void vl_api_gre_tunnel_details_t_handler_json
11622   (vl_api_gre_tunnel_details_t * mp)
11623 {
11624   vat_main_t *vam = &vat_main;
11625   vat_json_node_t *node = NULL;
11626   struct in_addr ip4;
11627   struct in6_addr ip6;
11628
11629   if (VAT_JSON_ARRAY != vam->json_tree.type)
11630     {
11631       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11632       vat_json_init_array (&vam->json_tree);
11633     }
11634   node = vat_json_array_add (&vam->json_tree);
11635
11636   vat_json_init_object (node);
11637   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11638   if (!mp->is_ipv6)
11639     {
11640       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
11641       vat_json_object_add_ip4 (node, "src_address", ip4);
11642       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
11643       vat_json_object_add_ip4 (node, "dst_address", ip4);
11644     }
11645   else
11646     {
11647       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
11648       vat_json_object_add_ip6 (node, "src_address", ip6);
11649       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
11650       vat_json_object_add_ip6 (node, "dst_address", ip6);
11651     }
11652   vat_json_object_add_uint (node, "teb", mp->teb);
11653   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
11654   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
11655 }
11656
11657 static int
11658 api_gre_tunnel_dump (vat_main_t * vam)
11659 {
11660   unformat_input_t *i = vam->input;
11661   vl_api_gre_tunnel_dump_t *mp;
11662   vl_api_control_ping_t *mp_ping;
11663   u32 sw_if_index;
11664   u8 sw_if_index_set = 0;
11665   int ret;
11666
11667   /* Parse args required to build the message */
11668   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11669     {
11670       if (unformat (i, "sw_if_index %d", &sw_if_index))
11671         sw_if_index_set = 1;
11672       else
11673         break;
11674     }
11675
11676   if (sw_if_index_set == 0)
11677     {
11678       sw_if_index = ~0;
11679     }
11680
11681   if (!vam->json_output)
11682     {
11683       print (vam->ofp, "%11s%24s%24s%6s%14s",
11684              "sw_if_index", "src_address", "dst_address", "teb",
11685              "outer_fib_id");
11686     }
11687
11688   /* Get list of gre-tunnel interfaces */
11689   M (GRE_TUNNEL_DUMP, mp);
11690
11691   mp->sw_if_index = htonl (sw_if_index);
11692
11693   S (mp);
11694
11695   /* Use a control ping for synchronization */
11696   M (CONTROL_PING, mp_ping);
11697   S (mp_ping);
11698
11699   W (ret);
11700   return ret;
11701 }
11702
11703 static int
11704 api_l2_fib_clear_table (vat_main_t * vam)
11705 {
11706 //  unformat_input_t * i = vam->input;
11707   vl_api_l2_fib_clear_table_t *mp;
11708   int ret;
11709
11710   M (L2_FIB_CLEAR_TABLE, mp);
11711
11712   S (mp);
11713   W (ret);
11714   return ret;
11715 }
11716
11717 static int
11718 api_l2_interface_efp_filter (vat_main_t * vam)
11719 {
11720   unformat_input_t *i = vam->input;
11721   vl_api_l2_interface_efp_filter_t *mp;
11722   u32 sw_if_index;
11723   u8 enable = 1;
11724   u8 sw_if_index_set = 0;
11725   int ret;
11726
11727   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11728     {
11729       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11730         sw_if_index_set = 1;
11731       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11732         sw_if_index_set = 1;
11733       else if (unformat (i, "enable"))
11734         enable = 1;
11735       else if (unformat (i, "disable"))
11736         enable = 0;
11737       else
11738         {
11739           clib_warning ("parse error '%U'", format_unformat_error, i);
11740           return -99;
11741         }
11742     }
11743
11744   if (sw_if_index_set == 0)
11745     {
11746       errmsg ("missing sw_if_index");
11747       return -99;
11748     }
11749
11750   M (L2_INTERFACE_EFP_FILTER, mp);
11751
11752   mp->sw_if_index = ntohl (sw_if_index);
11753   mp->enable_disable = enable;
11754
11755   S (mp);
11756   W (ret);
11757   return ret;
11758 }
11759
11760 #define foreach_vtr_op                          \
11761 _("disable",  L2_VTR_DISABLED)                  \
11762 _("push-1",  L2_VTR_PUSH_1)                     \
11763 _("push-2",  L2_VTR_PUSH_2)                     \
11764 _("pop-1",  L2_VTR_POP_1)                       \
11765 _("pop-2",  L2_VTR_POP_2)                       \
11766 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
11767 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
11768 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
11769 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
11770
11771 static int
11772 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
11773 {
11774   unformat_input_t *i = vam->input;
11775   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
11776   u32 sw_if_index;
11777   u8 sw_if_index_set = 0;
11778   u8 vtr_op_set = 0;
11779   u32 vtr_op = 0;
11780   u32 push_dot1q = 1;
11781   u32 tag1 = ~0;
11782   u32 tag2 = ~0;
11783   int ret;
11784
11785   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11786     {
11787       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11788         sw_if_index_set = 1;
11789       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11790         sw_if_index_set = 1;
11791       else if (unformat (i, "vtr_op %d", &vtr_op))
11792         vtr_op_set = 1;
11793 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
11794       foreach_vtr_op
11795 #undef _
11796         else if (unformat (i, "push_dot1q %d", &push_dot1q))
11797         ;
11798       else if (unformat (i, "tag1 %d", &tag1))
11799         ;
11800       else if (unformat (i, "tag2 %d", &tag2))
11801         ;
11802       else
11803         {
11804           clib_warning ("parse error '%U'", format_unformat_error, i);
11805           return -99;
11806         }
11807     }
11808
11809   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
11810     {
11811       errmsg ("missing vtr operation or sw_if_index");
11812       return -99;
11813     }
11814
11815   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
11816   mp->sw_if_index = ntohl (sw_if_index);
11817   mp->vtr_op = ntohl (vtr_op);
11818   mp->push_dot1q = ntohl (push_dot1q);
11819   mp->tag1 = ntohl (tag1);
11820   mp->tag2 = ntohl (tag2);
11821
11822   S (mp);
11823   W (ret);
11824   return ret;
11825 }
11826
11827 static int
11828 api_create_vhost_user_if (vat_main_t * vam)
11829 {
11830   unformat_input_t *i = vam->input;
11831   vl_api_create_vhost_user_if_t *mp;
11832   u8 *file_name;
11833   u8 is_server = 0;
11834   u8 file_name_set = 0;
11835   u32 custom_dev_instance = ~0;
11836   u8 hwaddr[6];
11837   u8 use_custom_mac = 0;
11838   u8 *tag = 0;
11839   int ret;
11840
11841   /* Shut up coverity */
11842   memset (hwaddr, 0, sizeof (hwaddr));
11843
11844   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11845     {
11846       if (unformat (i, "socket %s", &file_name))
11847         {
11848           file_name_set = 1;
11849         }
11850       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11851         ;
11852       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
11853         use_custom_mac = 1;
11854       else if (unformat (i, "server"))
11855         is_server = 1;
11856       else if (unformat (i, "tag %s", &tag))
11857         ;
11858       else
11859         break;
11860     }
11861
11862   if (file_name_set == 0)
11863     {
11864       errmsg ("missing socket file name");
11865       return -99;
11866     }
11867
11868   if (vec_len (file_name) > 255)
11869     {
11870       errmsg ("socket file name too long");
11871       return -99;
11872     }
11873   vec_add1 (file_name, 0);
11874
11875   M (CREATE_VHOST_USER_IF, mp);
11876
11877   mp->is_server = is_server;
11878   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11879   vec_free (file_name);
11880   if (custom_dev_instance != ~0)
11881     {
11882       mp->renumber = 1;
11883       mp->custom_dev_instance = ntohl (custom_dev_instance);
11884     }
11885   mp->use_custom_mac = use_custom_mac;
11886   clib_memcpy (mp->mac_address, hwaddr, 6);
11887   if (tag)
11888     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
11889   vec_free (tag);
11890
11891   S (mp);
11892   W (ret);
11893   return ret;
11894 }
11895
11896 static int
11897 api_modify_vhost_user_if (vat_main_t * vam)
11898 {
11899   unformat_input_t *i = vam->input;
11900   vl_api_modify_vhost_user_if_t *mp;
11901   u8 *file_name;
11902   u8 is_server = 0;
11903   u8 file_name_set = 0;
11904   u32 custom_dev_instance = ~0;
11905   u8 sw_if_index_set = 0;
11906   u32 sw_if_index = (u32) ~ 0;
11907   int ret;
11908
11909   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11910     {
11911       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11912         sw_if_index_set = 1;
11913       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11914         sw_if_index_set = 1;
11915       else if (unformat (i, "socket %s", &file_name))
11916         {
11917           file_name_set = 1;
11918         }
11919       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11920         ;
11921       else if (unformat (i, "server"))
11922         is_server = 1;
11923       else
11924         break;
11925     }
11926
11927   if (sw_if_index_set == 0)
11928     {
11929       errmsg ("missing sw_if_index or interface name");
11930       return -99;
11931     }
11932
11933   if (file_name_set == 0)
11934     {
11935       errmsg ("missing socket file name");
11936       return -99;
11937     }
11938
11939   if (vec_len (file_name) > 255)
11940     {
11941       errmsg ("socket file name too long");
11942       return -99;
11943     }
11944   vec_add1 (file_name, 0);
11945
11946   M (MODIFY_VHOST_USER_IF, mp);
11947
11948   mp->sw_if_index = ntohl (sw_if_index);
11949   mp->is_server = is_server;
11950   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11951   vec_free (file_name);
11952   if (custom_dev_instance != ~0)
11953     {
11954       mp->renumber = 1;
11955       mp->custom_dev_instance = ntohl (custom_dev_instance);
11956     }
11957
11958   S (mp);
11959   W (ret);
11960   return ret;
11961 }
11962
11963 static int
11964 api_delete_vhost_user_if (vat_main_t * vam)
11965 {
11966   unformat_input_t *i = vam->input;
11967   vl_api_delete_vhost_user_if_t *mp;
11968   u32 sw_if_index = ~0;
11969   u8 sw_if_index_set = 0;
11970   int ret;
11971
11972   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11973     {
11974       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11975         sw_if_index_set = 1;
11976       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11977         sw_if_index_set = 1;
11978       else
11979         break;
11980     }
11981
11982   if (sw_if_index_set == 0)
11983     {
11984       errmsg ("missing sw_if_index or interface name");
11985       return -99;
11986     }
11987
11988
11989   M (DELETE_VHOST_USER_IF, mp);
11990
11991   mp->sw_if_index = ntohl (sw_if_index);
11992
11993   S (mp);
11994   W (ret);
11995   return ret;
11996 }
11997
11998 static void vl_api_sw_interface_vhost_user_details_t_handler
11999   (vl_api_sw_interface_vhost_user_details_t * mp)
12000 {
12001   vat_main_t *vam = &vat_main;
12002
12003   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12004          (char *) mp->interface_name,
12005          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12006          clib_net_to_host_u64 (mp->features), mp->is_server,
12007          ntohl (mp->num_regions), (char *) mp->sock_filename);
12008   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12009 }
12010
12011 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12012   (vl_api_sw_interface_vhost_user_details_t * mp)
12013 {
12014   vat_main_t *vam = &vat_main;
12015   vat_json_node_t *node = NULL;
12016
12017   if (VAT_JSON_ARRAY != vam->json_tree.type)
12018     {
12019       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12020       vat_json_init_array (&vam->json_tree);
12021     }
12022   node = vat_json_array_add (&vam->json_tree);
12023
12024   vat_json_init_object (node);
12025   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12026   vat_json_object_add_string_copy (node, "interface_name",
12027                                    mp->interface_name);
12028   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12029                             ntohl (mp->virtio_net_hdr_sz));
12030   vat_json_object_add_uint (node, "features",
12031                             clib_net_to_host_u64 (mp->features));
12032   vat_json_object_add_uint (node, "is_server", mp->is_server);
12033   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12034   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12035   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12036 }
12037
12038 static int
12039 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12040 {
12041   vl_api_sw_interface_vhost_user_dump_t *mp;
12042   vl_api_control_ping_t *mp_ping;
12043   int ret;
12044   print (vam->ofp,
12045          "Interface name            idx hdr_sz features server regions filename");
12046
12047   /* Get list of vhost-user interfaces */
12048   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12049   S (mp);
12050
12051   /* Use a control ping for synchronization */
12052   M (CONTROL_PING, mp_ping);
12053   S (mp_ping);
12054
12055   W (ret);
12056   return ret;
12057 }
12058
12059 static int
12060 api_show_version (vat_main_t * vam)
12061 {
12062   vl_api_show_version_t *mp;
12063   int ret;
12064
12065   M (SHOW_VERSION, mp);
12066
12067   S (mp);
12068   W (ret);
12069   return ret;
12070 }
12071
12072
12073 static int
12074 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12075 {
12076   unformat_input_t *line_input = vam->input;
12077   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12078   ip4_address_t local4, remote4;
12079   ip6_address_t local6, remote6;
12080   u8 is_add = 1;
12081   u8 ipv4_set = 0, ipv6_set = 0;
12082   u8 local_set = 0;
12083   u8 remote_set = 0;
12084   u8 grp_set = 0;
12085   u32 mcast_sw_if_index = ~0;
12086   u32 encap_vrf_id = 0;
12087   u32 decap_vrf_id = 0;
12088   u8 protocol = ~0;
12089   u32 vni;
12090   u8 vni_set = 0;
12091   int ret;
12092
12093   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12094   memset (&local4, 0, sizeof local4);
12095   memset (&remote4, 0, sizeof remote4);
12096   memset (&local6, 0, sizeof local6);
12097   memset (&remote6, 0, sizeof remote6);
12098
12099   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12100     {
12101       if (unformat (line_input, "del"))
12102         is_add = 0;
12103       else if (unformat (line_input, "local %U",
12104                          unformat_ip4_address, &local4))
12105         {
12106           local_set = 1;
12107           ipv4_set = 1;
12108         }
12109       else if (unformat (line_input, "remote %U",
12110                          unformat_ip4_address, &remote4))
12111         {
12112           remote_set = 1;
12113           ipv4_set = 1;
12114         }
12115       else if (unformat (line_input, "local %U",
12116                          unformat_ip6_address, &local6))
12117         {
12118           local_set = 1;
12119           ipv6_set = 1;
12120         }
12121       else if (unformat (line_input, "remote %U",
12122                          unformat_ip6_address, &remote6))
12123         {
12124           remote_set = 1;
12125           ipv6_set = 1;
12126         }
12127       else if (unformat (line_input, "group %U %U",
12128                          unformat_ip4_address, &remote4,
12129                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12130         {
12131           grp_set = remote_set = 1;
12132           ipv4_set = 1;
12133         }
12134       else if (unformat (line_input, "group %U",
12135                          unformat_ip4_address, &remote4))
12136         {
12137           grp_set = remote_set = 1;
12138           ipv4_set = 1;
12139         }
12140       else if (unformat (line_input, "group %U %U",
12141                          unformat_ip6_address, &remote6,
12142                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12143         {
12144           grp_set = remote_set = 1;
12145           ipv6_set = 1;
12146         }
12147       else if (unformat (line_input, "group %U",
12148                          unformat_ip6_address, &remote6))
12149         {
12150           grp_set = remote_set = 1;
12151           ipv6_set = 1;
12152         }
12153       else
12154         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12155         ;
12156       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12157         ;
12158       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
12159         ;
12160       else if (unformat (line_input, "vni %d", &vni))
12161         vni_set = 1;
12162       else if (unformat (line_input, "next-ip4"))
12163         protocol = 1;
12164       else if (unformat (line_input, "next-ip6"))
12165         protocol = 2;
12166       else if (unformat (line_input, "next-ethernet"))
12167         protocol = 3;
12168       else if (unformat (line_input, "next-nsh"))
12169         protocol = 4;
12170       else
12171         {
12172           errmsg ("parse error '%U'", format_unformat_error, line_input);
12173           return -99;
12174         }
12175     }
12176
12177   if (local_set == 0)
12178     {
12179       errmsg ("tunnel local address not specified");
12180       return -99;
12181     }
12182   if (remote_set == 0)
12183     {
12184       errmsg ("tunnel remote address not specified");
12185       return -99;
12186     }
12187   if (grp_set && mcast_sw_if_index == ~0)
12188     {
12189       errmsg ("tunnel nonexistent multicast device");
12190       return -99;
12191     }
12192   if (ipv4_set && ipv6_set)
12193     {
12194       errmsg ("both IPv4 and IPv6 addresses specified");
12195       return -99;
12196     }
12197
12198   if (vni_set == 0)
12199     {
12200       errmsg ("vni not specified");
12201       return -99;
12202     }
12203
12204   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
12205
12206
12207   if (ipv6_set)
12208     {
12209       clib_memcpy (&mp->local, &local6, sizeof (local6));
12210       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
12211     }
12212   else
12213     {
12214       clib_memcpy (&mp->local, &local4, sizeof (local4));
12215       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
12216     }
12217
12218   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12219   mp->encap_vrf_id = ntohl (encap_vrf_id);
12220   mp->decap_vrf_id = ntohl (decap_vrf_id);
12221   mp->protocol = protocol;
12222   mp->vni = ntohl (vni);
12223   mp->is_add = is_add;
12224   mp->is_ipv6 = ipv6_set;
12225
12226   S (mp);
12227   W (ret);
12228   return ret;
12229 }
12230
12231 static void vl_api_vxlan_gpe_tunnel_details_t_handler
12232   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12233 {
12234   vat_main_t *vam = &vat_main;
12235   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
12236   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
12237
12238   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
12239          ntohl (mp->sw_if_index),
12240          format_ip46_address, &local, IP46_TYPE_ANY,
12241          format_ip46_address, &remote, IP46_TYPE_ANY,
12242          ntohl (mp->vni), mp->protocol,
12243          ntohl (mp->mcast_sw_if_index),
12244          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
12245 }
12246
12247
12248 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
12249   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12250 {
12251   vat_main_t *vam = &vat_main;
12252   vat_json_node_t *node = NULL;
12253   struct in_addr ip4;
12254   struct in6_addr ip6;
12255
12256   if (VAT_JSON_ARRAY != vam->json_tree.type)
12257     {
12258       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12259       vat_json_init_array (&vam->json_tree);
12260     }
12261   node = vat_json_array_add (&vam->json_tree);
12262
12263   vat_json_init_object (node);
12264   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12265   if (mp->is_ipv6)
12266     {
12267       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
12268       vat_json_object_add_ip6 (node, "local", ip6);
12269       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
12270       vat_json_object_add_ip6 (node, "remote", ip6);
12271     }
12272   else
12273     {
12274       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
12275       vat_json_object_add_ip4 (node, "local", ip4);
12276       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
12277       vat_json_object_add_ip4 (node, "remote", ip4);
12278     }
12279   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12280   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
12281   vat_json_object_add_uint (node, "mcast_sw_if_index",
12282                             ntohl (mp->mcast_sw_if_index));
12283   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12284   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
12285   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12286 }
12287
12288 static int
12289 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
12290 {
12291   unformat_input_t *i = vam->input;
12292   vl_api_vxlan_gpe_tunnel_dump_t *mp;
12293   vl_api_control_ping_t *mp_ping;
12294   u32 sw_if_index;
12295   u8 sw_if_index_set = 0;
12296   int ret;
12297
12298   /* Parse args required to build the message */
12299   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12300     {
12301       if (unformat (i, "sw_if_index %d", &sw_if_index))
12302         sw_if_index_set = 1;
12303       else
12304         break;
12305     }
12306
12307   if (sw_if_index_set == 0)
12308     {
12309       sw_if_index = ~0;
12310     }
12311
12312   if (!vam->json_output)
12313     {
12314       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
12315              "sw_if_index", "local", "remote", "vni",
12316              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
12317     }
12318
12319   /* Get list of vxlan-tunnel interfaces */
12320   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12321
12322   mp->sw_if_index = htonl (sw_if_index);
12323
12324   S (mp);
12325
12326   /* Use a control ping for synchronization */
12327   M (CONTROL_PING, mp_ping);
12328   S (mp_ping);
12329
12330   W (ret);
12331   return ret;
12332 }
12333
12334
12335 u8 *
12336 format_l2_fib_mac_address (u8 * s, va_list * args)
12337 {
12338   u8 *a = va_arg (*args, u8 *);
12339
12340   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
12341                  a[2], a[3], a[4], a[5], a[6], a[7]);
12342 }
12343
12344 static void vl_api_l2_fib_table_details_t_handler
12345   (vl_api_l2_fib_table_details_t * mp)
12346 {
12347   vat_main_t *vam = &vat_main;
12348
12349   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
12350          "       %d       %d     %d",
12351          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
12352          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
12353          mp->bvi_mac);
12354 }
12355
12356 static void vl_api_l2_fib_table_details_t_handler_json
12357   (vl_api_l2_fib_table_details_t * mp)
12358 {
12359   vat_main_t *vam = &vat_main;
12360   vat_json_node_t *node = NULL;
12361
12362   if (VAT_JSON_ARRAY != vam->json_tree.type)
12363     {
12364       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12365       vat_json_init_array (&vam->json_tree);
12366     }
12367   node = vat_json_array_add (&vam->json_tree);
12368
12369   vat_json_init_object (node);
12370   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
12371   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
12372   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12373   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
12374   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
12375   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
12376 }
12377
12378 static int
12379 api_l2_fib_table_dump (vat_main_t * vam)
12380 {
12381   unformat_input_t *i = vam->input;
12382   vl_api_l2_fib_table_dump_t *mp;
12383   vl_api_control_ping_t *mp_ping;
12384   u32 bd_id;
12385   u8 bd_id_set = 0;
12386   int ret;
12387
12388   /* Parse args required to build the message */
12389   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12390     {
12391       if (unformat (i, "bd_id %d", &bd_id))
12392         bd_id_set = 1;
12393       else
12394         break;
12395     }
12396
12397   if (bd_id_set == 0)
12398     {
12399       errmsg ("missing bridge domain");
12400       return -99;
12401     }
12402
12403   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
12404
12405   /* Get list of l2 fib entries */
12406   M (L2_FIB_TABLE_DUMP, mp);
12407
12408   mp->bd_id = ntohl (bd_id);
12409   S (mp);
12410
12411   /* Use a control ping for synchronization */
12412   M (CONTROL_PING, mp_ping);
12413   S (mp_ping);
12414
12415   W (ret);
12416   return ret;
12417 }
12418
12419
12420 static int
12421 api_interface_name_renumber (vat_main_t * vam)
12422 {
12423   unformat_input_t *line_input = vam->input;
12424   vl_api_interface_name_renumber_t *mp;
12425   u32 sw_if_index = ~0;
12426   u32 new_show_dev_instance = ~0;
12427   int ret;
12428
12429   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12430     {
12431       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
12432                     &sw_if_index))
12433         ;
12434       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12435         ;
12436       else if (unformat (line_input, "new_show_dev_instance %d",
12437                          &new_show_dev_instance))
12438         ;
12439       else
12440         break;
12441     }
12442
12443   if (sw_if_index == ~0)
12444     {
12445       errmsg ("missing interface name or sw_if_index");
12446       return -99;
12447     }
12448
12449   if (new_show_dev_instance == ~0)
12450     {
12451       errmsg ("missing new_show_dev_instance");
12452       return -99;
12453     }
12454
12455   M (INTERFACE_NAME_RENUMBER, mp);
12456
12457   mp->sw_if_index = ntohl (sw_if_index);
12458   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
12459
12460   S (mp);
12461   W (ret);
12462   return ret;
12463 }
12464
12465 static int
12466 api_want_ip4_arp_events (vat_main_t * vam)
12467 {
12468   unformat_input_t *line_input = vam->input;
12469   vl_api_want_ip4_arp_events_t *mp;
12470   ip4_address_t address;
12471   int address_set = 0;
12472   u32 enable_disable = 1;
12473   int ret;
12474
12475   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12476     {
12477       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
12478         address_set = 1;
12479       else if (unformat (line_input, "del"))
12480         enable_disable = 0;
12481       else
12482         break;
12483     }
12484
12485   if (address_set == 0)
12486     {
12487       errmsg ("missing addresses");
12488       return -99;
12489     }
12490
12491   M (WANT_IP4_ARP_EVENTS, mp);
12492   mp->enable_disable = enable_disable;
12493   mp->pid = htonl (getpid ());
12494   mp->address = address.as_u32;
12495
12496   S (mp);
12497   W (ret);
12498   return ret;
12499 }
12500
12501 static int
12502 api_want_ip6_nd_events (vat_main_t * vam)
12503 {
12504   unformat_input_t *line_input = vam->input;
12505   vl_api_want_ip6_nd_events_t *mp;
12506   ip6_address_t address;
12507   int address_set = 0;
12508   u32 enable_disable = 1;
12509   int ret;
12510
12511   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12512     {
12513       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
12514         address_set = 1;
12515       else if (unformat (line_input, "del"))
12516         enable_disable = 0;
12517       else
12518         break;
12519     }
12520
12521   if (address_set == 0)
12522     {
12523       errmsg ("missing addresses");
12524       return -99;
12525     }
12526
12527   M (WANT_IP6_ND_EVENTS, mp);
12528   mp->enable_disable = enable_disable;
12529   mp->pid = htonl (getpid ());
12530   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
12531
12532   S (mp);
12533   W (ret);
12534   return ret;
12535 }
12536
12537 static int
12538 api_input_acl_set_interface (vat_main_t * vam)
12539 {
12540   unformat_input_t *i = vam->input;
12541   vl_api_input_acl_set_interface_t *mp;
12542   u32 sw_if_index;
12543   int sw_if_index_set;
12544   u32 ip4_table_index = ~0;
12545   u32 ip6_table_index = ~0;
12546   u32 l2_table_index = ~0;
12547   u8 is_add = 1;
12548   int ret;
12549
12550   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12551     {
12552       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12553         sw_if_index_set = 1;
12554       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12555         sw_if_index_set = 1;
12556       else if (unformat (i, "del"))
12557         is_add = 0;
12558       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12559         ;
12560       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12561         ;
12562       else if (unformat (i, "l2-table %d", &l2_table_index))
12563         ;
12564       else
12565         {
12566           clib_warning ("parse error '%U'", format_unformat_error, i);
12567           return -99;
12568         }
12569     }
12570
12571   if (sw_if_index_set == 0)
12572     {
12573       errmsg ("missing interface name or sw_if_index");
12574       return -99;
12575     }
12576
12577   M (INPUT_ACL_SET_INTERFACE, mp);
12578
12579   mp->sw_if_index = ntohl (sw_if_index);
12580   mp->ip4_table_index = ntohl (ip4_table_index);
12581   mp->ip6_table_index = ntohl (ip6_table_index);
12582   mp->l2_table_index = ntohl (l2_table_index);
12583   mp->is_add = is_add;
12584
12585   S (mp);
12586   W (ret);
12587   return ret;
12588 }
12589
12590 static int
12591 api_ip_address_dump (vat_main_t * vam)
12592 {
12593   unformat_input_t *i = vam->input;
12594   vl_api_ip_address_dump_t *mp;
12595   vl_api_control_ping_t *mp_ping;
12596   u32 sw_if_index = ~0;
12597   u8 sw_if_index_set = 0;
12598   u8 ipv4_set = 0;
12599   u8 ipv6_set = 0;
12600   int ret;
12601
12602   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12603     {
12604       if (unformat (i, "sw_if_index %d", &sw_if_index))
12605         sw_if_index_set = 1;
12606       else
12607         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12608         sw_if_index_set = 1;
12609       else if (unformat (i, "ipv4"))
12610         ipv4_set = 1;
12611       else if (unformat (i, "ipv6"))
12612         ipv6_set = 1;
12613       else
12614         break;
12615     }
12616
12617   if (ipv4_set && ipv6_set)
12618     {
12619       errmsg ("ipv4 and ipv6 flags cannot be both set");
12620       return -99;
12621     }
12622
12623   if ((!ipv4_set) && (!ipv6_set))
12624     {
12625       errmsg ("no ipv4 nor ipv6 flag set");
12626       return -99;
12627     }
12628
12629   if (sw_if_index_set == 0)
12630     {
12631       errmsg ("missing interface name or sw_if_index");
12632       return -99;
12633     }
12634
12635   vam->current_sw_if_index = sw_if_index;
12636   vam->is_ipv6 = ipv6_set;
12637
12638   M (IP_ADDRESS_DUMP, mp);
12639   mp->sw_if_index = ntohl (sw_if_index);
12640   mp->is_ipv6 = ipv6_set;
12641   S (mp);
12642
12643   /* Use a control ping for synchronization */
12644   M (CONTROL_PING, mp_ping);
12645   S (mp_ping);
12646
12647   W (ret);
12648   return ret;
12649 }
12650
12651 static int
12652 api_ip_dump (vat_main_t * vam)
12653 {
12654   vl_api_ip_dump_t *mp;
12655   vl_api_control_ping_t *mp_ping;
12656   unformat_input_t *in = vam->input;
12657   int ipv4_set = 0;
12658   int ipv6_set = 0;
12659   int is_ipv6;
12660   int i;
12661   int ret;
12662
12663   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
12664     {
12665       if (unformat (in, "ipv4"))
12666         ipv4_set = 1;
12667       else if (unformat (in, "ipv6"))
12668         ipv6_set = 1;
12669       else
12670         break;
12671     }
12672
12673   if (ipv4_set && ipv6_set)
12674     {
12675       errmsg ("ipv4 and ipv6 flags cannot be both set");
12676       return -99;
12677     }
12678
12679   if ((!ipv4_set) && (!ipv6_set))
12680     {
12681       errmsg ("no ipv4 nor ipv6 flag set");
12682       return -99;
12683     }
12684
12685   is_ipv6 = ipv6_set;
12686   vam->is_ipv6 = is_ipv6;
12687
12688   /* free old data */
12689   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
12690     {
12691       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
12692     }
12693   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
12694
12695   M (IP_DUMP, mp);
12696   mp->is_ipv6 = ipv6_set;
12697   S (mp);
12698
12699   /* Use a control ping for synchronization */
12700   M (CONTROL_PING, mp_ping);
12701   S (mp_ping);
12702
12703   W (ret);
12704   return ret;
12705 }
12706
12707 static int
12708 api_ipsec_spd_add_del (vat_main_t * vam)
12709 {
12710   unformat_input_t *i = vam->input;
12711   vl_api_ipsec_spd_add_del_t *mp;
12712   u32 spd_id = ~0;
12713   u8 is_add = 1;
12714   int ret;
12715
12716   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12717     {
12718       if (unformat (i, "spd_id %d", &spd_id))
12719         ;
12720       else if (unformat (i, "del"))
12721         is_add = 0;
12722       else
12723         {
12724           clib_warning ("parse error '%U'", format_unformat_error, i);
12725           return -99;
12726         }
12727     }
12728   if (spd_id == ~0)
12729     {
12730       errmsg ("spd_id must be set");
12731       return -99;
12732     }
12733
12734   M (IPSEC_SPD_ADD_DEL, mp);
12735
12736   mp->spd_id = ntohl (spd_id);
12737   mp->is_add = is_add;
12738
12739   S (mp);
12740   W (ret);
12741   return ret;
12742 }
12743
12744 static int
12745 api_ipsec_interface_add_del_spd (vat_main_t * vam)
12746 {
12747   unformat_input_t *i = vam->input;
12748   vl_api_ipsec_interface_add_del_spd_t *mp;
12749   u32 sw_if_index;
12750   u8 sw_if_index_set = 0;
12751   u32 spd_id = (u32) ~ 0;
12752   u8 is_add = 1;
12753   int ret;
12754
12755   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12756     {
12757       if (unformat (i, "del"))
12758         is_add = 0;
12759       else if (unformat (i, "spd_id %d", &spd_id))
12760         ;
12761       else
12762         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12763         sw_if_index_set = 1;
12764       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12765         sw_if_index_set = 1;
12766       else
12767         {
12768           clib_warning ("parse error '%U'", format_unformat_error, i);
12769           return -99;
12770         }
12771
12772     }
12773
12774   if (spd_id == (u32) ~ 0)
12775     {
12776       errmsg ("spd_id must be set");
12777       return -99;
12778     }
12779
12780   if (sw_if_index_set == 0)
12781     {
12782       errmsg ("missing interface name or sw_if_index");
12783       return -99;
12784     }
12785
12786   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
12787
12788   mp->spd_id = ntohl (spd_id);
12789   mp->sw_if_index = ntohl (sw_if_index);
12790   mp->is_add = is_add;
12791
12792   S (mp);
12793   W (ret);
12794   return ret;
12795 }
12796
12797 static int
12798 api_ipsec_spd_add_del_entry (vat_main_t * vam)
12799 {
12800   unformat_input_t *i = vam->input;
12801   vl_api_ipsec_spd_add_del_entry_t *mp;
12802   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
12803   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
12804   i32 priority = 0;
12805   u32 rport_start = 0, rport_stop = (u32) ~ 0;
12806   u32 lport_start = 0, lport_stop = (u32) ~ 0;
12807   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
12808   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
12809   int ret;
12810
12811   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
12812   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
12813   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
12814   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
12815   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
12816   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
12817
12818   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12819     {
12820       if (unformat (i, "del"))
12821         is_add = 0;
12822       if (unformat (i, "outbound"))
12823         is_outbound = 1;
12824       if (unformat (i, "inbound"))
12825         is_outbound = 0;
12826       else if (unformat (i, "spd_id %d", &spd_id))
12827         ;
12828       else if (unformat (i, "sa_id %d", &sa_id))
12829         ;
12830       else if (unformat (i, "priority %d", &priority))
12831         ;
12832       else if (unformat (i, "protocol %d", &protocol))
12833         ;
12834       else if (unformat (i, "lport_start %d", &lport_start))
12835         ;
12836       else if (unformat (i, "lport_stop %d", &lport_stop))
12837         ;
12838       else if (unformat (i, "rport_start %d", &rport_start))
12839         ;
12840       else if (unformat (i, "rport_stop %d", &rport_stop))
12841         ;
12842       else
12843         if (unformat
12844             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
12845         {
12846           is_ipv6 = 0;
12847           is_ip_any = 0;
12848         }
12849       else
12850         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
12851         {
12852           is_ipv6 = 0;
12853           is_ip_any = 0;
12854         }
12855       else
12856         if (unformat
12857             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
12858         {
12859           is_ipv6 = 0;
12860           is_ip_any = 0;
12861         }
12862       else
12863         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
12864         {
12865           is_ipv6 = 0;
12866           is_ip_any = 0;
12867         }
12868       else
12869         if (unformat
12870             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
12871         {
12872           is_ipv6 = 1;
12873           is_ip_any = 0;
12874         }
12875       else
12876         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
12877         {
12878           is_ipv6 = 1;
12879           is_ip_any = 0;
12880         }
12881       else
12882         if (unformat
12883             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
12884         {
12885           is_ipv6 = 1;
12886           is_ip_any = 0;
12887         }
12888       else
12889         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
12890         {
12891           is_ipv6 = 1;
12892           is_ip_any = 0;
12893         }
12894       else
12895         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
12896         {
12897           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
12898             {
12899               clib_warning ("unsupported action: 'resolve'");
12900               return -99;
12901             }
12902         }
12903       else
12904         {
12905           clib_warning ("parse error '%U'", format_unformat_error, i);
12906           return -99;
12907         }
12908
12909     }
12910
12911   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
12912
12913   mp->spd_id = ntohl (spd_id);
12914   mp->priority = ntohl (priority);
12915   mp->is_outbound = is_outbound;
12916
12917   mp->is_ipv6 = is_ipv6;
12918   if (is_ipv6 || is_ip_any)
12919     {
12920       clib_memcpy (mp->remote_address_start, &raddr6_start,
12921                    sizeof (ip6_address_t));
12922       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
12923                    sizeof (ip6_address_t));
12924       clib_memcpy (mp->local_address_start, &laddr6_start,
12925                    sizeof (ip6_address_t));
12926       clib_memcpy (mp->local_address_stop, &laddr6_stop,
12927                    sizeof (ip6_address_t));
12928     }
12929   else
12930     {
12931       clib_memcpy (mp->remote_address_start, &raddr4_start,
12932                    sizeof (ip4_address_t));
12933       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
12934                    sizeof (ip4_address_t));
12935       clib_memcpy (mp->local_address_start, &laddr4_start,
12936                    sizeof (ip4_address_t));
12937       clib_memcpy (mp->local_address_stop, &laddr4_stop,
12938                    sizeof (ip4_address_t));
12939     }
12940   mp->protocol = (u8) protocol;
12941   mp->local_port_start = ntohs ((u16) lport_start);
12942   mp->local_port_stop = ntohs ((u16) lport_stop);
12943   mp->remote_port_start = ntohs ((u16) rport_start);
12944   mp->remote_port_stop = ntohs ((u16) rport_stop);
12945   mp->policy = (u8) policy;
12946   mp->sa_id = ntohl (sa_id);
12947   mp->is_add = is_add;
12948   mp->is_ip_any = is_ip_any;
12949   S (mp);
12950   W (ret);
12951   return ret;
12952 }
12953
12954 static int
12955 api_ipsec_sad_add_del_entry (vat_main_t * vam)
12956 {
12957   unformat_input_t *i = vam->input;
12958   vl_api_ipsec_sad_add_del_entry_t *mp;
12959   u32 sad_id = 0, spi = 0;
12960   u8 *ck = 0, *ik = 0;
12961   u8 is_add = 1;
12962
12963   u8 protocol = IPSEC_PROTOCOL_AH;
12964   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
12965   u32 crypto_alg = 0, integ_alg = 0;
12966   ip4_address_t tun_src4;
12967   ip4_address_t tun_dst4;
12968   ip6_address_t tun_src6;
12969   ip6_address_t tun_dst6;
12970   int ret;
12971
12972   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12973     {
12974       if (unformat (i, "del"))
12975         is_add = 0;
12976       else if (unformat (i, "sad_id %d", &sad_id))
12977         ;
12978       else if (unformat (i, "spi %d", &spi))
12979         ;
12980       else if (unformat (i, "esp"))
12981         protocol = IPSEC_PROTOCOL_ESP;
12982       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
12983         {
12984           is_tunnel = 1;
12985           is_tunnel_ipv6 = 0;
12986         }
12987       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
12988         {
12989           is_tunnel = 1;
12990           is_tunnel_ipv6 = 0;
12991         }
12992       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
12993         {
12994           is_tunnel = 1;
12995           is_tunnel_ipv6 = 1;
12996         }
12997       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
12998         {
12999           is_tunnel = 1;
13000           is_tunnel_ipv6 = 1;
13001         }
13002       else
13003         if (unformat
13004             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
13005         {
13006           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
13007               crypto_alg >= IPSEC_CRYPTO_N_ALG)
13008             {
13009               clib_warning ("unsupported crypto-alg: '%U'",
13010                             format_ipsec_crypto_alg, crypto_alg);
13011               return -99;
13012             }
13013         }
13014       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13015         ;
13016       else
13017         if (unformat
13018             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
13019         {
13020           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
13021               integ_alg >= IPSEC_INTEG_N_ALG)
13022             {
13023               clib_warning ("unsupported integ-alg: '%U'",
13024                             format_ipsec_integ_alg, integ_alg);
13025               return -99;
13026             }
13027         }
13028       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13029         ;
13030       else
13031         {
13032           clib_warning ("parse error '%U'", format_unformat_error, i);
13033           return -99;
13034         }
13035
13036     }
13037
13038   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
13039
13040   mp->sad_id = ntohl (sad_id);
13041   mp->is_add = is_add;
13042   mp->protocol = protocol;
13043   mp->spi = ntohl (spi);
13044   mp->is_tunnel = is_tunnel;
13045   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
13046   mp->crypto_algorithm = crypto_alg;
13047   mp->integrity_algorithm = integ_alg;
13048   mp->crypto_key_length = vec_len (ck);
13049   mp->integrity_key_length = vec_len (ik);
13050
13051   if (mp->crypto_key_length > sizeof (mp->crypto_key))
13052     mp->crypto_key_length = sizeof (mp->crypto_key);
13053
13054   if (mp->integrity_key_length > sizeof (mp->integrity_key))
13055     mp->integrity_key_length = sizeof (mp->integrity_key);
13056
13057   if (ck)
13058     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
13059   if (ik)
13060     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
13061
13062   if (is_tunnel)
13063     {
13064       if (is_tunnel_ipv6)
13065         {
13066           clib_memcpy (mp->tunnel_src_address, &tun_src6,
13067                        sizeof (ip6_address_t));
13068           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
13069                        sizeof (ip6_address_t));
13070         }
13071       else
13072         {
13073           clib_memcpy (mp->tunnel_src_address, &tun_src4,
13074                        sizeof (ip4_address_t));
13075           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
13076                        sizeof (ip4_address_t));
13077         }
13078     }
13079
13080   S (mp);
13081   W (ret);
13082   return ret;
13083 }
13084
13085 static int
13086 api_ipsec_sa_set_key (vat_main_t * vam)
13087 {
13088   unformat_input_t *i = vam->input;
13089   vl_api_ipsec_sa_set_key_t *mp;
13090   u32 sa_id;
13091   u8 *ck = 0, *ik = 0;
13092   int ret;
13093
13094   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13095     {
13096       if (unformat (i, "sa_id %d", &sa_id))
13097         ;
13098       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13099         ;
13100       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13101         ;
13102       else
13103         {
13104           clib_warning ("parse error '%U'", format_unformat_error, i);
13105           return -99;
13106         }
13107     }
13108
13109   M (IPSEC_SA_SET_KEY, mp);
13110
13111   mp->sa_id = ntohl (sa_id);
13112   mp->crypto_key_length = vec_len (ck);
13113   mp->integrity_key_length = vec_len (ik);
13114
13115   if (mp->crypto_key_length > sizeof (mp->crypto_key))
13116     mp->crypto_key_length = sizeof (mp->crypto_key);
13117
13118   if (mp->integrity_key_length > sizeof (mp->integrity_key))
13119     mp->integrity_key_length = sizeof (mp->integrity_key);
13120
13121   if (ck)
13122     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
13123   if (ik)
13124     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
13125
13126   S (mp);
13127   W (ret);
13128   return ret;
13129 }
13130
13131 static int
13132 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
13133 {
13134   unformat_input_t *i = vam->input;
13135   vl_api_ipsec_tunnel_if_add_del_t *mp;
13136   u32 local_spi = 0, remote_spi = 0;
13137   u32 crypto_alg = 0, integ_alg = 0;
13138   u8 *lck = NULL, *rck = NULL;
13139   u8 *lik = NULL, *rik = NULL;
13140   ip4_address_t local_ip = { {0} };
13141   ip4_address_t remote_ip = { {0} };
13142   u8 is_add = 1;
13143   u8 esn = 0;
13144   u8 anti_replay = 0;
13145   int ret;
13146
13147   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13148     {
13149       if (unformat (i, "del"))
13150         is_add = 0;
13151       else if (unformat (i, "esn"))
13152         esn = 1;
13153       else if (unformat (i, "anti_replay"))
13154         anti_replay = 1;
13155       else if (unformat (i, "local_spi %d", &local_spi))
13156         ;
13157       else if (unformat (i, "remote_spi %d", &remote_spi))
13158         ;
13159       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
13160         ;
13161       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
13162         ;
13163       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
13164         ;
13165       else
13166         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
13167         ;
13168       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
13169         ;
13170       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
13171         ;
13172       else
13173         if (unformat
13174             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
13175         {
13176           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
13177               crypto_alg >= IPSEC_CRYPTO_N_ALG)
13178             {
13179               errmsg ("unsupported crypto-alg: '%U'\n",
13180                       format_ipsec_crypto_alg, crypto_alg);
13181               return -99;
13182             }
13183         }
13184       else
13185         if (unformat
13186             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
13187         {
13188           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
13189               integ_alg >= IPSEC_INTEG_N_ALG)
13190             {
13191               errmsg ("unsupported integ-alg: '%U'\n",
13192                       format_ipsec_integ_alg, integ_alg);
13193               return -99;
13194             }
13195         }
13196       else
13197         {
13198           errmsg ("parse error '%U'\n", format_unformat_error, i);
13199           return -99;
13200         }
13201     }
13202
13203   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
13204
13205   mp->is_add = is_add;
13206   mp->esn = esn;
13207   mp->anti_replay = anti_replay;
13208
13209   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
13210   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
13211
13212   mp->local_spi = htonl (local_spi);
13213   mp->remote_spi = htonl (remote_spi);
13214   mp->crypto_alg = (u8) crypto_alg;
13215
13216   mp->local_crypto_key_len = 0;
13217   if (lck)
13218     {
13219       mp->local_crypto_key_len = vec_len (lck);
13220       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
13221         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
13222       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
13223     }
13224
13225   mp->remote_crypto_key_len = 0;
13226   if (rck)
13227     {
13228       mp->remote_crypto_key_len = vec_len (rck);
13229       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
13230         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
13231       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
13232     }
13233
13234   mp->integ_alg = (u8) integ_alg;
13235
13236   mp->local_integ_key_len = 0;
13237   if (lik)
13238     {
13239       mp->local_integ_key_len = vec_len (lik);
13240       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
13241         mp->local_integ_key_len = sizeof (mp->local_integ_key);
13242       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
13243     }
13244
13245   mp->remote_integ_key_len = 0;
13246   if (rik)
13247     {
13248       mp->remote_integ_key_len = vec_len (rik);
13249       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
13250         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
13251       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
13252     }
13253
13254   S (mp);
13255   W (ret);
13256   return ret;
13257 }
13258
13259 static int
13260 api_ikev2_profile_add_del (vat_main_t * vam)
13261 {
13262   unformat_input_t *i = vam->input;
13263   vl_api_ikev2_profile_add_del_t *mp;
13264   u8 is_add = 1;
13265   u8 *name = 0;
13266   int ret;
13267
13268   const char *valid_chars = "a-zA-Z0-9_";
13269
13270   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13271     {
13272       if (unformat (i, "del"))
13273         is_add = 0;
13274       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13275         vec_add1 (name, 0);
13276       else
13277         {
13278           errmsg ("parse error '%U'", format_unformat_error, i);
13279           return -99;
13280         }
13281     }
13282
13283   if (!vec_len (name))
13284     {
13285       errmsg ("profile name must be specified");
13286       return -99;
13287     }
13288
13289   if (vec_len (name) > 64)
13290     {
13291       errmsg ("profile name too long");
13292       return -99;
13293     }
13294
13295   M (IKEV2_PROFILE_ADD_DEL, mp);
13296
13297   clib_memcpy (mp->name, name, vec_len (name));
13298   mp->is_add = is_add;
13299   vec_free (name);
13300
13301   S (mp);
13302   W (ret);
13303   return ret;
13304 }
13305
13306 static int
13307 api_ikev2_profile_set_auth (vat_main_t * vam)
13308 {
13309   unformat_input_t *i = vam->input;
13310   vl_api_ikev2_profile_set_auth_t *mp;
13311   u8 *name = 0;
13312   u8 *data = 0;
13313   u32 auth_method = 0;
13314   u8 is_hex = 0;
13315   int ret;
13316
13317   const char *valid_chars = "a-zA-Z0-9_";
13318
13319   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13320     {
13321       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13322         vec_add1 (name, 0);
13323       else if (unformat (i, "auth_method %U",
13324                          unformat_ikev2_auth_method, &auth_method))
13325         ;
13326       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
13327         is_hex = 1;
13328       else if (unformat (i, "auth_data %v", &data))
13329         ;
13330       else
13331         {
13332           errmsg ("parse error '%U'", format_unformat_error, i);
13333           return -99;
13334         }
13335     }
13336
13337   if (!vec_len (name))
13338     {
13339       errmsg ("profile name must be specified");
13340       return -99;
13341     }
13342
13343   if (vec_len (name) > 64)
13344     {
13345       errmsg ("profile name too long");
13346       return -99;
13347     }
13348
13349   if (!vec_len (data))
13350     {
13351       errmsg ("auth_data must be specified");
13352       return -99;
13353     }
13354
13355   if (!auth_method)
13356     {
13357       errmsg ("auth_method must be specified");
13358       return -99;
13359     }
13360
13361   M (IKEV2_PROFILE_SET_AUTH, mp);
13362
13363   mp->is_hex = is_hex;
13364   mp->auth_method = (u8) auth_method;
13365   mp->data_len = vec_len (data);
13366   clib_memcpy (mp->name, name, vec_len (name));
13367   clib_memcpy (mp->data, data, vec_len (data));
13368   vec_free (name);
13369   vec_free (data);
13370
13371   S (mp);
13372   W (ret);
13373   return ret;
13374 }
13375
13376 static int
13377 api_ikev2_profile_set_id (vat_main_t * vam)
13378 {
13379   unformat_input_t *i = vam->input;
13380   vl_api_ikev2_profile_set_id_t *mp;
13381   u8 *name = 0;
13382   u8 *data = 0;
13383   u8 is_local = 0;
13384   u32 id_type = 0;
13385   ip4_address_t ip4;
13386   int ret;
13387
13388   const char *valid_chars = "a-zA-Z0-9_";
13389
13390   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13391     {
13392       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13393         vec_add1 (name, 0);
13394       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
13395         ;
13396       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
13397         {
13398           data = vec_new (u8, 4);
13399           clib_memcpy (data, ip4.as_u8, 4);
13400         }
13401       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
13402         ;
13403       else if (unformat (i, "id_data %v", &data))
13404         ;
13405       else if (unformat (i, "local"))
13406         is_local = 1;
13407       else if (unformat (i, "remote"))
13408         is_local = 0;
13409       else
13410         {
13411           errmsg ("parse error '%U'", format_unformat_error, i);
13412           return -99;
13413         }
13414     }
13415
13416   if (!vec_len (name))
13417     {
13418       errmsg ("profile name must be specified");
13419       return -99;
13420     }
13421
13422   if (vec_len (name) > 64)
13423     {
13424       errmsg ("profile name too long");
13425       return -99;
13426     }
13427
13428   if (!vec_len (data))
13429     {
13430       errmsg ("id_data must be specified");
13431       return -99;
13432     }
13433
13434   if (!id_type)
13435     {
13436       errmsg ("id_type must be specified");
13437       return -99;
13438     }
13439
13440   M (IKEV2_PROFILE_SET_ID, mp);
13441
13442   mp->is_local = is_local;
13443   mp->id_type = (u8) id_type;
13444   mp->data_len = vec_len (data);
13445   clib_memcpy (mp->name, name, vec_len (name));
13446   clib_memcpy (mp->data, data, vec_len (data));
13447   vec_free (name);
13448   vec_free (data);
13449
13450   S (mp);
13451   W (ret);
13452   return ret;
13453 }
13454
13455 static int
13456 api_ikev2_profile_set_ts (vat_main_t * vam)
13457 {
13458   unformat_input_t *i = vam->input;
13459   vl_api_ikev2_profile_set_ts_t *mp;
13460   u8 *name = 0;
13461   u8 is_local = 0;
13462   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
13463   ip4_address_t start_addr, end_addr;
13464
13465   const char *valid_chars = "a-zA-Z0-9_";
13466   int ret;
13467
13468   start_addr.as_u32 = 0;
13469   end_addr.as_u32 = (u32) ~ 0;
13470
13471   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13472     {
13473       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13474         vec_add1 (name, 0);
13475       else if (unformat (i, "protocol %d", &proto))
13476         ;
13477       else if (unformat (i, "start_port %d", &start_port))
13478         ;
13479       else if (unformat (i, "end_port %d", &end_port))
13480         ;
13481       else
13482         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
13483         ;
13484       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
13485         ;
13486       else if (unformat (i, "local"))
13487         is_local = 1;
13488       else if (unformat (i, "remote"))
13489         is_local = 0;
13490       else
13491         {
13492           errmsg ("parse error '%U'", format_unformat_error, i);
13493           return -99;
13494         }
13495     }
13496
13497   if (!vec_len (name))
13498     {
13499       errmsg ("profile name must be specified");
13500       return -99;
13501     }
13502
13503   if (vec_len (name) > 64)
13504     {
13505       errmsg ("profile name too long");
13506       return -99;
13507     }
13508
13509   M (IKEV2_PROFILE_SET_TS, mp);
13510
13511   mp->is_local = is_local;
13512   mp->proto = (u8) proto;
13513   mp->start_port = (u16) start_port;
13514   mp->end_port = (u16) end_port;
13515   mp->start_addr = start_addr.as_u32;
13516   mp->end_addr = end_addr.as_u32;
13517   clib_memcpy (mp->name, name, vec_len (name));
13518   vec_free (name);
13519
13520   S (mp);
13521   W (ret);
13522   return ret;
13523 }
13524
13525 static int
13526 api_ikev2_set_local_key (vat_main_t * vam)
13527 {
13528   unformat_input_t *i = vam->input;
13529   vl_api_ikev2_set_local_key_t *mp;
13530   u8 *file = 0;
13531   int ret;
13532
13533   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13534     {
13535       if (unformat (i, "file %v", &file))
13536         vec_add1 (file, 0);
13537       else
13538         {
13539           errmsg ("parse error '%U'", format_unformat_error, i);
13540           return -99;
13541         }
13542     }
13543
13544   if (!vec_len (file))
13545     {
13546       errmsg ("RSA key file must be specified");
13547       return -99;
13548     }
13549
13550   if (vec_len (file) > 256)
13551     {
13552       errmsg ("file name too long");
13553       return -99;
13554     }
13555
13556   M (IKEV2_SET_LOCAL_KEY, mp);
13557
13558   clib_memcpy (mp->key_file, file, vec_len (file));
13559   vec_free (file);
13560
13561   S (mp);
13562   W (ret);
13563   return ret;
13564 }
13565
13566 static int
13567 api_ikev2_set_responder (vat_main_t * vam)
13568 {
13569   unformat_input_t *i = vam->input;
13570   vl_api_ikev2_set_responder_t *mp;
13571   int ret;
13572   u8 *name = 0;
13573   u32 sw_if_index = ~0;
13574   ip4_address_t address;
13575
13576   const char *valid_chars = "a-zA-Z0-9_";
13577
13578   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13579     {
13580       if (unformat
13581           (i, "%U interface %d address %U", unformat_token, valid_chars,
13582            &name, &sw_if_index, unformat_ip4_address, &address))
13583         vec_add1 (name, 0);
13584       else
13585         {
13586           errmsg ("parse error '%U'", format_unformat_error, i);
13587           return -99;
13588         }
13589     }
13590
13591   if (!vec_len (name))
13592     {
13593       errmsg ("profile name must be specified");
13594       return -99;
13595     }
13596
13597   if (vec_len (name) > 64)
13598     {
13599       errmsg ("profile name too long");
13600       return -99;
13601     }
13602
13603   M (IKEV2_SET_RESPONDER, mp);
13604
13605   clib_memcpy (mp->name, name, vec_len (name));
13606   vec_free (name);
13607
13608   mp->sw_if_index = sw_if_index;
13609   clib_memcpy (mp->address, &address, sizeof (address));
13610
13611   S (mp);
13612   W (ret);
13613   return ret;
13614 }
13615
13616 static int
13617 api_ikev2_set_ike_transforms (vat_main_t * vam)
13618 {
13619   unformat_input_t *i = vam->input;
13620   vl_api_ikev2_set_ike_transforms_t *mp;
13621   int ret;
13622   u8 *name = 0;
13623   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13624
13625   const char *valid_chars = "a-zA-Z0-9_";
13626
13627   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13628     {
13629       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13630                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13631         vec_add1 (name, 0);
13632       else
13633         {
13634           errmsg ("parse error '%U'", format_unformat_error, i);
13635           return -99;
13636         }
13637     }
13638
13639   if (!vec_len (name))
13640     {
13641       errmsg ("profile name must be specified");
13642       return -99;
13643     }
13644
13645   if (vec_len (name) > 64)
13646     {
13647       errmsg ("profile name too long");
13648       return -99;
13649     }
13650
13651   M (IKEV2_SET_IKE_TRANSFORMS, mp);
13652
13653   clib_memcpy (mp->name, name, vec_len (name));
13654   vec_free (name);
13655   mp->crypto_alg = crypto_alg;
13656   mp->crypto_key_size = crypto_key_size;
13657   mp->integ_alg = integ_alg;
13658   mp->dh_group = dh_group;
13659
13660   S (mp);
13661   W (ret);
13662   return ret;
13663 }
13664
13665
13666 static int
13667 api_ikev2_set_esp_transforms (vat_main_t * vam)
13668 {
13669   unformat_input_t *i = vam->input;
13670   vl_api_ikev2_set_esp_transforms_t *mp;
13671   int ret;
13672   u8 *name = 0;
13673   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13674
13675   const char *valid_chars = "a-zA-Z0-9_";
13676
13677   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13678     {
13679       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13680                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13681         vec_add1 (name, 0);
13682       else
13683         {
13684           errmsg ("parse error '%U'", format_unformat_error, i);
13685           return -99;
13686         }
13687     }
13688
13689   if (!vec_len (name))
13690     {
13691       errmsg ("profile name must be specified");
13692       return -99;
13693     }
13694
13695   if (vec_len (name) > 64)
13696     {
13697       errmsg ("profile name too long");
13698       return -99;
13699     }
13700
13701   M (IKEV2_SET_ESP_TRANSFORMS, mp);
13702
13703   clib_memcpy (mp->name, name, vec_len (name));
13704   vec_free (name);
13705   mp->crypto_alg = crypto_alg;
13706   mp->crypto_key_size = crypto_key_size;
13707   mp->integ_alg = integ_alg;
13708   mp->dh_group = dh_group;
13709
13710   S (mp);
13711   W (ret);
13712   return ret;
13713 }
13714
13715 static int
13716 api_ikev2_set_sa_lifetime (vat_main_t * vam)
13717 {
13718   unformat_input_t *i = vam->input;
13719   vl_api_ikev2_set_sa_lifetime_t *mp;
13720   int ret;
13721   u8 *name = 0;
13722   u64 lifetime, lifetime_maxdata;
13723   u32 lifetime_jitter, handover;
13724
13725   const char *valid_chars = "a-zA-Z0-9_";
13726
13727   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13728     {
13729       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
13730                     &lifetime, &lifetime_jitter, &handover,
13731                     &lifetime_maxdata))
13732         vec_add1 (name, 0);
13733       else
13734         {
13735           errmsg ("parse error '%U'", format_unformat_error, i);
13736           return -99;
13737         }
13738     }
13739
13740   if (!vec_len (name))
13741     {
13742       errmsg ("profile name must be specified");
13743       return -99;
13744     }
13745
13746   if (vec_len (name) > 64)
13747     {
13748       errmsg ("profile name too long");
13749       return -99;
13750     }
13751
13752   M (IKEV2_SET_SA_LIFETIME, mp);
13753
13754   clib_memcpy (mp->name, name, vec_len (name));
13755   vec_free (name);
13756   mp->lifetime = lifetime;
13757   mp->lifetime_jitter = lifetime_jitter;
13758   mp->handover = handover;
13759   mp->lifetime_maxdata = lifetime_maxdata;
13760
13761   S (mp);
13762   W (ret);
13763   return ret;
13764 }
13765
13766 static int
13767 api_ikev2_initiate_sa_init (vat_main_t * vam)
13768 {
13769   unformat_input_t *i = vam->input;
13770   vl_api_ikev2_initiate_sa_init_t *mp;
13771   int ret;
13772   u8 *name = 0;
13773
13774   const char *valid_chars = "a-zA-Z0-9_";
13775
13776   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13777     {
13778       if (unformat (i, "%U", unformat_token, valid_chars, &name))
13779         vec_add1 (name, 0);
13780       else
13781         {
13782           errmsg ("parse error '%U'", format_unformat_error, i);
13783           return -99;
13784         }
13785     }
13786
13787   if (!vec_len (name))
13788     {
13789       errmsg ("profile name must be specified");
13790       return -99;
13791     }
13792
13793   if (vec_len (name) > 64)
13794     {
13795       errmsg ("profile name too long");
13796       return -99;
13797     }
13798
13799   M (IKEV2_INITIATE_SA_INIT, mp);
13800
13801   clib_memcpy (mp->name, name, vec_len (name));
13802   vec_free (name);
13803
13804   S (mp);
13805   W (ret);
13806   return ret;
13807 }
13808
13809 static int
13810 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
13811 {
13812   unformat_input_t *i = vam->input;
13813   vl_api_ikev2_initiate_del_ike_sa_t *mp;
13814   int ret;
13815   u64 ispi;
13816
13817
13818   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13819     {
13820       if (unformat (i, "%lx", &ispi))
13821         ;
13822       else
13823         {
13824           errmsg ("parse error '%U'", format_unformat_error, i);
13825           return -99;
13826         }
13827     }
13828
13829   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
13830
13831   mp->ispi = ispi;
13832
13833   S (mp);
13834   W (ret);
13835   return ret;
13836 }
13837
13838 static int
13839 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
13840 {
13841   unformat_input_t *i = vam->input;
13842   vl_api_ikev2_initiate_del_child_sa_t *mp;
13843   int ret;
13844   u32 ispi;
13845
13846
13847   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13848     {
13849       if (unformat (i, "%x", &ispi))
13850         ;
13851       else
13852         {
13853           errmsg ("parse error '%U'", format_unformat_error, i);
13854           return -99;
13855         }
13856     }
13857
13858   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
13859
13860   mp->ispi = ispi;
13861
13862   S (mp);
13863   W (ret);
13864   return ret;
13865 }
13866
13867 static int
13868 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
13869 {
13870   unformat_input_t *i = vam->input;
13871   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
13872   int ret;
13873   u32 ispi;
13874
13875
13876   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13877     {
13878       if (unformat (i, "%x", &ispi))
13879         ;
13880       else
13881         {
13882           errmsg ("parse error '%U'", format_unformat_error, i);
13883           return -99;
13884         }
13885     }
13886
13887   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
13888
13889   mp->ispi = ispi;
13890
13891   S (mp);
13892   W (ret);
13893   return ret;
13894 }
13895
13896 /*
13897  * MAP
13898  */
13899 static int
13900 api_map_add_domain (vat_main_t * vam)
13901 {
13902   unformat_input_t *i = vam->input;
13903   vl_api_map_add_domain_t *mp;
13904
13905   ip4_address_t ip4_prefix;
13906   ip6_address_t ip6_prefix;
13907   ip6_address_t ip6_src;
13908   u32 num_m_args = 0;
13909   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
13910     0, psid_length = 0;
13911   u8 is_translation = 0;
13912   u32 mtu = 0;
13913   u32 ip6_src_len = 128;
13914   int ret;
13915
13916   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13917     {
13918       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
13919                     &ip4_prefix, &ip4_prefix_len))
13920         num_m_args++;
13921       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
13922                          &ip6_prefix, &ip6_prefix_len))
13923         num_m_args++;
13924       else
13925         if (unformat
13926             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
13927              &ip6_src_len))
13928         num_m_args++;
13929       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
13930         num_m_args++;
13931       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
13932         num_m_args++;
13933       else if (unformat (i, "psid-offset %d", &psid_offset))
13934         num_m_args++;
13935       else if (unformat (i, "psid-len %d", &psid_length))
13936         num_m_args++;
13937       else if (unformat (i, "mtu %d", &mtu))
13938         num_m_args++;
13939       else if (unformat (i, "map-t"))
13940         is_translation = 1;
13941       else
13942         {
13943           clib_warning ("parse error '%U'", format_unformat_error, i);
13944           return -99;
13945         }
13946     }
13947
13948   if (num_m_args < 3)
13949     {
13950       errmsg ("mandatory argument(s) missing");
13951       return -99;
13952     }
13953
13954   /* Construct the API message */
13955   M (MAP_ADD_DOMAIN, mp);
13956
13957   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
13958   mp->ip4_prefix_len = ip4_prefix_len;
13959
13960   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
13961   mp->ip6_prefix_len = ip6_prefix_len;
13962
13963   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
13964   mp->ip6_src_prefix_len = ip6_src_len;
13965
13966   mp->ea_bits_len = ea_bits_len;
13967   mp->psid_offset = psid_offset;
13968   mp->psid_length = psid_length;
13969   mp->is_translation = is_translation;
13970   mp->mtu = htons (mtu);
13971
13972   /* send it... */
13973   S (mp);
13974
13975   /* Wait for a reply, return good/bad news  */
13976   W (ret);
13977   return ret;
13978 }
13979
13980 static int
13981 api_map_del_domain (vat_main_t * vam)
13982 {
13983   unformat_input_t *i = vam->input;
13984   vl_api_map_del_domain_t *mp;
13985
13986   u32 num_m_args = 0;
13987   u32 index;
13988   int ret;
13989
13990   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13991     {
13992       if (unformat (i, "index %d", &index))
13993         num_m_args++;
13994       else
13995         {
13996           clib_warning ("parse error '%U'", format_unformat_error, i);
13997           return -99;
13998         }
13999     }
14000
14001   if (num_m_args != 1)
14002     {
14003       errmsg ("mandatory argument(s) missing");
14004       return -99;
14005     }
14006
14007   /* Construct the API message */
14008   M (MAP_DEL_DOMAIN, mp);
14009
14010   mp->index = ntohl (index);
14011
14012   /* send it... */
14013   S (mp);
14014
14015   /* Wait for a reply, return good/bad news  */
14016   W (ret);
14017   return ret;
14018 }
14019
14020 static int
14021 api_map_add_del_rule (vat_main_t * vam)
14022 {
14023   unformat_input_t *i = vam->input;
14024   vl_api_map_add_del_rule_t *mp;
14025   u8 is_add = 1;
14026   ip6_address_t ip6_dst;
14027   u32 num_m_args = 0, index, psid = 0;
14028   int ret;
14029
14030   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14031     {
14032       if (unformat (i, "index %d", &index))
14033         num_m_args++;
14034       else if (unformat (i, "psid %d", &psid))
14035         num_m_args++;
14036       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
14037         num_m_args++;
14038       else if (unformat (i, "del"))
14039         {
14040           is_add = 0;
14041         }
14042       else
14043         {
14044           clib_warning ("parse error '%U'", format_unformat_error, i);
14045           return -99;
14046         }
14047     }
14048
14049   /* Construct the API message */
14050   M (MAP_ADD_DEL_RULE, mp);
14051
14052   mp->index = ntohl (index);
14053   mp->is_add = is_add;
14054   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
14055   mp->psid = ntohs (psid);
14056
14057   /* send it... */
14058   S (mp);
14059
14060   /* Wait for a reply, return good/bad news  */
14061   W (ret);
14062   return ret;
14063 }
14064
14065 static int
14066 api_map_domain_dump (vat_main_t * vam)
14067 {
14068   vl_api_map_domain_dump_t *mp;
14069   vl_api_control_ping_t *mp_ping;
14070   int ret;
14071
14072   /* Construct the API message */
14073   M (MAP_DOMAIN_DUMP, mp);
14074
14075   /* send it... */
14076   S (mp);
14077
14078   /* Use a control ping for synchronization */
14079   M (CONTROL_PING, mp_ping);
14080   S (mp_ping);
14081
14082   W (ret);
14083   return ret;
14084 }
14085
14086 static int
14087 api_map_rule_dump (vat_main_t * vam)
14088 {
14089   unformat_input_t *i = vam->input;
14090   vl_api_map_rule_dump_t *mp;
14091   vl_api_control_ping_t *mp_ping;
14092   u32 domain_index = ~0;
14093   int ret;
14094
14095   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14096     {
14097       if (unformat (i, "index %u", &domain_index))
14098         ;
14099       else
14100         break;
14101     }
14102
14103   if (domain_index == ~0)
14104     {
14105       clib_warning ("parse error: domain index expected");
14106       return -99;
14107     }
14108
14109   /* Construct the API message */
14110   M (MAP_RULE_DUMP, mp);
14111
14112   mp->domain_index = htonl (domain_index);
14113
14114   /* send it... */
14115   S (mp);
14116
14117   /* Use a control ping for synchronization */
14118   M (CONTROL_PING, mp_ping);
14119   S (mp_ping);
14120
14121   W (ret);
14122   return ret;
14123 }
14124
14125 static void vl_api_map_add_domain_reply_t_handler
14126   (vl_api_map_add_domain_reply_t * mp)
14127 {
14128   vat_main_t *vam = &vat_main;
14129   i32 retval = ntohl (mp->retval);
14130
14131   if (vam->async_mode)
14132     {
14133       vam->async_errors += (retval < 0);
14134     }
14135   else
14136     {
14137       vam->retval = retval;
14138       vam->result_ready = 1;
14139     }
14140 }
14141
14142 static void vl_api_map_add_domain_reply_t_handler_json
14143   (vl_api_map_add_domain_reply_t * mp)
14144 {
14145   vat_main_t *vam = &vat_main;
14146   vat_json_node_t node;
14147
14148   vat_json_init_object (&node);
14149   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
14150   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
14151
14152   vat_json_print (vam->ofp, &node);
14153   vat_json_free (&node);
14154
14155   vam->retval = ntohl (mp->retval);
14156   vam->result_ready = 1;
14157 }
14158
14159 static int
14160 api_get_first_msg_id (vat_main_t * vam)
14161 {
14162   vl_api_get_first_msg_id_t *mp;
14163   unformat_input_t *i = vam->input;
14164   u8 *name;
14165   u8 name_set = 0;
14166   int ret;
14167
14168   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14169     {
14170       if (unformat (i, "client %s", &name))
14171         name_set = 1;
14172       else
14173         break;
14174     }
14175
14176   if (name_set == 0)
14177     {
14178       errmsg ("missing client name");
14179       return -99;
14180     }
14181   vec_add1 (name, 0);
14182
14183   if (vec_len (name) > 63)
14184     {
14185       errmsg ("client name too long");
14186       return -99;
14187     }
14188
14189   M (GET_FIRST_MSG_ID, mp);
14190   clib_memcpy (mp->name, name, vec_len (name));
14191   S (mp);
14192   W (ret);
14193   return ret;
14194 }
14195
14196 static int
14197 api_cop_interface_enable_disable (vat_main_t * vam)
14198 {
14199   unformat_input_t *line_input = vam->input;
14200   vl_api_cop_interface_enable_disable_t *mp;
14201   u32 sw_if_index = ~0;
14202   u8 enable_disable = 1;
14203   int ret;
14204
14205   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14206     {
14207       if (unformat (line_input, "disable"))
14208         enable_disable = 0;
14209       if (unformat (line_input, "enable"))
14210         enable_disable = 1;
14211       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14212                          vam, &sw_if_index))
14213         ;
14214       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14215         ;
14216       else
14217         break;
14218     }
14219
14220   if (sw_if_index == ~0)
14221     {
14222       errmsg ("missing interface name or sw_if_index");
14223       return -99;
14224     }
14225
14226   /* Construct the API message */
14227   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14228   mp->sw_if_index = ntohl (sw_if_index);
14229   mp->enable_disable = enable_disable;
14230
14231   /* send it... */
14232   S (mp);
14233   /* Wait for the reply */
14234   W (ret);
14235   return ret;
14236 }
14237
14238 static int
14239 api_cop_whitelist_enable_disable (vat_main_t * vam)
14240 {
14241   unformat_input_t *line_input = vam->input;
14242   vl_api_cop_whitelist_enable_disable_t *mp;
14243   u32 sw_if_index = ~0;
14244   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14245   u32 fib_id = 0;
14246   int ret;
14247
14248   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14249     {
14250       if (unformat (line_input, "ip4"))
14251         ip4 = 1;
14252       else if (unformat (line_input, "ip6"))
14253         ip6 = 1;
14254       else if (unformat (line_input, "default"))
14255         default_cop = 1;
14256       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14257                          vam, &sw_if_index))
14258         ;
14259       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14260         ;
14261       else if (unformat (line_input, "fib-id %d", &fib_id))
14262         ;
14263       else
14264         break;
14265     }
14266
14267   if (sw_if_index == ~0)
14268     {
14269       errmsg ("missing interface name or sw_if_index");
14270       return -99;
14271     }
14272
14273   /* Construct the API message */
14274   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14275   mp->sw_if_index = ntohl (sw_if_index);
14276   mp->fib_id = ntohl (fib_id);
14277   mp->ip4 = ip4;
14278   mp->ip6 = ip6;
14279   mp->default_cop = default_cop;
14280
14281   /* send it... */
14282   S (mp);
14283   /* Wait for the reply */
14284   W (ret);
14285   return ret;
14286 }
14287
14288 static int
14289 api_get_node_graph (vat_main_t * vam)
14290 {
14291   vl_api_get_node_graph_t *mp;
14292   int ret;
14293
14294   M (GET_NODE_GRAPH, mp);
14295
14296   /* send it... */
14297   S (mp);
14298   /* Wait for the reply */
14299   W (ret);
14300   return ret;
14301 }
14302
14303 /* *INDENT-OFF* */
14304 /** Used for parsing LISP eids */
14305 typedef CLIB_PACKED(struct{
14306   u8 addr[16];   /**< eid address */
14307   u32 len;       /**< prefix length if IP */
14308   u8 type;      /**< type of eid */
14309 }) lisp_eid_vat_t;
14310 /* *INDENT-ON* */
14311
14312 static uword
14313 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14314 {
14315   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14316
14317   memset (a, 0, sizeof (a[0]));
14318
14319   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
14320     {
14321       a->type = 0;              /* ipv4 type */
14322     }
14323   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
14324     {
14325       a->type = 1;              /* ipv6 type */
14326     }
14327   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
14328     {
14329       a->type = 2;              /* mac type */
14330     }
14331   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
14332     {
14333       a->type = 3;              /* NSH type */
14334       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
14335       nsh->spi = clib_host_to_net_u32 (nsh->spi);
14336     }
14337   else
14338     {
14339       return 0;
14340     }
14341
14342   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
14343     {
14344       return 0;
14345     }
14346
14347   return 1;
14348 }
14349
14350 static int
14351 lisp_eid_size_vat (u8 type)
14352 {
14353   switch (type)
14354     {
14355     case 0:
14356       return 4;
14357     case 1:
14358       return 16;
14359     case 2:
14360       return 6;
14361     case 3:
14362       return 5;
14363     }
14364   return 0;
14365 }
14366
14367 static void
14368 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
14369 {
14370   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
14371 }
14372
14373 static int
14374 api_one_add_del_locator_set (vat_main_t * vam)
14375 {
14376   unformat_input_t *input = vam->input;
14377   vl_api_one_add_del_locator_set_t *mp;
14378   u8 is_add = 1;
14379   u8 *locator_set_name = NULL;
14380   u8 locator_set_name_set = 0;
14381   vl_api_local_locator_t locator, *locators = 0;
14382   u32 sw_if_index, priority, weight;
14383   u32 data_len = 0;
14384
14385   int ret;
14386   /* Parse args required to build the message */
14387   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14388     {
14389       if (unformat (input, "del"))
14390         {
14391           is_add = 0;
14392         }
14393       else if (unformat (input, "locator-set %s", &locator_set_name))
14394         {
14395           locator_set_name_set = 1;
14396         }
14397       else if (unformat (input, "sw_if_index %u p %u w %u",
14398                          &sw_if_index, &priority, &weight))
14399         {
14400           locator.sw_if_index = htonl (sw_if_index);
14401           locator.priority = priority;
14402           locator.weight = weight;
14403           vec_add1 (locators, locator);
14404         }
14405       else
14406         if (unformat
14407             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14408              &sw_if_index, &priority, &weight))
14409         {
14410           locator.sw_if_index = htonl (sw_if_index);
14411           locator.priority = priority;
14412           locator.weight = weight;
14413           vec_add1 (locators, locator);
14414         }
14415       else
14416         break;
14417     }
14418
14419   if (locator_set_name_set == 0)
14420     {
14421       errmsg ("missing locator-set name");
14422       vec_free (locators);
14423       return -99;
14424     }
14425
14426   if (vec_len (locator_set_name) > 64)
14427     {
14428       errmsg ("locator-set name too long");
14429       vec_free (locator_set_name);
14430       vec_free (locators);
14431       return -99;
14432     }
14433   vec_add1 (locator_set_name, 0);
14434
14435   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14436
14437   /* Construct the API message */
14438   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14439
14440   mp->is_add = is_add;
14441   clib_memcpy (mp->locator_set_name, locator_set_name,
14442                vec_len (locator_set_name));
14443   vec_free (locator_set_name);
14444
14445   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14446   if (locators)
14447     clib_memcpy (mp->locators, locators, data_len);
14448   vec_free (locators);
14449
14450   /* send it... */
14451   S (mp);
14452
14453   /* Wait for a reply... */
14454   W (ret);
14455   return ret;
14456 }
14457
14458 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14459
14460 static int
14461 api_one_add_del_locator (vat_main_t * vam)
14462 {
14463   unformat_input_t *input = vam->input;
14464   vl_api_one_add_del_locator_t *mp;
14465   u32 tmp_if_index = ~0;
14466   u32 sw_if_index = ~0;
14467   u8 sw_if_index_set = 0;
14468   u8 sw_if_index_if_name_set = 0;
14469   u32 priority = ~0;
14470   u8 priority_set = 0;
14471   u32 weight = ~0;
14472   u8 weight_set = 0;
14473   u8 is_add = 1;
14474   u8 *locator_set_name = NULL;
14475   u8 locator_set_name_set = 0;
14476   int ret;
14477
14478   /* Parse args required to build the message */
14479   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14480     {
14481       if (unformat (input, "del"))
14482         {
14483           is_add = 0;
14484         }
14485       else if (unformat (input, "locator-set %s", &locator_set_name))
14486         {
14487           locator_set_name_set = 1;
14488         }
14489       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14490                          &tmp_if_index))
14491         {
14492           sw_if_index_if_name_set = 1;
14493           sw_if_index = tmp_if_index;
14494         }
14495       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14496         {
14497           sw_if_index_set = 1;
14498           sw_if_index = tmp_if_index;
14499         }
14500       else if (unformat (input, "p %d", &priority))
14501         {
14502           priority_set = 1;
14503         }
14504       else if (unformat (input, "w %d", &weight))
14505         {
14506           weight_set = 1;
14507         }
14508       else
14509         break;
14510     }
14511
14512   if (locator_set_name_set == 0)
14513     {
14514       errmsg ("missing locator-set name");
14515       return -99;
14516     }
14517
14518   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14519     {
14520       errmsg ("missing sw_if_index");
14521       vec_free (locator_set_name);
14522       return -99;
14523     }
14524
14525   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14526     {
14527       errmsg ("cannot use both params interface name and sw_if_index");
14528       vec_free (locator_set_name);
14529       return -99;
14530     }
14531
14532   if (priority_set == 0)
14533     {
14534       errmsg ("missing locator-set priority");
14535       vec_free (locator_set_name);
14536       return -99;
14537     }
14538
14539   if (weight_set == 0)
14540     {
14541       errmsg ("missing locator-set weight");
14542       vec_free (locator_set_name);
14543       return -99;
14544     }
14545
14546   if (vec_len (locator_set_name) > 64)
14547     {
14548       errmsg ("locator-set name too long");
14549       vec_free (locator_set_name);
14550       return -99;
14551     }
14552   vec_add1 (locator_set_name, 0);
14553
14554   /* Construct the API message */
14555   M (ONE_ADD_DEL_LOCATOR, mp);
14556
14557   mp->is_add = is_add;
14558   mp->sw_if_index = ntohl (sw_if_index);
14559   mp->priority = priority;
14560   mp->weight = weight;
14561   clib_memcpy (mp->locator_set_name, locator_set_name,
14562                vec_len (locator_set_name));
14563   vec_free (locator_set_name);
14564
14565   /* send it... */
14566   S (mp);
14567
14568   /* Wait for a reply... */
14569   W (ret);
14570   return ret;
14571 }
14572
14573 #define api_lisp_add_del_locator api_one_add_del_locator
14574
14575 uword
14576 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14577 {
14578   u32 *key_id = va_arg (*args, u32 *);
14579   u8 *s = 0;
14580
14581   if (unformat (input, "%s", &s))
14582     {
14583       if (!strcmp ((char *) s, "sha1"))
14584         key_id[0] = HMAC_SHA_1_96;
14585       else if (!strcmp ((char *) s, "sha256"))
14586         key_id[0] = HMAC_SHA_256_128;
14587       else
14588         {
14589           clib_warning ("invalid key_id: '%s'", s);
14590           key_id[0] = HMAC_NO_KEY;
14591         }
14592     }
14593   else
14594     return 0;
14595
14596   vec_free (s);
14597   return 1;
14598 }
14599
14600 static int
14601 api_one_add_del_local_eid (vat_main_t * vam)
14602 {
14603   unformat_input_t *input = vam->input;
14604   vl_api_one_add_del_local_eid_t *mp;
14605   u8 is_add = 1;
14606   u8 eid_set = 0;
14607   lisp_eid_vat_t _eid, *eid = &_eid;
14608   u8 *locator_set_name = 0;
14609   u8 locator_set_name_set = 0;
14610   u32 vni = 0;
14611   u16 key_id = 0;
14612   u8 *key = 0;
14613   int ret;
14614
14615   /* Parse args required to build the message */
14616   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14617     {
14618       if (unformat (input, "del"))
14619         {
14620           is_add = 0;
14621         }
14622       else if (unformat (input, "vni %d", &vni))
14623         {
14624           ;
14625         }
14626       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14627         {
14628           eid_set = 1;
14629         }
14630       else if (unformat (input, "locator-set %s", &locator_set_name))
14631         {
14632           locator_set_name_set = 1;
14633         }
14634       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14635         ;
14636       else if (unformat (input, "secret-key %_%v%_", &key))
14637         ;
14638       else
14639         break;
14640     }
14641
14642   if (locator_set_name_set == 0)
14643     {
14644       errmsg ("missing locator-set name");
14645       return -99;
14646     }
14647
14648   if (0 == eid_set)
14649     {
14650       errmsg ("EID address not set!");
14651       vec_free (locator_set_name);
14652       return -99;
14653     }
14654
14655   if (key && (0 == key_id))
14656     {
14657       errmsg ("invalid key_id!");
14658       return -99;
14659     }
14660
14661   if (vec_len (key) > 64)
14662     {
14663       errmsg ("key too long");
14664       vec_free (key);
14665       return -99;
14666     }
14667
14668   if (vec_len (locator_set_name) > 64)
14669     {
14670       errmsg ("locator-set name too long");
14671       vec_free (locator_set_name);
14672       return -99;
14673     }
14674   vec_add1 (locator_set_name, 0);
14675
14676   /* Construct the API message */
14677   M (ONE_ADD_DEL_LOCAL_EID, mp);
14678
14679   mp->is_add = is_add;
14680   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14681   mp->eid_type = eid->type;
14682   mp->prefix_len = eid->len;
14683   mp->vni = clib_host_to_net_u32 (vni);
14684   mp->key_id = clib_host_to_net_u16 (key_id);
14685   clib_memcpy (mp->locator_set_name, locator_set_name,
14686                vec_len (locator_set_name));
14687   clib_memcpy (mp->key, key, vec_len (key));
14688
14689   vec_free (locator_set_name);
14690   vec_free (key);
14691
14692   /* send it... */
14693   S (mp);
14694
14695   /* Wait for a reply... */
14696   W (ret);
14697   return ret;
14698 }
14699
14700 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14701
14702 static int
14703 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14704 {
14705   u32 dp_table = 0, vni = 0;;
14706   unformat_input_t *input = vam->input;
14707   vl_api_gpe_add_del_fwd_entry_t *mp;
14708   u8 is_add = 1;
14709   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14710   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14711   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14712   u32 action = ~0, w;
14713   ip4_address_t rmt_rloc4, lcl_rloc4;
14714   ip6_address_t rmt_rloc6, lcl_rloc6;
14715   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14716   int ret;
14717
14718   memset (&rloc, 0, sizeof (rloc));
14719
14720   /* Parse args required to build the message */
14721   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14722     {
14723       if (unformat (input, "del"))
14724         is_add = 0;
14725       else if (unformat (input, "add"))
14726         is_add = 1;
14727       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14728         {
14729           rmt_eid_set = 1;
14730         }
14731       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14732         {
14733           lcl_eid_set = 1;
14734         }
14735       else if (unformat (input, "vrf %d", &dp_table))
14736         ;
14737       else if (unformat (input, "bd %d", &dp_table))
14738         ;
14739       else if (unformat (input, "vni %d", &vni))
14740         ;
14741       else if (unformat (input, "w %d", &w))
14742         {
14743           if (!curr_rloc)
14744             {
14745               errmsg ("No RLOC configured for setting priority/weight!");
14746               return -99;
14747             }
14748           curr_rloc->weight = w;
14749         }
14750       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14751                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14752         {
14753           rloc.is_ip4 = 1;
14754
14755           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
14756           rloc.weight = 0;
14757           vec_add1 (lcl_locs, rloc);
14758
14759           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
14760           vec_add1 (rmt_locs, rloc);
14761           /* weight saved in rmt loc */
14762           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14763         }
14764       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14765                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14766         {
14767           rloc.is_ip4 = 0;
14768           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
14769           rloc.weight = 0;
14770           vec_add1 (lcl_locs, rloc);
14771
14772           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
14773           vec_add1 (rmt_locs, rloc);
14774           /* weight saved in rmt loc */
14775           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14776         }
14777       else if (unformat (input, "action %d", &action))
14778         {
14779           ;
14780         }
14781       else
14782         {
14783           clib_warning ("parse error '%U'", format_unformat_error, input);
14784           return -99;
14785         }
14786     }
14787
14788   if (!rmt_eid_set)
14789     {
14790       errmsg ("remote eid addresses not set");
14791       return -99;
14792     }
14793
14794   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14795     {
14796       errmsg ("eid types don't match");
14797       return -99;
14798     }
14799
14800   if (0 == rmt_locs && (u32) ~ 0 == action)
14801     {
14802       errmsg ("action not set for negative mapping");
14803       return -99;
14804     }
14805
14806   /* Construct the API message */
14807   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14808       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14809
14810   mp->is_add = is_add;
14811   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
14812   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
14813   mp->eid_type = rmt_eid->type;
14814   mp->dp_table = clib_host_to_net_u32 (dp_table);
14815   mp->vni = clib_host_to_net_u32 (vni);
14816   mp->rmt_len = rmt_eid->len;
14817   mp->lcl_len = lcl_eid->len;
14818   mp->action = action;
14819
14820   if (0 != rmt_locs && 0 != lcl_locs)
14821     {
14822       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14823       clib_memcpy (mp->locs, lcl_locs,
14824                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14825
14826       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14827       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14828                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14829     }
14830   vec_free (lcl_locs);
14831   vec_free (rmt_locs);
14832
14833   /* send it... */
14834   S (mp);
14835
14836   /* Wait for a reply... */
14837   W (ret);
14838   return ret;
14839 }
14840
14841 static int
14842 api_one_add_del_map_server (vat_main_t * vam)
14843 {
14844   unformat_input_t *input = vam->input;
14845   vl_api_one_add_del_map_server_t *mp;
14846   u8 is_add = 1;
14847   u8 ipv4_set = 0;
14848   u8 ipv6_set = 0;
14849   ip4_address_t ipv4;
14850   ip6_address_t ipv6;
14851   int ret;
14852
14853   /* Parse args required to build the message */
14854   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14855     {
14856       if (unformat (input, "del"))
14857         {
14858           is_add = 0;
14859         }
14860       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14861         {
14862           ipv4_set = 1;
14863         }
14864       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14865         {
14866           ipv6_set = 1;
14867         }
14868       else
14869         break;
14870     }
14871
14872   if (ipv4_set && ipv6_set)
14873     {
14874       errmsg ("both eid v4 and v6 addresses set");
14875       return -99;
14876     }
14877
14878   if (!ipv4_set && !ipv6_set)
14879     {
14880       errmsg ("eid addresses not set");
14881       return -99;
14882     }
14883
14884   /* Construct the API message */
14885   M (ONE_ADD_DEL_MAP_SERVER, mp);
14886
14887   mp->is_add = is_add;
14888   if (ipv6_set)
14889     {
14890       mp->is_ipv6 = 1;
14891       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14892     }
14893   else
14894     {
14895       mp->is_ipv6 = 0;
14896       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14897     }
14898
14899   /* send it... */
14900   S (mp);
14901
14902   /* Wait for a reply... */
14903   W (ret);
14904   return ret;
14905 }
14906
14907 #define api_lisp_add_del_map_server api_one_add_del_map_server
14908
14909 static int
14910 api_one_add_del_map_resolver (vat_main_t * vam)
14911 {
14912   unformat_input_t *input = vam->input;
14913   vl_api_one_add_del_map_resolver_t *mp;
14914   u8 is_add = 1;
14915   u8 ipv4_set = 0;
14916   u8 ipv6_set = 0;
14917   ip4_address_t ipv4;
14918   ip6_address_t ipv6;
14919   int ret;
14920
14921   /* Parse args required to build the message */
14922   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14923     {
14924       if (unformat (input, "del"))
14925         {
14926           is_add = 0;
14927         }
14928       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14929         {
14930           ipv4_set = 1;
14931         }
14932       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14933         {
14934           ipv6_set = 1;
14935         }
14936       else
14937         break;
14938     }
14939
14940   if (ipv4_set && ipv6_set)
14941     {
14942       errmsg ("both eid v4 and v6 addresses set");
14943       return -99;
14944     }
14945
14946   if (!ipv4_set && !ipv6_set)
14947     {
14948       errmsg ("eid addresses not set");
14949       return -99;
14950     }
14951
14952   /* Construct the API message */
14953   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14954
14955   mp->is_add = is_add;
14956   if (ipv6_set)
14957     {
14958       mp->is_ipv6 = 1;
14959       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14960     }
14961   else
14962     {
14963       mp->is_ipv6 = 0;
14964       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14965     }
14966
14967   /* send it... */
14968   S (mp);
14969
14970   /* Wait for a reply... */
14971   W (ret);
14972   return ret;
14973 }
14974
14975 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14976
14977 static int
14978 api_lisp_gpe_enable_disable (vat_main_t * vam)
14979 {
14980   unformat_input_t *input = vam->input;
14981   vl_api_gpe_enable_disable_t *mp;
14982   u8 is_set = 0;
14983   u8 is_en = 1;
14984   int ret;
14985
14986   /* Parse args required to build the message */
14987   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14988     {
14989       if (unformat (input, "enable"))
14990         {
14991           is_set = 1;
14992           is_en = 1;
14993         }
14994       else if (unformat (input, "disable"))
14995         {
14996           is_set = 1;
14997           is_en = 0;
14998         }
14999       else
15000         break;
15001     }
15002
15003   if (is_set == 0)
15004     {
15005       errmsg ("Value not set");
15006       return -99;
15007     }
15008
15009   /* Construct the API message */
15010   M (GPE_ENABLE_DISABLE, mp);
15011
15012   mp->is_en = is_en;
15013
15014   /* send it... */
15015   S (mp);
15016
15017   /* Wait for a reply... */
15018   W (ret);
15019   return ret;
15020 }
15021
15022 static int
15023 api_one_rloc_probe_enable_disable (vat_main_t * vam)
15024 {
15025   unformat_input_t *input = vam->input;
15026   vl_api_one_rloc_probe_enable_disable_t *mp;
15027   u8 is_set = 0;
15028   u8 is_en = 0;
15029   int ret;
15030
15031   /* Parse args required to build the message */
15032   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15033     {
15034       if (unformat (input, "enable"))
15035         {
15036           is_set = 1;
15037           is_en = 1;
15038         }
15039       else if (unformat (input, "disable"))
15040         is_set = 1;
15041       else
15042         break;
15043     }
15044
15045   if (!is_set)
15046     {
15047       errmsg ("Value not set");
15048       return -99;
15049     }
15050
15051   /* Construct the API message */
15052   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
15053
15054   mp->is_enabled = is_en;
15055
15056   /* send it... */
15057   S (mp);
15058
15059   /* Wait for a reply... */
15060   W (ret);
15061   return ret;
15062 }
15063
15064 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
15065
15066 static int
15067 api_one_map_register_enable_disable (vat_main_t * vam)
15068 {
15069   unformat_input_t *input = vam->input;
15070   vl_api_one_map_register_enable_disable_t *mp;
15071   u8 is_set = 0;
15072   u8 is_en = 0;
15073   int ret;
15074
15075   /* Parse args required to build the message */
15076   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15077     {
15078       if (unformat (input, "enable"))
15079         {
15080           is_set = 1;
15081           is_en = 1;
15082         }
15083       else if (unformat (input, "disable"))
15084         is_set = 1;
15085       else
15086         break;
15087     }
15088
15089   if (!is_set)
15090     {
15091       errmsg ("Value not set");
15092       return -99;
15093     }
15094
15095   /* Construct the API message */
15096   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
15097
15098   mp->is_enabled = is_en;
15099
15100   /* send it... */
15101   S (mp);
15102
15103   /* Wait for a reply... */
15104   W (ret);
15105   return ret;
15106 }
15107
15108 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
15109
15110 static int
15111 api_one_enable_disable (vat_main_t * vam)
15112 {
15113   unformat_input_t *input = vam->input;
15114   vl_api_one_enable_disable_t *mp;
15115   u8 is_set = 0;
15116   u8 is_en = 0;
15117   int ret;
15118
15119   /* Parse args required to build the message */
15120   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15121     {
15122       if (unformat (input, "enable"))
15123         {
15124           is_set = 1;
15125           is_en = 1;
15126         }
15127       else if (unformat (input, "disable"))
15128         {
15129           is_set = 1;
15130         }
15131       else
15132         break;
15133     }
15134
15135   if (!is_set)
15136     {
15137       errmsg ("Value not set");
15138       return -99;
15139     }
15140
15141   /* Construct the API message */
15142   M (ONE_ENABLE_DISABLE, mp);
15143
15144   mp->is_en = is_en;
15145
15146   /* send it... */
15147   S (mp);
15148
15149   /* Wait for a reply... */
15150   W (ret);
15151   return ret;
15152 }
15153
15154 #define api_lisp_enable_disable api_one_enable_disable
15155
15156 static int
15157 api_show_one_map_register_state (vat_main_t * vam)
15158 {
15159   vl_api_show_one_map_register_state_t *mp;
15160   int ret;
15161
15162   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15163
15164   /* send */
15165   S (mp);
15166
15167   /* wait for reply */
15168   W (ret);
15169   return ret;
15170 }
15171
15172 #define api_show_lisp_map_register_state api_show_one_map_register_state
15173
15174 static int
15175 api_show_one_rloc_probe_state (vat_main_t * vam)
15176 {
15177   vl_api_show_one_rloc_probe_state_t *mp;
15178   int ret;
15179
15180   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15181
15182   /* send */
15183   S (mp);
15184
15185   /* wait for reply */
15186   W (ret);
15187   return ret;
15188 }
15189
15190 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15191
15192 static int
15193 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15194 {
15195   vl_api_one_add_del_l2_arp_entry_t *mp;
15196   unformat_input_t *input = vam->input;
15197   u8 is_add = 1;
15198   u8 mac_set = 0;
15199   u8 bd_set = 0;
15200   u8 ip_set = 0;
15201   u8 mac[6] = { 0, };
15202   u32 ip4 = 0, bd = ~0;
15203   int ret;
15204
15205   /* Parse args required to build the message */
15206   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15207     {
15208       if (unformat (input, "del"))
15209         is_add = 0;
15210       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15211         mac_set = 1;
15212       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15213         ip_set = 1;
15214       else if (unformat (input, "bd %d", &bd))
15215         bd_set = 1;
15216       else
15217         {
15218           errmsg ("parse error '%U'", format_unformat_error, input);
15219           return -99;
15220         }
15221     }
15222
15223   if (!bd_set || !ip_set || (!mac_set && is_add))
15224     {
15225       errmsg ("Missing BD, IP or MAC!");
15226       return -99;
15227     }
15228
15229   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15230   mp->is_add = is_add;
15231   clib_memcpy (mp->mac, mac, 6);
15232   mp->bd = clib_host_to_net_u32 (bd);
15233   mp->ip4 = ip4;
15234
15235   /* send */
15236   S (mp);
15237
15238   /* wait for reply */
15239   W (ret);
15240   return ret;
15241 }
15242
15243 static int
15244 api_one_l2_arp_bd_get (vat_main_t * vam)
15245 {
15246   vl_api_one_l2_arp_bd_get_t *mp;
15247   int ret;
15248
15249   M (ONE_L2_ARP_BD_GET, mp);
15250
15251   /* send */
15252   S (mp);
15253
15254   /* wait for reply */
15255   W (ret);
15256   return ret;
15257 }
15258
15259 static int
15260 api_one_l2_arp_entries_get (vat_main_t * vam)
15261 {
15262   vl_api_one_l2_arp_entries_get_t *mp;
15263   unformat_input_t *input = vam->input;
15264   u8 bd_set = 0;
15265   u32 bd = ~0;
15266   int ret;
15267
15268   /* Parse args required to build the message */
15269   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15270     {
15271       if (unformat (input, "bd %d", &bd))
15272         bd_set = 1;
15273       else
15274         {
15275           errmsg ("parse error '%U'", format_unformat_error, input);
15276           return -99;
15277         }
15278     }
15279
15280   if (!bd_set)
15281     {
15282       errmsg ("Expected bridge domain!");
15283       return -99;
15284     }
15285
15286   M (ONE_L2_ARP_ENTRIES_GET, mp);
15287   mp->bd = clib_host_to_net_u32 (bd);
15288
15289   /* send */
15290   S (mp);
15291
15292   /* wait for reply */
15293   W (ret);
15294   return ret;
15295 }
15296
15297 static int
15298 api_one_stats_enable_disable (vat_main_t * vam)
15299 {
15300   vl_api_one_stats_enable_disable_t *mp;
15301   unformat_input_t *input = vam->input;
15302   u8 is_set = 0;
15303   u8 is_en = 0;
15304   int ret;
15305
15306   /* Parse args required to build the message */
15307   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15308     {
15309       if (unformat (input, "enable"))
15310         {
15311           is_set = 1;
15312           is_en = 1;
15313         }
15314       else if (unformat (input, "disable"))
15315         {
15316           is_set = 1;
15317         }
15318       else
15319         break;
15320     }
15321
15322   if (!is_set)
15323     {
15324       errmsg ("Value not set");
15325       return -99;
15326     }
15327
15328   M (ONE_STATS_ENABLE_DISABLE, mp);
15329   mp->is_en = is_en;
15330
15331   /* send */
15332   S (mp);
15333
15334   /* wait for reply */
15335   W (ret);
15336   return ret;
15337 }
15338
15339 static int
15340 api_show_one_stats_enable_disable (vat_main_t * vam)
15341 {
15342   vl_api_show_one_stats_enable_disable_t *mp;
15343   int ret;
15344
15345   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
15346
15347   /* send */
15348   S (mp);
15349
15350   /* wait for reply */
15351   W (ret);
15352   return ret;
15353 }
15354
15355 static int
15356 api_show_one_map_request_mode (vat_main_t * vam)
15357 {
15358   vl_api_show_one_map_request_mode_t *mp;
15359   int ret;
15360
15361   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
15362
15363   /* send */
15364   S (mp);
15365
15366   /* wait for reply */
15367   W (ret);
15368   return ret;
15369 }
15370
15371 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
15372
15373 static int
15374 api_one_map_request_mode (vat_main_t * vam)
15375 {
15376   unformat_input_t *input = vam->input;
15377   vl_api_one_map_request_mode_t *mp;
15378   u8 mode = 0;
15379   int ret;
15380
15381   /* Parse args required to build the message */
15382   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15383     {
15384       if (unformat (input, "dst-only"))
15385         mode = 0;
15386       else if (unformat (input, "src-dst"))
15387         mode = 1;
15388       else
15389         {
15390           errmsg ("parse error '%U'", format_unformat_error, input);
15391           return -99;
15392         }
15393     }
15394
15395   M (ONE_MAP_REQUEST_MODE, mp);
15396
15397   mp->mode = mode;
15398
15399   /* send */
15400   S (mp);
15401
15402   /* wait for reply */
15403   W (ret);
15404   return ret;
15405 }
15406
15407 #define api_lisp_map_request_mode api_one_map_request_mode
15408
15409 /**
15410  * Enable/disable ONE proxy ITR.
15411  *
15412  * @param vam vpp API test context
15413  * @return return code
15414  */
15415 static int
15416 api_one_pitr_set_locator_set (vat_main_t * vam)
15417 {
15418   u8 ls_name_set = 0;
15419   unformat_input_t *input = vam->input;
15420   vl_api_one_pitr_set_locator_set_t *mp;
15421   u8 is_add = 1;
15422   u8 *ls_name = 0;
15423   int ret;
15424
15425   /* Parse args required to build the message */
15426   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15427     {
15428       if (unformat (input, "del"))
15429         is_add = 0;
15430       else if (unformat (input, "locator-set %s", &ls_name))
15431         ls_name_set = 1;
15432       else
15433         {
15434           errmsg ("parse error '%U'", format_unformat_error, input);
15435           return -99;
15436         }
15437     }
15438
15439   if (!ls_name_set)
15440     {
15441       errmsg ("locator-set name not set!");
15442       return -99;
15443     }
15444
15445   M (ONE_PITR_SET_LOCATOR_SET, mp);
15446
15447   mp->is_add = is_add;
15448   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15449   vec_free (ls_name);
15450
15451   /* send */
15452   S (mp);
15453
15454   /* wait for reply */
15455   W (ret);
15456   return ret;
15457 }
15458
15459 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
15460
15461 static int
15462 api_one_nsh_set_locator_set (vat_main_t * vam)
15463 {
15464   u8 ls_name_set = 0;
15465   unformat_input_t *input = vam->input;
15466   vl_api_one_nsh_set_locator_set_t *mp;
15467   u8 is_add = 1;
15468   u8 *ls_name = 0;
15469   int ret;
15470
15471   /* Parse args required to build the message */
15472   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15473     {
15474       if (unformat (input, "del"))
15475         is_add = 0;
15476       else if (unformat (input, "ls %s", &ls_name))
15477         ls_name_set = 1;
15478       else
15479         {
15480           errmsg ("parse error '%U'", format_unformat_error, input);
15481           return -99;
15482         }
15483     }
15484
15485   if (!ls_name_set && is_add)
15486     {
15487       errmsg ("locator-set name not set!");
15488       return -99;
15489     }
15490
15491   M (ONE_NSH_SET_LOCATOR_SET, mp);
15492
15493   mp->is_add = is_add;
15494   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15495   vec_free (ls_name);
15496
15497   /* send */
15498   S (mp);
15499
15500   /* wait for reply */
15501   W (ret);
15502   return ret;
15503 }
15504
15505 static int
15506 api_show_one_pitr (vat_main_t * vam)
15507 {
15508   vl_api_show_one_pitr_t *mp;
15509   int ret;
15510
15511   if (!vam->json_output)
15512     {
15513       print (vam->ofp, "%=20s", "lisp status:");
15514     }
15515
15516   M (SHOW_ONE_PITR, mp);
15517   /* send it... */
15518   S (mp);
15519
15520   /* Wait for a reply... */
15521   W (ret);
15522   return ret;
15523 }
15524
15525 #define api_show_lisp_pitr api_show_one_pitr
15526
15527 static int
15528 api_one_use_petr (vat_main_t * vam)
15529 {
15530   unformat_input_t *input = vam->input;
15531   vl_api_one_use_petr_t *mp;
15532   u8 is_add = 0;
15533   ip_address_t ip;
15534   int ret;
15535
15536   memset (&ip, 0, sizeof (ip));
15537
15538   /* Parse args required to build the message */
15539   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15540     {
15541       if (unformat (input, "disable"))
15542         is_add = 0;
15543       else
15544         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
15545         {
15546           is_add = 1;
15547           ip_addr_version (&ip) = IP4;
15548         }
15549       else
15550         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
15551         {
15552           is_add = 1;
15553           ip_addr_version (&ip) = IP6;
15554         }
15555       else
15556         {
15557           errmsg ("parse error '%U'", format_unformat_error, input);
15558           return -99;
15559         }
15560     }
15561
15562   M (ONE_USE_PETR, mp);
15563
15564   mp->is_add = is_add;
15565   if (is_add)
15566     {
15567       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
15568       if (mp->is_ip4)
15569         clib_memcpy (mp->address, &ip, 4);
15570       else
15571         clib_memcpy (mp->address, &ip, 16);
15572     }
15573
15574   /* send */
15575   S (mp);
15576
15577   /* wait for reply */
15578   W (ret);
15579   return ret;
15580 }
15581
15582 #define api_lisp_use_petr api_one_use_petr
15583
15584 static int
15585 api_show_one_nsh_mapping (vat_main_t * vam)
15586 {
15587   vl_api_show_one_use_petr_t *mp;
15588   int ret;
15589
15590   if (!vam->json_output)
15591     {
15592       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
15593     }
15594
15595   M (SHOW_ONE_NSH_MAPPING, mp);
15596   /* send it... */
15597   S (mp);
15598
15599   /* Wait for a reply... */
15600   W (ret);
15601   return ret;
15602 }
15603
15604 static int
15605 api_show_one_use_petr (vat_main_t * vam)
15606 {
15607   vl_api_show_one_use_petr_t *mp;
15608   int ret;
15609
15610   if (!vam->json_output)
15611     {
15612       print (vam->ofp, "%=20s", "Proxy-ETR status:");
15613     }
15614
15615   M (SHOW_ONE_USE_PETR, mp);
15616   /* send it... */
15617   S (mp);
15618
15619   /* Wait for a reply... */
15620   W (ret);
15621   return ret;
15622 }
15623
15624 #define api_show_lisp_use_petr api_show_one_use_petr
15625
15626 /**
15627  * Add/delete mapping between vni and vrf
15628  */
15629 static int
15630 api_one_eid_table_add_del_map (vat_main_t * vam)
15631 {
15632   unformat_input_t *input = vam->input;
15633   vl_api_one_eid_table_add_del_map_t *mp;
15634   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15635   u32 vni, vrf, bd_index;
15636   int ret;
15637
15638   /* Parse args required to build the message */
15639   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15640     {
15641       if (unformat (input, "del"))
15642         is_add = 0;
15643       else if (unformat (input, "vrf %d", &vrf))
15644         vrf_set = 1;
15645       else if (unformat (input, "bd_index %d", &bd_index))
15646         bd_index_set = 1;
15647       else if (unformat (input, "vni %d", &vni))
15648         vni_set = 1;
15649       else
15650         break;
15651     }
15652
15653   if (!vni_set || (!vrf_set && !bd_index_set))
15654     {
15655       errmsg ("missing arguments!");
15656       return -99;
15657     }
15658
15659   if (vrf_set && bd_index_set)
15660     {
15661       errmsg ("error: both vrf and bd entered!");
15662       return -99;
15663     }
15664
15665   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15666
15667   mp->is_add = is_add;
15668   mp->vni = htonl (vni);
15669   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15670   mp->is_l2 = bd_index_set;
15671
15672   /* send */
15673   S (mp);
15674
15675   /* wait for reply */
15676   W (ret);
15677   return ret;
15678 }
15679
15680 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15681
15682 uword
15683 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15684 {
15685   u32 *action = va_arg (*args, u32 *);
15686   u8 *s = 0;
15687
15688   if (unformat (input, "%s", &s))
15689     {
15690       if (!strcmp ((char *) s, "no-action"))
15691         action[0] = 0;
15692       else if (!strcmp ((char *) s, "natively-forward"))
15693         action[0] = 1;
15694       else if (!strcmp ((char *) s, "send-map-request"))
15695         action[0] = 2;
15696       else if (!strcmp ((char *) s, "drop"))
15697         action[0] = 3;
15698       else
15699         {
15700           clib_warning ("invalid action: '%s'", s);
15701           action[0] = 3;
15702         }
15703     }
15704   else
15705     return 0;
15706
15707   vec_free (s);
15708   return 1;
15709 }
15710
15711 /**
15712  * Add/del remote mapping to/from ONE control plane
15713  *
15714  * @param vam vpp API test context
15715  * @return return code
15716  */
15717 static int
15718 api_one_add_del_remote_mapping (vat_main_t * vam)
15719 {
15720   unformat_input_t *input = vam->input;
15721   vl_api_one_add_del_remote_mapping_t *mp;
15722   u32 vni = 0;
15723   lisp_eid_vat_t _eid, *eid = &_eid;
15724   lisp_eid_vat_t _seid, *seid = &_seid;
15725   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15726   u32 action = ~0, p, w, data_len;
15727   ip4_address_t rloc4;
15728   ip6_address_t rloc6;
15729   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15730   int ret;
15731
15732   memset (&rloc, 0, sizeof (rloc));
15733
15734   /* Parse args required to build the message */
15735   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15736     {
15737       if (unformat (input, "del-all"))
15738         {
15739           del_all = 1;
15740         }
15741       else if (unformat (input, "del"))
15742         {
15743           is_add = 0;
15744         }
15745       else if (unformat (input, "add"))
15746         {
15747           is_add = 1;
15748         }
15749       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15750         {
15751           eid_set = 1;
15752         }
15753       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15754         {
15755           seid_set = 1;
15756         }
15757       else if (unformat (input, "vni %d", &vni))
15758         {
15759           ;
15760         }
15761       else if (unformat (input, "p %d w %d", &p, &w))
15762         {
15763           if (!curr_rloc)
15764             {
15765               errmsg ("No RLOC configured for setting priority/weight!");
15766               return -99;
15767             }
15768           curr_rloc->priority = p;
15769           curr_rloc->weight = w;
15770         }
15771       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15772         {
15773           rloc.is_ip4 = 1;
15774           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
15775           vec_add1 (rlocs, rloc);
15776           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15777         }
15778       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15779         {
15780           rloc.is_ip4 = 0;
15781           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
15782           vec_add1 (rlocs, rloc);
15783           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15784         }
15785       else if (unformat (input, "action %U",
15786                          unformat_negative_mapping_action, &action))
15787         {
15788           ;
15789         }
15790       else
15791         {
15792           clib_warning ("parse error '%U'", format_unformat_error, input);
15793           return -99;
15794         }
15795     }
15796
15797   if (0 == eid_set)
15798     {
15799       errmsg ("missing params!");
15800       return -99;
15801     }
15802
15803   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15804     {
15805       errmsg ("no action set for negative map-reply!");
15806       return -99;
15807     }
15808
15809   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15810
15811   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15812   mp->is_add = is_add;
15813   mp->vni = htonl (vni);
15814   mp->action = (u8) action;
15815   mp->is_src_dst = seid_set;
15816   mp->eid_len = eid->len;
15817   mp->seid_len = seid->len;
15818   mp->del_all = del_all;
15819   mp->eid_type = eid->type;
15820   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15821   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
15822
15823   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15824   clib_memcpy (mp->rlocs, rlocs, data_len);
15825   vec_free (rlocs);
15826
15827   /* send it... */
15828   S (mp);
15829
15830   /* Wait for a reply... */
15831   W (ret);
15832   return ret;
15833 }
15834
15835 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15836
15837 /**
15838  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15839  * forwarding entries in data-plane accordingly.
15840  *
15841  * @param vam vpp API test context
15842  * @return return code
15843  */
15844 static int
15845 api_one_add_del_adjacency (vat_main_t * vam)
15846 {
15847   unformat_input_t *input = vam->input;
15848   vl_api_one_add_del_adjacency_t *mp;
15849   u32 vni = 0;
15850   ip4_address_t leid4, reid4;
15851   ip6_address_t leid6, reid6;
15852   u8 reid_mac[6] = { 0 };
15853   u8 leid_mac[6] = { 0 };
15854   u8 reid_type, leid_type;
15855   u32 leid_len = 0, reid_len = 0, len;
15856   u8 is_add = 1;
15857   int ret;
15858
15859   leid_type = reid_type = (u8) ~ 0;
15860
15861   /* Parse args required to build the message */
15862   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15863     {
15864       if (unformat (input, "del"))
15865         {
15866           is_add = 0;
15867         }
15868       else if (unformat (input, "add"))
15869         {
15870           is_add = 1;
15871         }
15872       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
15873                          &reid4, &len))
15874         {
15875           reid_type = 0;        /* ipv4 */
15876           reid_len = len;
15877         }
15878       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
15879                          &reid6, &len))
15880         {
15881           reid_type = 1;        /* ipv6 */
15882           reid_len = len;
15883         }
15884       else if (unformat (input, "reid %U", unformat_ethernet_address,
15885                          reid_mac))
15886         {
15887           reid_type = 2;        /* mac */
15888         }
15889       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
15890                          &leid4, &len))
15891         {
15892           leid_type = 0;        /* ipv4 */
15893           leid_len = len;
15894         }
15895       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
15896                          &leid6, &len))
15897         {
15898           leid_type = 1;        /* ipv6 */
15899           leid_len = len;
15900         }
15901       else if (unformat (input, "leid %U", unformat_ethernet_address,
15902                          leid_mac))
15903         {
15904           leid_type = 2;        /* mac */
15905         }
15906       else if (unformat (input, "vni %d", &vni))
15907         {
15908           ;
15909         }
15910       else
15911         {
15912           errmsg ("parse error '%U'", format_unformat_error, input);
15913           return -99;
15914         }
15915     }
15916
15917   if ((u8) ~ 0 == reid_type)
15918     {
15919       errmsg ("missing params!");
15920       return -99;
15921     }
15922
15923   if (leid_type != reid_type)
15924     {
15925       errmsg ("remote and local EIDs are of different types!");
15926       return -99;
15927     }
15928
15929   M (ONE_ADD_DEL_ADJACENCY, mp);
15930   mp->is_add = is_add;
15931   mp->vni = htonl (vni);
15932   mp->leid_len = leid_len;
15933   mp->reid_len = reid_len;
15934   mp->eid_type = reid_type;
15935
15936   switch (mp->eid_type)
15937     {
15938     case 0:
15939       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
15940       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
15941       break;
15942     case 1:
15943       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
15944       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
15945       break;
15946     case 2:
15947       clib_memcpy (mp->leid, leid_mac, 6);
15948       clib_memcpy (mp->reid, reid_mac, 6);
15949       break;
15950     default:
15951       errmsg ("unknown EID type %d!", mp->eid_type);
15952       return 0;
15953     }
15954
15955   /* send it... */
15956   S (mp);
15957
15958   /* Wait for a reply... */
15959   W (ret);
15960   return ret;
15961 }
15962
15963 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
15964
15965 uword
15966 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
15967 {
15968   u32 *mode = va_arg (*args, u32 *);
15969
15970   if (unformat (input, "lisp"))
15971     *mode = 0;
15972   else if (unformat (input, "vxlan"))
15973     *mode = 1;
15974   else
15975     return 0;
15976
15977   return 1;
15978 }
15979
15980 static int
15981 api_gpe_get_encap_mode (vat_main_t * vam)
15982 {
15983   vl_api_gpe_get_encap_mode_t *mp;
15984   int ret;
15985
15986   /* Construct the API message */
15987   M (GPE_GET_ENCAP_MODE, mp);
15988
15989   /* send it... */
15990   S (mp);
15991
15992   /* Wait for a reply... */
15993   W (ret);
15994   return ret;
15995 }
15996
15997 static int
15998 api_gpe_set_encap_mode (vat_main_t * vam)
15999 {
16000   unformat_input_t *input = vam->input;
16001   vl_api_gpe_set_encap_mode_t *mp;
16002   int ret;
16003   u32 mode = 0;
16004
16005   /* Parse args required to build the message */
16006   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16007     {
16008       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16009         ;
16010       else
16011         break;
16012     }
16013
16014   /* Construct the API message */
16015   M (GPE_SET_ENCAP_MODE, mp);
16016
16017   mp->mode = mode;
16018
16019   /* send it... */
16020   S (mp);
16021
16022   /* Wait for a reply... */
16023   W (ret);
16024   return ret;
16025 }
16026
16027 static int
16028 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16029 {
16030   unformat_input_t *input = vam->input;
16031   vl_api_gpe_add_del_iface_t *mp;
16032   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16033   u32 dp_table = 0, vni = 0;
16034   int ret;
16035
16036   /* Parse args required to build the message */
16037   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16038     {
16039       if (unformat (input, "up"))
16040         {
16041           action_set = 1;
16042           is_add = 1;
16043         }
16044       else if (unformat (input, "down"))
16045         {
16046           action_set = 1;
16047           is_add = 0;
16048         }
16049       else if (unformat (input, "table_id %d", &dp_table))
16050         {
16051           dp_table_set = 1;
16052         }
16053       else if (unformat (input, "bd_id %d", &dp_table))
16054         {
16055           dp_table_set = 1;
16056           is_l2 = 1;
16057         }
16058       else if (unformat (input, "vni %d", &vni))
16059         {
16060           vni_set = 1;
16061         }
16062       else
16063         break;
16064     }
16065
16066   if (action_set == 0)
16067     {
16068       errmsg ("Action not set");
16069       return -99;
16070     }
16071   if (dp_table_set == 0 || vni_set == 0)
16072     {
16073       errmsg ("vni and dp_table must be set");
16074       return -99;
16075     }
16076
16077   /* Construct the API message */
16078   M (GPE_ADD_DEL_IFACE, mp);
16079
16080   mp->is_add = is_add;
16081   mp->dp_table = clib_host_to_net_u32 (dp_table);
16082   mp->is_l2 = is_l2;
16083   mp->vni = clib_host_to_net_u32 (vni);
16084
16085   /* send it... */
16086   S (mp);
16087
16088   /* Wait for a reply... */
16089   W (ret);
16090   return ret;
16091 }
16092
16093 static int
16094 api_one_map_register_set_ttl (vat_main_t * vam)
16095 {
16096   unformat_input_t *input = vam->input;
16097   vl_api_one_map_register_set_ttl_t *mp;
16098   u32 ttl = 0;
16099   u8 is_set = 0;
16100   int ret;
16101
16102   /* Parse args required to build the message */
16103   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16104     {
16105       if (unformat (input, "%u", &ttl))
16106         is_set = 1;
16107       else
16108         {
16109           clib_warning ("parse error '%U'", format_unformat_error, input);
16110           return -99;
16111         }
16112     }
16113
16114   if (!is_set)
16115     {
16116       errmsg ("TTL value missing!");
16117       return -99;
16118     }
16119
16120   M (ONE_MAP_REGISTER_SET_TTL, mp);
16121   mp->ttl = clib_host_to_net_u32 (ttl);
16122
16123   /* send it... */
16124   S (mp);
16125
16126   /* Wait for a reply... */
16127   W (ret);
16128   return ret;
16129 }
16130
16131 static int
16132 api_show_one_map_register_ttl (vat_main_t * vam)
16133 {
16134   vl_api_show_one_map_register_ttl_t *mp;
16135   int ret;
16136
16137   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
16138
16139   /* send it... */
16140   S (mp);
16141
16142   /* Wait for a reply... */
16143   W (ret);
16144   return ret;
16145 }
16146
16147 /**
16148  * Add/del map request itr rlocs from ONE control plane and updates
16149  *
16150  * @param vam vpp API test context
16151  * @return return code
16152  */
16153 static int
16154 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
16155 {
16156   unformat_input_t *input = vam->input;
16157   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
16158   u8 *locator_set_name = 0;
16159   u8 locator_set_name_set = 0;
16160   u8 is_add = 1;
16161   int ret;
16162
16163   /* Parse args required to build the message */
16164   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16165     {
16166       if (unformat (input, "del"))
16167         {
16168           is_add = 0;
16169         }
16170       else if (unformat (input, "%_%v%_", &locator_set_name))
16171         {
16172           locator_set_name_set = 1;
16173         }
16174       else
16175         {
16176           clib_warning ("parse error '%U'", format_unformat_error, input);
16177           return -99;
16178         }
16179     }
16180
16181   if (is_add && !locator_set_name_set)
16182     {
16183       errmsg ("itr-rloc is not set!");
16184       return -99;
16185     }
16186
16187   if (is_add && vec_len (locator_set_name) > 64)
16188     {
16189       errmsg ("itr-rloc locator-set name too long");
16190       vec_free (locator_set_name);
16191       return -99;
16192     }
16193
16194   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
16195   mp->is_add = is_add;
16196   if (is_add)
16197     {
16198       clib_memcpy (mp->locator_set_name, locator_set_name,
16199                    vec_len (locator_set_name));
16200     }
16201   else
16202     {
16203       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
16204     }
16205   vec_free (locator_set_name);
16206
16207   /* send it... */
16208   S (mp);
16209
16210   /* Wait for a reply... */
16211   W (ret);
16212   return ret;
16213 }
16214
16215 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
16216
16217 static int
16218 api_one_locator_dump (vat_main_t * vam)
16219 {
16220   unformat_input_t *input = vam->input;
16221   vl_api_one_locator_dump_t *mp;
16222   vl_api_control_ping_t *mp_ping;
16223   u8 is_index_set = 0, is_name_set = 0;
16224   u8 *ls_name = 0;
16225   u32 ls_index = ~0;
16226   int ret;
16227
16228   /* Parse args required to build the message */
16229   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16230     {
16231       if (unformat (input, "ls_name %_%v%_", &ls_name))
16232         {
16233           is_name_set = 1;
16234         }
16235       else if (unformat (input, "ls_index %d", &ls_index))
16236         {
16237           is_index_set = 1;
16238         }
16239       else
16240         {
16241           errmsg ("parse error '%U'", format_unformat_error, input);
16242           return -99;
16243         }
16244     }
16245
16246   if (!is_index_set && !is_name_set)
16247     {
16248       errmsg ("error: expected one of index or name!");
16249       return -99;
16250     }
16251
16252   if (is_index_set && is_name_set)
16253     {
16254       errmsg ("error: only one param expected!");
16255       return -99;
16256     }
16257
16258   if (vec_len (ls_name) > 62)
16259     {
16260       errmsg ("error: locator set name too long!");
16261       return -99;
16262     }
16263
16264   if (!vam->json_output)
16265     {
16266       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
16267     }
16268
16269   M (ONE_LOCATOR_DUMP, mp);
16270   mp->is_index_set = is_index_set;
16271
16272   if (is_index_set)
16273     mp->ls_index = clib_host_to_net_u32 (ls_index);
16274   else
16275     {
16276       vec_add1 (ls_name, 0);
16277       strncpy ((char *) mp->ls_name, (char *) ls_name,
16278                sizeof (mp->ls_name) - 1);
16279     }
16280
16281   /* send it... */
16282   S (mp);
16283
16284   /* Use a control ping for synchronization */
16285   M (CONTROL_PING, mp_ping);
16286   S (mp_ping);
16287
16288   /* Wait for a reply... */
16289   W (ret);
16290   return ret;
16291 }
16292
16293 #define api_lisp_locator_dump api_one_locator_dump
16294
16295 static int
16296 api_one_locator_set_dump (vat_main_t * vam)
16297 {
16298   vl_api_one_locator_set_dump_t *mp;
16299   vl_api_control_ping_t *mp_ping;
16300   unformat_input_t *input = vam->input;
16301   u8 filter = 0;
16302   int ret;
16303
16304   /* Parse args required to build the message */
16305   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16306     {
16307       if (unformat (input, "local"))
16308         {
16309           filter = 1;
16310         }
16311       else if (unformat (input, "remote"))
16312         {
16313           filter = 2;
16314         }
16315       else
16316         {
16317           errmsg ("parse error '%U'", format_unformat_error, input);
16318           return -99;
16319         }
16320     }
16321
16322   if (!vam->json_output)
16323     {
16324       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
16325     }
16326
16327   M (ONE_LOCATOR_SET_DUMP, mp);
16328
16329   mp->filter = filter;
16330
16331   /* send it... */
16332   S (mp);
16333
16334   /* Use a control ping for synchronization */
16335   M (CONTROL_PING, mp_ping);
16336   S (mp_ping);
16337
16338   /* Wait for a reply... */
16339   W (ret);
16340   return ret;
16341 }
16342
16343 #define api_lisp_locator_set_dump api_one_locator_set_dump
16344
16345 static int
16346 api_one_eid_table_map_dump (vat_main_t * vam)
16347 {
16348   u8 is_l2 = 0;
16349   u8 mode_set = 0;
16350   unformat_input_t *input = vam->input;
16351   vl_api_one_eid_table_map_dump_t *mp;
16352   vl_api_control_ping_t *mp_ping;
16353   int ret;
16354
16355   /* Parse args required to build the message */
16356   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16357     {
16358       if (unformat (input, "l2"))
16359         {
16360           is_l2 = 1;
16361           mode_set = 1;
16362         }
16363       else if (unformat (input, "l3"))
16364         {
16365           is_l2 = 0;
16366           mode_set = 1;
16367         }
16368       else
16369         {
16370           errmsg ("parse error '%U'", format_unformat_error, input);
16371           return -99;
16372         }
16373     }
16374
16375   if (!mode_set)
16376     {
16377       errmsg ("expected one of 'l2' or 'l3' parameter!");
16378       return -99;
16379     }
16380
16381   if (!vam->json_output)
16382     {
16383       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
16384     }
16385
16386   M (ONE_EID_TABLE_MAP_DUMP, mp);
16387   mp->is_l2 = is_l2;
16388
16389   /* send it... */
16390   S (mp);
16391
16392   /* Use a control ping for synchronization */
16393   M (CONTROL_PING, mp_ping);
16394   S (mp_ping);
16395
16396   /* Wait for a reply... */
16397   W (ret);
16398   return ret;
16399 }
16400
16401 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
16402
16403 static int
16404 api_one_eid_table_vni_dump (vat_main_t * vam)
16405 {
16406   vl_api_one_eid_table_vni_dump_t *mp;
16407   vl_api_control_ping_t *mp_ping;
16408   int ret;
16409
16410   if (!vam->json_output)
16411     {
16412       print (vam->ofp, "VNI");
16413     }
16414
16415   M (ONE_EID_TABLE_VNI_DUMP, mp);
16416
16417   /* send it... */
16418   S (mp);
16419
16420   /* Use a control ping for synchronization */
16421   M (CONTROL_PING, mp_ping);
16422   S (mp_ping);
16423
16424   /* Wait for a reply... */
16425   W (ret);
16426   return ret;
16427 }
16428
16429 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
16430
16431 static int
16432 api_one_eid_table_dump (vat_main_t * vam)
16433 {
16434   unformat_input_t *i = vam->input;
16435   vl_api_one_eid_table_dump_t *mp;
16436   vl_api_control_ping_t *mp_ping;
16437   struct in_addr ip4;
16438   struct in6_addr ip6;
16439   u8 mac[6];
16440   u8 eid_type = ~0, eid_set = 0;
16441   u32 prefix_length = ~0, t, vni = 0;
16442   u8 filter = 0;
16443   int ret;
16444   lisp_nsh_api_t nsh;
16445
16446   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16447     {
16448       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
16449         {
16450           eid_set = 1;
16451           eid_type = 0;
16452           prefix_length = t;
16453         }
16454       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
16455         {
16456           eid_set = 1;
16457           eid_type = 1;
16458           prefix_length = t;
16459         }
16460       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
16461         {
16462           eid_set = 1;
16463           eid_type = 2;
16464         }
16465       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
16466         {
16467           eid_set = 1;
16468           eid_type = 3;
16469         }
16470       else if (unformat (i, "vni %d", &t))
16471         {
16472           vni = t;
16473         }
16474       else if (unformat (i, "local"))
16475         {
16476           filter = 1;
16477         }
16478       else if (unformat (i, "remote"))
16479         {
16480           filter = 2;
16481         }
16482       else
16483         {
16484           errmsg ("parse error '%U'", format_unformat_error, i);
16485           return -99;
16486         }
16487     }
16488
16489   if (!vam->json_output)
16490     {
16491       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
16492              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
16493     }
16494
16495   M (ONE_EID_TABLE_DUMP, mp);
16496
16497   mp->filter = filter;
16498   if (eid_set)
16499     {
16500       mp->eid_set = 1;
16501       mp->vni = htonl (vni);
16502       mp->eid_type = eid_type;
16503       switch (eid_type)
16504         {
16505         case 0:
16506           mp->prefix_length = prefix_length;
16507           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
16508           break;
16509         case 1:
16510           mp->prefix_length = prefix_length;
16511           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
16512           break;
16513         case 2:
16514           clib_memcpy (mp->eid, mac, sizeof (mac));
16515           break;
16516         case 3:
16517           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
16518           break;
16519         default:
16520           errmsg ("unknown EID type %d!", eid_type);
16521           return -99;
16522         }
16523     }
16524
16525   /* send it... */
16526   S (mp);
16527
16528   /* Use a control ping for synchronization */
16529   M (CONTROL_PING, mp_ping);
16530   S (mp_ping);
16531
16532   /* Wait for a reply... */
16533   W (ret);
16534   return ret;
16535 }
16536
16537 #define api_lisp_eid_table_dump api_one_eid_table_dump
16538
16539 static int
16540 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
16541 {
16542   unformat_input_t *i = vam->input;
16543   vl_api_gpe_fwd_entries_get_t *mp;
16544   u8 vni_set = 0;
16545   u32 vni = ~0;
16546   int ret;
16547
16548   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16549     {
16550       if (unformat (i, "vni %d", &vni))
16551         {
16552           vni_set = 1;
16553         }
16554       else
16555         {
16556           errmsg ("parse error '%U'", format_unformat_error, i);
16557           return -99;
16558         }
16559     }
16560
16561   if (!vni_set)
16562     {
16563       errmsg ("vni not set!");
16564       return -99;
16565     }
16566
16567   if (!vam->json_output)
16568     {
16569       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
16570              "leid", "reid");
16571     }
16572
16573   M (GPE_FWD_ENTRIES_GET, mp);
16574   mp->vni = clib_host_to_net_u32 (vni);
16575
16576   /* send it... */
16577   S (mp);
16578
16579   /* Wait for a reply... */
16580   W (ret);
16581   return ret;
16582 }
16583
16584 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
16585 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
16586 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
16587 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
16588 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
16589 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
16590 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
16591 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
16592
16593 static int
16594 api_one_adjacencies_get (vat_main_t * vam)
16595 {
16596   unformat_input_t *i = vam->input;
16597   vl_api_one_adjacencies_get_t *mp;
16598   u8 vni_set = 0;
16599   u32 vni = ~0;
16600   int ret;
16601
16602   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16603     {
16604       if (unformat (i, "vni %d", &vni))
16605         {
16606           vni_set = 1;
16607         }
16608       else
16609         {
16610           errmsg ("parse error '%U'", format_unformat_error, i);
16611           return -99;
16612         }
16613     }
16614
16615   if (!vni_set)
16616     {
16617       errmsg ("vni not set!");
16618       return -99;
16619     }
16620
16621   if (!vam->json_output)
16622     {
16623       print (vam->ofp, "%s %40s", "leid", "reid");
16624     }
16625
16626   M (ONE_ADJACENCIES_GET, mp);
16627   mp->vni = clib_host_to_net_u32 (vni);
16628
16629   /* send it... */
16630   S (mp);
16631
16632   /* Wait for a reply... */
16633   W (ret);
16634   return ret;
16635 }
16636
16637 #define api_lisp_adjacencies_get api_one_adjacencies_get
16638
16639 static int
16640 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
16641 {
16642   unformat_input_t *i = vam->input;
16643   vl_api_gpe_native_fwd_rpaths_get_t *mp;
16644   int ret;
16645   u8 ip_family_set = 0, is_ip4 = 1;
16646
16647   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16648     {
16649       if (unformat (i, "ip4"))
16650         {
16651           ip_family_set = 1;
16652           is_ip4 = 1;
16653         }
16654       else if (unformat (i, "ip6"))
16655         {
16656           ip_family_set = 1;
16657           is_ip4 = 0;
16658         }
16659       else
16660         {
16661           errmsg ("parse error '%U'", format_unformat_error, i);
16662           return -99;
16663         }
16664     }
16665
16666   if (!ip_family_set)
16667     {
16668       errmsg ("ip family not set!");
16669       return -99;
16670     }
16671
16672   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
16673   mp->is_ip4 = is_ip4;
16674
16675   /* send it... */
16676   S (mp);
16677
16678   /* Wait for a reply... */
16679   W (ret);
16680   return ret;
16681 }
16682
16683 static int
16684 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
16685 {
16686   vl_api_gpe_fwd_entry_vnis_get_t *mp;
16687   int ret;
16688
16689   if (!vam->json_output)
16690     {
16691       print (vam->ofp, "VNIs");
16692     }
16693
16694   M (GPE_FWD_ENTRY_VNIS_GET, mp);
16695
16696   /* send it... */
16697   S (mp);
16698
16699   /* Wait for a reply... */
16700   W (ret);
16701   return ret;
16702 }
16703
16704 static int
16705 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
16706 {
16707   unformat_input_t *i = vam->input;
16708   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
16709   int ret = 0;
16710   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
16711   struct in_addr ip4;
16712   struct in6_addr ip6;
16713   u32 table_id = 0, nh_sw_if_index = ~0;
16714
16715   memset (&ip4, 0, sizeof (ip4));
16716   memset (&ip6, 0, sizeof (ip6));
16717
16718   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16719     {
16720       if (unformat (i, "del"))
16721         is_add = 0;
16722       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
16723                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16724         {
16725           ip_set = 1;
16726           is_ip4 = 1;
16727         }
16728       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
16729                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16730         {
16731           ip_set = 1;
16732           is_ip4 = 0;
16733         }
16734       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
16735         {
16736           ip_set = 1;
16737           is_ip4 = 1;
16738           nh_sw_if_index = ~0;
16739         }
16740       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
16741         {
16742           ip_set = 1;
16743           is_ip4 = 0;
16744           nh_sw_if_index = ~0;
16745         }
16746       else if (unformat (i, "table %d", &table_id))
16747         ;
16748       else
16749         {
16750           errmsg ("parse error '%U'", format_unformat_error, i);
16751           return -99;
16752         }
16753     }
16754
16755   if (!ip_set)
16756     {
16757       errmsg ("nh addr not set!");
16758       return -99;
16759     }
16760
16761   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
16762   mp->is_add = is_add;
16763   mp->table_id = clib_host_to_net_u32 (table_id);
16764   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
16765   mp->is_ip4 = is_ip4;
16766   if (is_ip4)
16767     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
16768   else
16769     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
16770
16771   /* send it... */
16772   S (mp);
16773
16774   /* Wait for a reply... */
16775   W (ret);
16776   return ret;
16777 }
16778
16779 static int
16780 api_one_map_server_dump (vat_main_t * vam)
16781 {
16782   vl_api_one_map_server_dump_t *mp;
16783   vl_api_control_ping_t *mp_ping;
16784   int ret;
16785
16786   if (!vam->json_output)
16787     {
16788       print (vam->ofp, "%=20s", "Map server");
16789     }
16790
16791   M (ONE_MAP_SERVER_DUMP, mp);
16792   /* send it... */
16793   S (mp);
16794
16795   /* Use a control ping for synchronization */
16796   M (CONTROL_PING, mp_ping);
16797   S (mp_ping);
16798
16799   /* Wait for a reply... */
16800   W (ret);
16801   return ret;
16802 }
16803
16804 #define api_lisp_map_server_dump api_one_map_server_dump
16805
16806 static int
16807 api_one_map_resolver_dump (vat_main_t * vam)
16808 {
16809   vl_api_one_map_resolver_dump_t *mp;
16810   vl_api_control_ping_t *mp_ping;
16811   int ret;
16812
16813   if (!vam->json_output)
16814     {
16815       print (vam->ofp, "%=20s", "Map resolver");
16816     }
16817
16818   M (ONE_MAP_RESOLVER_DUMP, mp);
16819   /* send it... */
16820   S (mp);
16821
16822   /* Use a control ping for synchronization */
16823   M (CONTROL_PING, mp_ping);
16824   S (mp_ping);
16825
16826   /* Wait for a reply... */
16827   W (ret);
16828   return ret;
16829 }
16830
16831 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
16832
16833 static int
16834 api_one_stats_flush (vat_main_t * vam)
16835 {
16836   vl_api_one_stats_flush_t *mp;
16837   int ret = 0;
16838
16839   M (ONE_STATS_FLUSH, mp);
16840   S (mp);
16841   W (ret);
16842   return ret;
16843 }
16844
16845 static int
16846 api_one_stats_dump (vat_main_t * vam)
16847 {
16848   vl_api_one_stats_dump_t *mp;
16849   vl_api_control_ping_t *mp_ping;
16850   int ret;
16851
16852   M (ONE_STATS_DUMP, mp);
16853   /* send it... */
16854   S (mp);
16855
16856   /* Use a control ping for synchronization */
16857   M (CONTROL_PING, mp_ping);
16858   S (mp_ping);
16859
16860   /* Wait for a reply... */
16861   W (ret);
16862   return ret;
16863 }
16864
16865 static int
16866 api_show_one_status (vat_main_t * vam)
16867 {
16868   vl_api_show_one_status_t *mp;
16869   int ret;
16870
16871   if (!vam->json_output)
16872     {
16873       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
16874     }
16875
16876   M (SHOW_ONE_STATUS, mp);
16877   /* send it... */
16878   S (mp);
16879   /* Wait for a reply... */
16880   W (ret);
16881   return ret;
16882 }
16883
16884 #define api_show_lisp_status api_show_one_status
16885
16886 static int
16887 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
16888 {
16889   vl_api_gpe_fwd_entry_path_dump_t *mp;
16890   vl_api_control_ping_t *mp_ping;
16891   unformat_input_t *i = vam->input;
16892   u32 fwd_entry_index = ~0;
16893   int ret;
16894
16895   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16896     {
16897       if (unformat (i, "index %d", &fwd_entry_index))
16898         ;
16899       else
16900         break;
16901     }
16902
16903   if (~0 == fwd_entry_index)
16904     {
16905       errmsg ("no index specified!");
16906       return -99;
16907     }
16908
16909   if (!vam->json_output)
16910     {
16911       print (vam->ofp, "first line");
16912     }
16913
16914   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
16915
16916   /* send it... */
16917   S (mp);
16918   /* Use a control ping for synchronization */
16919   M (CONTROL_PING, mp_ping);
16920   S (mp_ping);
16921
16922   /* Wait for a reply... */
16923   W (ret);
16924   return ret;
16925 }
16926
16927 static int
16928 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
16929 {
16930   vl_api_one_get_map_request_itr_rlocs_t *mp;
16931   int ret;
16932
16933   if (!vam->json_output)
16934     {
16935       print (vam->ofp, "%=20s", "itr-rlocs:");
16936     }
16937
16938   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
16939   /* send it... */
16940   S (mp);
16941   /* Wait for a reply... */
16942   W (ret);
16943   return ret;
16944 }
16945
16946 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
16947
16948 static int
16949 api_af_packet_create (vat_main_t * vam)
16950 {
16951   unformat_input_t *i = vam->input;
16952   vl_api_af_packet_create_t *mp;
16953   u8 *host_if_name = 0;
16954   u8 hw_addr[6];
16955   u8 random_hw_addr = 1;
16956   int ret;
16957
16958   memset (hw_addr, 0, sizeof (hw_addr));
16959
16960   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16961     {
16962       if (unformat (i, "name %s", &host_if_name))
16963         vec_add1 (host_if_name, 0);
16964       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
16965         random_hw_addr = 0;
16966       else
16967         break;
16968     }
16969
16970   if (!vec_len (host_if_name))
16971     {
16972       errmsg ("host-interface name must be specified");
16973       return -99;
16974     }
16975
16976   if (vec_len (host_if_name) > 64)
16977     {
16978       errmsg ("host-interface name too long");
16979       return -99;
16980     }
16981
16982   M (AF_PACKET_CREATE, mp);
16983
16984   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
16985   clib_memcpy (mp->hw_addr, hw_addr, 6);
16986   mp->use_random_hw_addr = random_hw_addr;
16987   vec_free (host_if_name);
16988
16989   S (mp);
16990
16991   /* *INDENT-OFF* */
16992   W2 (ret,
16993       ({
16994         if (ret == 0)
16995           fprintf (vam->ofp ? vam->ofp : stderr,
16996                    " new sw_if_index = %d\n", vam->sw_if_index);
16997       }));
16998   /* *INDENT-ON* */
16999   return ret;
17000 }
17001
17002 static int
17003 api_af_packet_delete (vat_main_t * vam)
17004 {
17005   unformat_input_t *i = vam->input;
17006   vl_api_af_packet_delete_t *mp;
17007   u8 *host_if_name = 0;
17008   int ret;
17009
17010   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17011     {
17012       if (unformat (i, "name %s", &host_if_name))
17013         vec_add1 (host_if_name, 0);
17014       else
17015         break;
17016     }
17017
17018   if (!vec_len (host_if_name))
17019     {
17020       errmsg ("host-interface name must be specified");
17021       return -99;
17022     }
17023
17024   if (vec_len (host_if_name) > 64)
17025     {
17026       errmsg ("host-interface name too long");
17027       return -99;
17028     }
17029
17030   M (AF_PACKET_DELETE, mp);
17031
17032   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17033   vec_free (host_if_name);
17034
17035   S (mp);
17036   W (ret);
17037   return ret;
17038 }
17039
17040 static int
17041 api_policer_add_del (vat_main_t * vam)
17042 {
17043   unformat_input_t *i = vam->input;
17044   vl_api_policer_add_del_t *mp;
17045   u8 is_add = 1;
17046   u8 *name = 0;
17047   u32 cir = 0;
17048   u32 eir = 0;
17049   u64 cb = 0;
17050   u64 eb = 0;
17051   u8 rate_type = 0;
17052   u8 round_type = 0;
17053   u8 type = 0;
17054   u8 color_aware = 0;
17055   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17056   int ret;
17057
17058   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17059   conform_action.dscp = 0;
17060   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17061   exceed_action.dscp = 0;
17062   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17063   violate_action.dscp = 0;
17064
17065   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17066     {
17067       if (unformat (i, "del"))
17068         is_add = 0;
17069       else if (unformat (i, "name %s", &name))
17070         vec_add1 (name, 0);
17071       else if (unformat (i, "cir %u", &cir))
17072         ;
17073       else if (unformat (i, "eir %u", &eir))
17074         ;
17075       else if (unformat (i, "cb %u", &cb))
17076         ;
17077       else if (unformat (i, "eb %u", &eb))
17078         ;
17079       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17080                          &rate_type))
17081         ;
17082       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17083                          &round_type))
17084         ;
17085       else if (unformat (i, "type %U", unformat_policer_type, &type))
17086         ;
17087       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17088                          &conform_action))
17089         ;
17090       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17091                          &exceed_action))
17092         ;
17093       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17094                          &violate_action))
17095         ;
17096       else if (unformat (i, "color-aware"))
17097         color_aware = 1;
17098       else
17099         break;
17100     }
17101
17102   if (!vec_len (name))
17103     {
17104       errmsg ("policer name must be specified");
17105       return -99;
17106     }
17107
17108   if (vec_len (name) > 64)
17109     {
17110       errmsg ("policer name too long");
17111       return -99;
17112     }
17113
17114   M (POLICER_ADD_DEL, mp);
17115
17116   clib_memcpy (mp->name, name, vec_len (name));
17117   vec_free (name);
17118   mp->is_add = is_add;
17119   mp->cir = cir;
17120   mp->eir = eir;
17121   mp->cb = cb;
17122   mp->eb = eb;
17123   mp->rate_type = rate_type;
17124   mp->round_type = round_type;
17125   mp->type = type;
17126   mp->conform_action_type = conform_action.action_type;
17127   mp->conform_dscp = conform_action.dscp;
17128   mp->exceed_action_type = exceed_action.action_type;
17129   mp->exceed_dscp = exceed_action.dscp;
17130   mp->violate_action_type = violate_action.action_type;
17131   mp->violate_dscp = violate_action.dscp;
17132   mp->color_aware = color_aware;
17133
17134   S (mp);
17135   W (ret);
17136   return ret;
17137 }
17138
17139 static int
17140 api_policer_dump (vat_main_t * vam)
17141 {
17142   unformat_input_t *i = vam->input;
17143   vl_api_policer_dump_t *mp;
17144   vl_api_control_ping_t *mp_ping;
17145   u8 *match_name = 0;
17146   u8 match_name_valid = 0;
17147   int ret;
17148
17149   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17150     {
17151       if (unformat (i, "name %s", &match_name))
17152         {
17153           vec_add1 (match_name, 0);
17154           match_name_valid = 1;
17155         }
17156       else
17157         break;
17158     }
17159
17160   M (POLICER_DUMP, mp);
17161   mp->match_name_valid = match_name_valid;
17162   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
17163   vec_free (match_name);
17164   /* send it... */
17165   S (mp);
17166
17167   /* Use a control ping for synchronization */
17168   M (CONTROL_PING, mp_ping);
17169   S (mp_ping);
17170
17171   /* Wait for a reply... */
17172   W (ret);
17173   return ret;
17174 }
17175
17176 static int
17177 api_policer_classify_set_interface (vat_main_t * vam)
17178 {
17179   unformat_input_t *i = vam->input;
17180   vl_api_policer_classify_set_interface_t *mp;
17181   u32 sw_if_index;
17182   int sw_if_index_set;
17183   u32 ip4_table_index = ~0;
17184   u32 ip6_table_index = ~0;
17185   u32 l2_table_index = ~0;
17186   u8 is_add = 1;
17187   int ret;
17188
17189   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17190     {
17191       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17192         sw_if_index_set = 1;
17193       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17194         sw_if_index_set = 1;
17195       else if (unformat (i, "del"))
17196         is_add = 0;
17197       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17198         ;
17199       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17200         ;
17201       else if (unformat (i, "l2-table %d", &l2_table_index))
17202         ;
17203       else
17204         {
17205           clib_warning ("parse error '%U'", format_unformat_error, i);
17206           return -99;
17207         }
17208     }
17209
17210   if (sw_if_index_set == 0)
17211     {
17212       errmsg ("missing interface name or sw_if_index");
17213       return -99;
17214     }
17215
17216   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
17217
17218   mp->sw_if_index = ntohl (sw_if_index);
17219   mp->ip4_table_index = ntohl (ip4_table_index);
17220   mp->ip6_table_index = ntohl (ip6_table_index);
17221   mp->l2_table_index = ntohl (l2_table_index);
17222   mp->is_add = is_add;
17223
17224   S (mp);
17225   W (ret);
17226   return ret;
17227 }
17228
17229 static int
17230 api_policer_classify_dump (vat_main_t * vam)
17231 {
17232   unformat_input_t *i = vam->input;
17233   vl_api_policer_classify_dump_t *mp;
17234   vl_api_control_ping_t *mp_ping;
17235   u8 type = POLICER_CLASSIFY_N_TABLES;
17236   int ret;
17237
17238   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
17239     ;
17240   else
17241     {
17242       errmsg ("classify table type must be specified");
17243       return -99;
17244     }
17245
17246   if (!vam->json_output)
17247     {
17248       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17249     }
17250
17251   M (POLICER_CLASSIFY_DUMP, mp);
17252   mp->type = type;
17253   /* send it... */
17254   S (mp);
17255
17256   /* Use a control ping for synchronization */
17257   M (CONTROL_PING, mp_ping);
17258   S (mp_ping);
17259
17260   /* Wait for a reply... */
17261   W (ret);
17262   return ret;
17263 }
17264
17265 static int
17266 api_netmap_create (vat_main_t * vam)
17267 {
17268   unformat_input_t *i = vam->input;
17269   vl_api_netmap_create_t *mp;
17270   u8 *if_name = 0;
17271   u8 hw_addr[6];
17272   u8 random_hw_addr = 1;
17273   u8 is_pipe = 0;
17274   u8 is_master = 0;
17275   int ret;
17276
17277   memset (hw_addr, 0, sizeof (hw_addr));
17278
17279   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17280     {
17281       if (unformat (i, "name %s", &if_name))
17282         vec_add1 (if_name, 0);
17283       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17284         random_hw_addr = 0;
17285       else if (unformat (i, "pipe"))
17286         is_pipe = 1;
17287       else if (unformat (i, "master"))
17288         is_master = 1;
17289       else if (unformat (i, "slave"))
17290         is_master = 0;
17291       else
17292         break;
17293     }
17294
17295   if (!vec_len (if_name))
17296     {
17297       errmsg ("interface name must be specified");
17298       return -99;
17299     }
17300
17301   if (vec_len (if_name) > 64)
17302     {
17303       errmsg ("interface name too long");
17304       return -99;
17305     }
17306
17307   M (NETMAP_CREATE, mp);
17308
17309   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
17310   clib_memcpy (mp->hw_addr, hw_addr, 6);
17311   mp->use_random_hw_addr = random_hw_addr;
17312   mp->is_pipe = is_pipe;
17313   mp->is_master = is_master;
17314   vec_free (if_name);
17315
17316   S (mp);
17317   W (ret);
17318   return ret;
17319 }
17320
17321 static int
17322 api_netmap_delete (vat_main_t * vam)
17323 {
17324   unformat_input_t *i = vam->input;
17325   vl_api_netmap_delete_t *mp;
17326   u8 *if_name = 0;
17327   int ret;
17328
17329   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17330     {
17331       if (unformat (i, "name %s", &if_name))
17332         vec_add1 (if_name, 0);
17333       else
17334         break;
17335     }
17336
17337   if (!vec_len (if_name))
17338     {
17339       errmsg ("interface name must be specified");
17340       return -99;
17341     }
17342
17343   if (vec_len (if_name) > 64)
17344     {
17345       errmsg ("interface name too long");
17346       return -99;
17347     }
17348
17349   M (NETMAP_DELETE, mp);
17350
17351   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
17352   vec_free (if_name);
17353
17354   S (mp);
17355   W (ret);
17356   return ret;
17357 }
17358
17359 static void
17360 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
17361 {
17362   if (fp->afi == IP46_TYPE_IP6)
17363     print (vam->ofp,
17364            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17365            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17366            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17367            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17368            format_ip6_address, fp->next_hop);
17369   else if (fp->afi == IP46_TYPE_IP4)
17370     print (vam->ofp,
17371            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17372            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17373            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17374            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17375            format_ip4_address, fp->next_hop);
17376 }
17377
17378 static void
17379 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
17380                                  vl_api_fib_path2_t * fp)
17381 {
17382   struct in_addr ip4;
17383   struct in6_addr ip6;
17384
17385   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17386   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17387   vat_json_object_add_uint (node, "is_local", fp->is_local);
17388   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
17389   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
17390   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
17391   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
17392   if (fp->afi == IP46_TYPE_IP4)
17393     {
17394       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
17395       vat_json_object_add_ip4 (node, "next_hop", ip4);
17396     }
17397   else if (fp->afi == IP46_TYPE_IP6)
17398     {
17399       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
17400       vat_json_object_add_ip6 (node, "next_hop", ip6);
17401     }
17402 }
17403
17404 static void
17405 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
17406 {
17407   vat_main_t *vam = &vat_main;
17408   int count = ntohl (mp->mt_count);
17409   vl_api_fib_path2_t *fp;
17410   i32 i;
17411
17412   print (vam->ofp, "[%d]: sw_if_index %d via:",
17413          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
17414   fp = mp->mt_paths;
17415   for (i = 0; i < count; i++)
17416     {
17417       vl_api_mpls_fib_path_print (vam, fp);
17418       fp++;
17419     }
17420
17421   print (vam->ofp, "");
17422 }
17423
17424 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
17425 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
17426
17427 static void
17428 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
17429 {
17430   vat_main_t *vam = &vat_main;
17431   vat_json_node_t *node = NULL;
17432   int count = ntohl (mp->mt_count);
17433   vl_api_fib_path2_t *fp;
17434   i32 i;
17435
17436   if (VAT_JSON_ARRAY != vam->json_tree.type)
17437     {
17438       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17439       vat_json_init_array (&vam->json_tree);
17440     }
17441   node = vat_json_array_add (&vam->json_tree);
17442
17443   vat_json_init_object (node);
17444   vat_json_object_add_uint (node, "tunnel_index",
17445                             ntohl (mp->mt_tunnel_index));
17446   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
17447
17448   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
17449
17450   fp = mp->mt_paths;
17451   for (i = 0; i < count; i++)
17452     {
17453       vl_api_mpls_fib_path_json_print (node, fp);
17454       fp++;
17455     }
17456 }
17457
17458 static int
17459 api_mpls_tunnel_dump (vat_main_t * vam)
17460 {
17461   vl_api_mpls_tunnel_dump_t *mp;
17462   vl_api_control_ping_t *mp_ping;
17463   i32 index = -1;
17464   int ret;
17465
17466   /* Parse args required to build the message */
17467   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
17468     {
17469       if (!unformat (vam->input, "tunnel_index %d", &index))
17470         {
17471           index = -1;
17472           break;
17473         }
17474     }
17475
17476   print (vam->ofp, "  tunnel_index %d", index);
17477
17478   M (MPLS_TUNNEL_DUMP, mp);
17479   mp->tunnel_index = htonl (index);
17480   S (mp);
17481
17482   /* Use a control ping for synchronization */
17483   M (CONTROL_PING, mp_ping);
17484   S (mp_ping);
17485
17486   W (ret);
17487   return ret;
17488 }
17489
17490 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
17491 #define vl_api_mpls_fib_details_t_print vl_noop_handler
17492
17493
17494 static void
17495 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
17496 {
17497   vat_main_t *vam = &vat_main;
17498   int count = ntohl (mp->count);
17499   vl_api_fib_path2_t *fp;
17500   int i;
17501
17502   print (vam->ofp,
17503          "table-id %d, label %u, ess_bit %u",
17504          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
17505   fp = mp->path;
17506   for (i = 0; i < count; i++)
17507     {
17508       vl_api_mpls_fib_path_print (vam, fp);
17509       fp++;
17510     }
17511 }
17512
17513 static void vl_api_mpls_fib_details_t_handler_json
17514   (vl_api_mpls_fib_details_t * mp)
17515 {
17516   vat_main_t *vam = &vat_main;
17517   int count = ntohl (mp->count);
17518   vat_json_node_t *node = NULL;
17519   vl_api_fib_path2_t *fp;
17520   int i;
17521
17522   if (VAT_JSON_ARRAY != vam->json_tree.type)
17523     {
17524       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17525       vat_json_init_array (&vam->json_tree);
17526     }
17527   node = vat_json_array_add (&vam->json_tree);
17528
17529   vat_json_init_object (node);
17530   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
17531   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
17532   vat_json_object_add_uint (node, "label", ntohl (mp->label));
17533   vat_json_object_add_uint (node, "path_count", count);
17534   fp = mp->path;
17535   for (i = 0; i < count; i++)
17536     {
17537       vl_api_mpls_fib_path_json_print (node, fp);
17538       fp++;
17539     }
17540 }
17541
17542 static int
17543 api_mpls_fib_dump (vat_main_t * vam)
17544 {
17545   vl_api_mpls_fib_dump_t *mp;
17546   vl_api_control_ping_t *mp_ping;
17547   int ret;
17548
17549   M (MPLS_FIB_DUMP, mp);
17550   S (mp);
17551
17552   /* Use a control ping for synchronization */
17553   M (CONTROL_PING, mp_ping);
17554   S (mp_ping);
17555
17556   W (ret);
17557   return ret;
17558 }
17559
17560 #define vl_api_ip_fib_details_t_endian vl_noop_handler
17561 #define vl_api_ip_fib_details_t_print vl_noop_handler
17562
17563 static void
17564 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
17565 {
17566   vat_main_t *vam = &vat_main;
17567   int count = ntohl (mp->count);
17568   vl_api_fib_path_t *fp;
17569   int i;
17570
17571   print (vam->ofp,
17572          "table-id %d, prefix %U/%d",
17573          ntohl (mp->table_id), format_ip4_address, mp->address,
17574          mp->address_length);
17575   fp = mp->path;
17576   for (i = 0; i < count; i++)
17577     {
17578       if (fp->afi == IP46_TYPE_IP6)
17579         print (vam->ofp,
17580                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17581                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17582                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17583                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17584                format_ip6_address, fp->next_hop);
17585       else if (fp->afi == IP46_TYPE_IP4)
17586         print (vam->ofp,
17587                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17588                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17589                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17590                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17591                format_ip4_address, fp->next_hop);
17592       fp++;
17593     }
17594 }
17595
17596 static void vl_api_ip_fib_details_t_handler_json
17597   (vl_api_ip_fib_details_t * mp)
17598 {
17599   vat_main_t *vam = &vat_main;
17600   int count = ntohl (mp->count);
17601   vat_json_node_t *node = NULL;
17602   struct in_addr ip4;
17603   struct in6_addr ip6;
17604   vl_api_fib_path_t *fp;
17605   int i;
17606
17607   if (VAT_JSON_ARRAY != vam->json_tree.type)
17608     {
17609       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17610       vat_json_init_array (&vam->json_tree);
17611     }
17612   node = vat_json_array_add (&vam->json_tree);
17613
17614   vat_json_init_object (node);
17615   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
17616   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
17617   vat_json_object_add_ip4 (node, "prefix", ip4);
17618   vat_json_object_add_uint (node, "mask_length", mp->address_length);
17619   vat_json_object_add_uint (node, "path_count", count);
17620   fp = mp->path;
17621   for (i = 0; i < count; i++)
17622     {
17623       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17624       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17625       vat_json_object_add_uint (node, "is_local", fp->is_local);
17626       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
17627       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
17628       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
17629       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
17630       if (fp->afi == IP46_TYPE_IP4)
17631         {
17632           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
17633           vat_json_object_add_ip4 (node, "next_hop", ip4);
17634         }
17635       else if (fp->afi == IP46_TYPE_IP6)
17636         {
17637           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
17638           vat_json_object_add_ip6 (node, "next_hop", ip6);
17639         }
17640     }
17641 }
17642
17643 static int
17644 api_ip_fib_dump (vat_main_t * vam)
17645 {
17646   vl_api_ip_fib_dump_t *mp;
17647   vl_api_control_ping_t *mp_ping;
17648   int ret;
17649
17650   M (IP_FIB_DUMP, mp);
17651   S (mp);
17652
17653   /* Use a control ping for synchronization */
17654   M (CONTROL_PING, mp_ping);
17655   S (mp_ping);
17656
17657   W (ret);
17658   return ret;
17659 }
17660
17661 static int
17662 api_ip_mfib_dump (vat_main_t * vam)
17663 {
17664   vl_api_ip_mfib_dump_t *mp;
17665   vl_api_control_ping_t *mp_ping;
17666   int ret;
17667
17668   M (IP_MFIB_DUMP, mp);
17669   S (mp);
17670
17671   /* Use a control ping for synchronization */
17672   M (CONTROL_PING, mp_ping);
17673   S (mp_ping);
17674
17675   W (ret);
17676   return ret;
17677 }
17678
17679 static void vl_api_ip_neighbor_details_t_handler
17680   (vl_api_ip_neighbor_details_t * mp)
17681 {
17682   vat_main_t *vam = &vat_main;
17683
17684   print (vam->ofp, "%c %U %U",
17685          (mp->is_static) ? 'S' : 'D',
17686          format_ethernet_address, &mp->mac_address,
17687          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
17688          &mp->ip_address);
17689 }
17690
17691 static void vl_api_ip_neighbor_details_t_handler_json
17692   (vl_api_ip_neighbor_details_t * mp)
17693 {
17694
17695   vat_main_t *vam = &vat_main;
17696   vat_json_node_t *node;
17697   struct in_addr ip4;
17698   struct in6_addr ip6;
17699
17700   if (VAT_JSON_ARRAY != vam->json_tree.type)
17701     {
17702       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17703       vat_json_init_array (&vam->json_tree);
17704     }
17705   node = vat_json_array_add (&vam->json_tree);
17706
17707   vat_json_init_object (node);
17708   vat_json_object_add_string_copy (node, "flag",
17709                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
17710                                    "dynamic");
17711
17712   vat_json_object_add_string_copy (node, "link_layer",
17713                                    format (0, "%U", format_ethernet_address,
17714                                            &mp->mac_address));
17715
17716   if (mp->is_ipv6)
17717     {
17718       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
17719       vat_json_object_add_ip6 (node, "ip_address", ip6);
17720     }
17721   else
17722     {
17723       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
17724       vat_json_object_add_ip4 (node, "ip_address", ip4);
17725     }
17726 }
17727
17728 static int
17729 api_ip_neighbor_dump (vat_main_t * vam)
17730 {
17731   unformat_input_t *i = vam->input;
17732   vl_api_ip_neighbor_dump_t *mp;
17733   vl_api_control_ping_t *mp_ping;
17734   u8 is_ipv6 = 0;
17735   u32 sw_if_index = ~0;
17736   int ret;
17737
17738   /* Parse args required to build the message */
17739   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17740     {
17741       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17742         ;
17743       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17744         ;
17745       else if (unformat (i, "ip6"))
17746         is_ipv6 = 1;
17747       else
17748         break;
17749     }
17750
17751   if (sw_if_index == ~0)
17752     {
17753       errmsg ("missing interface name or sw_if_index");
17754       return -99;
17755     }
17756
17757   M (IP_NEIGHBOR_DUMP, mp);
17758   mp->is_ipv6 = (u8) is_ipv6;
17759   mp->sw_if_index = ntohl (sw_if_index);
17760   S (mp);
17761
17762   /* Use a control ping for synchronization */
17763   M (CONTROL_PING, mp_ping);
17764   S (mp_ping);
17765
17766   W (ret);
17767   return ret;
17768 }
17769
17770 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
17771 #define vl_api_ip6_fib_details_t_print vl_noop_handler
17772
17773 static void
17774 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
17775 {
17776   vat_main_t *vam = &vat_main;
17777   int count = ntohl (mp->count);
17778   vl_api_fib_path_t *fp;
17779   int i;
17780
17781   print (vam->ofp,
17782          "table-id %d, prefix %U/%d",
17783          ntohl (mp->table_id), format_ip6_address, mp->address,
17784          mp->address_length);
17785   fp = mp->path;
17786   for (i = 0; i < count; i++)
17787     {
17788       if (fp->afi == IP46_TYPE_IP6)
17789         print (vam->ofp,
17790                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17791                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17792                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17793                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17794                format_ip6_address, fp->next_hop);
17795       else if (fp->afi == IP46_TYPE_IP4)
17796         print (vam->ofp,
17797                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17798                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17799                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17800                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17801                format_ip4_address, fp->next_hop);
17802       fp++;
17803     }
17804 }
17805
17806 static void vl_api_ip6_fib_details_t_handler_json
17807   (vl_api_ip6_fib_details_t * mp)
17808 {
17809   vat_main_t *vam = &vat_main;
17810   int count = ntohl (mp->count);
17811   vat_json_node_t *node = NULL;
17812   struct in_addr ip4;
17813   struct in6_addr ip6;
17814   vl_api_fib_path_t *fp;
17815   int i;
17816
17817   if (VAT_JSON_ARRAY != vam->json_tree.type)
17818     {
17819       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17820       vat_json_init_array (&vam->json_tree);
17821     }
17822   node = vat_json_array_add (&vam->json_tree);
17823
17824   vat_json_init_object (node);
17825   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
17826   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
17827   vat_json_object_add_ip6 (node, "prefix", ip6);
17828   vat_json_object_add_uint (node, "mask_length", mp->address_length);
17829   vat_json_object_add_uint (node, "path_count", count);
17830   fp = mp->path;
17831   for (i = 0; i < count; i++)
17832     {
17833       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17834       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17835       vat_json_object_add_uint (node, "is_local", fp->is_local);
17836       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
17837       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
17838       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
17839       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
17840       if (fp->afi == IP46_TYPE_IP4)
17841         {
17842           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
17843           vat_json_object_add_ip4 (node, "next_hop", ip4);
17844         }
17845       else if (fp->afi == IP46_TYPE_IP6)
17846         {
17847           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
17848           vat_json_object_add_ip6 (node, "next_hop", ip6);
17849         }
17850     }
17851 }
17852
17853 static int
17854 api_ip6_fib_dump (vat_main_t * vam)
17855 {
17856   vl_api_ip6_fib_dump_t *mp;
17857   vl_api_control_ping_t *mp_ping;
17858   int ret;
17859
17860   M (IP6_FIB_DUMP, mp);
17861   S (mp);
17862
17863   /* Use a control ping for synchronization */
17864   M (CONTROL_PING, mp_ping);
17865   S (mp_ping);
17866
17867   W (ret);
17868   return ret;
17869 }
17870
17871 static int
17872 api_ip6_mfib_dump (vat_main_t * vam)
17873 {
17874   vl_api_ip6_mfib_dump_t *mp;
17875   vl_api_control_ping_t *mp_ping;
17876   int ret;
17877
17878   M (IP6_MFIB_DUMP, mp);
17879   S (mp);
17880
17881   /* Use a control ping for synchronization */
17882   M (CONTROL_PING, mp_ping);
17883   S (mp_ping);
17884
17885   W (ret);
17886   return ret;
17887 }
17888
17889 int
17890 api_classify_table_ids (vat_main_t * vam)
17891 {
17892   vl_api_classify_table_ids_t *mp;
17893   int ret;
17894
17895   /* Construct the API message */
17896   M (CLASSIFY_TABLE_IDS, mp);
17897   mp->context = 0;
17898
17899   S (mp);
17900   W (ret);
17901   return ret;
17902 }
17903
17904 int
17905 api_classify_table_by_interface (vat_main_t * vam)
17906 {
17907   unformat_input_t *input = vam->input;
17908   vl_api_classify_table_by_interface_t *mp;
17909
17910   u32 sw_if_index = ~0;
17911   int ret;
17912   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17913     {
17914       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17915         ;
17916       else if (unformat (input, "sw_if_index %d", &sw_if_index))
17917         ;
17918       else
17919         break;
17920     }
17921   if (sw_if_index == ~0)
17922     {
17923       errmsg ("missing interface name or sw_if_index");
17924       return -99;
17925     }
17926
17927   /* Construct the API message */
17928   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
17929   mp->context = 0;
17930   mp->sw_if_index = ntohl (sw_if_index);
17931
17932   S (mp);
17933   W (ret);
17934   return ret;
17935 }
17936
17937 int
17938 api_classify_table_info (vat_main_t * vam)
17939 {
17940   unformat_input_t *input = vam->input;
17941   vl_api_classify_table_info_t *mp;
17942
17943   u32 table_id = ~0;
17944   int ret;
17945   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17946     {
17947       if (unformat (input, "table_id %d", &table_id))
17948         ;
17949       else
17950         break;
17951     }
17952   if (table_id == ~0)
17953     {
17954       errmsg ("missing table id");
17955       return -99;
17956     }
17957
17958   /* Construct the API message */
17959   M (CLASSIFY_TABLE_INFO, mp);
17960   mp->context = 0;
17961   mp->table_id = ntohl (table_id);
17962
17963   S (mp);
17964   W (ret);
17965   return ret;
17966 }
17967
17968 int
17969 api_classify_session_dump (vat_main_t * vam)
17970 {
17971   unformat_input_t *input = vam->input;
17972   vl_api_classify_session_dump_t *mp;
17973   vl_api_control_ping_t *mp_ping;
17974
17975   u32 table_id = ~0;
17976   int ret;
17977   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17978     {
17979       if (unformat (input, "table_id %d", &table_id))
17980         ;
17981       else
17982         break;
17983     }
17984   if (table_id == ~0)
17985     {
17986       errmsg ("missing table id");
17987       return -99;
17988     }
17989
17990   /* Construct the API message */
17991   M (CLASSIFY_SESSION_DUMP, mp);
17992   mp->context = 0;
17993   mp->table_id = ntohl (table_id);
17994   S (mp);
17995
17996   /* Use a control ping for synchronization */
17997   M (CONTROL_PING, mp_ping);
17998   S (mp_ping);
17999
18000   W (ret);
18001   return ret;
18002 }
18003
18004 static void
18005 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
18006 {
18007   vat_main_t *vam = &vat_main;
18008
18009   print (vam->ofp, "collector_address %U, collector_port %d, "
18010          "src_address %U, vrf_id %d, path_mtu %u, "
18011          "template_interval %u, udp_checksum %d",
18012          format_ip4_address, mp->collector_address,
18013          ntohs (mp->collector_port),
18014          format_ip4_address, mp->src_address,
18015          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
18016          ntohl (mp->template_interval), mp->udp_checksum);
18017
18018   vam->retval = 0;
18019   vam->result_ready = 1;
18020 }
18021
18022 static void
18023   vl_api_ipfix_exporter_details_t_handler_json
18024   (vl_api_ipfix_exporter_details_t * mp)
18025 {
18026   vat_main_t *vam = &vat_main;
18027   vat_json_node_t node;
18028   struct in_addr collector_address;
18029   struct in_addr src_address;
18030
18031   vat_json_init_object (&node);
18032   clib_memcpy (&collector_address, &mp->collector_address,
18033                sizeof (collector_address));
18034   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
18035   vat_json_object_add_uint (&node, "collector_port",
18036                             ntohs (mp->collector_port));
18037   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
18038   vat_json_object_add_ip4 (&node, "src_address", src_address);
18039   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
18040   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
18041   vat_json_object_add_uint (&node, "template_interval",
18042                             ntohl (mp->template_interval));
18043   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
18044
18045   vat_json_print (vam->ofp, &node);
18046   vat_json_free (&node);
18047   vam->retval = 0;
18048   vam->result_ready = 1;
18049 }
18050
18051 int
18052 api_ipfix_exporter_dump (vat_main_t * vam)
18053 {
18054   vl_api_ipfix_exporter_dump_t *mp;
18055   int ret;
18056
18057   /* Construct the API message */
18058   M (IPFIX_EXPORTER_DUMP, mp);
18059   mp->context = 0;
18060
18061   S (mp);
18062   W (ret);
18063   return ret;
18064 }
18065
18066 static int
18067 api_ipfix_classify_stream_dump (vat_main_t * vam)
18068 {
18069   vl_api_ipfix_classify_stream_dump_t *mp;
18070   int ret;
18071
18072   /* Construct the API message */
18073   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
18074   mp->context = 0;
18075
18076   S (mp);
18077   W (ret);
18078   return ret;
18079   /* NOTREACHED */
18080   return 0;
18081 }
18082
18083 static void
18084   vl_api_ipfix_classify_stream_details_t_handler
18085   (vl_api_ipfix_classify_stream_details_t * mp)
18086 {
18087   vat_main_t *vam = &vat_main;
18088   print (vam->ofp, "domain_id %d, src_port %d",
18089          ntohl (mp->domain_id), ntohs (mp->src_port));
18090   vam->retval = 0;
18091   vam->result_ready = 1;
18092 }
18093
18094 static void
18095   vl_api_ipfix_classify_stream_details_t_handler_json
18096   (vl_api_ipfix_classify_stream_details_t * mp)
18097 {
18098   vat_main_t *vam = &vat_main;
18099   vat_json_node_t node;
18100
18101   vat_json_init_object (&node);
18102   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
18103   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
18104
18105   vat_json_print (vam->ofp, &node);
18106   vat_json_free (&node);
18107   vam->retval = 0;
18108   vam->result_ready = 1;
18109 }
18110
18111 static int
18112 api_ipfix_classify_table_dump (vat_main_t * vam)
18113 {
18114   vl_api_ipfix_classify_table_dump_t *mp;
18115   vl_api_control_ping_t *mp_ping;
18116   int ret;
18117
18118   if (!vam->json_output)
18119     {
18120       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
18121              "transport_protocol");
18122     }
18123
18124   /* Construct the API message */
18125   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
18126
18127   /* send it... */
18128   S (mp);
18129
18130   /* Use a control ping for synchronization */
18131   M (CONTROL_PING, mp_ping);
18132   S (mp_ping);
18133
18134   W (ret);
18135   return ret;
18136 }
18137
18138 static void
18139   vl_api_ipfix_classify_table_details_t_handler
18140   (vl_api_ipfix_classify_table_details_t * mp)
18141 {
18142   vat_main_t *vam = &vat_main;
18143   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
18144          mp->transport_protocol);
18145 }
18146
18147 static void
18148   vl_api_ipfix_classify_table_details_t_handler_json
18149   (vl_api_ipfix_classify_table_details_t * mp)
18150 {
18151   vat_json_node_t *node = NULL;
18152   vat_main_t *vam = &vat_main;
18153
18154   if (VAT_JSON_ARRAY != vam->json_tree.type)
18155     {
18156       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18157       vat_json_init_array (&vam->json_tree);
18158     }
18159
18160   node = vat_json_array_add (&vam->json_tree);
18161   vat_json_init_object (node);
18162
18163   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
18164   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
18165   vat_json_object_add_uint (node, "transport_protocol",
18166                             mp->transport_protocol);
18167 }
18168
18169 static int
18170 api_sw_interface_span_enable_disable (vat_main_t * vam)
18171 {
18172   unformat_input_t *i = vam->input;
18173   vl_api_sw_interface_span_enable_disable_t *mp;
18174   u32 src_sw_if_index = ~0;
18175   u32 dst_sw_if_index = ~0;
18176   u8 state = 3;
18177   int ret;
18178   u8 is_l2 = 0;
18179
18180   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18181     {
18182       if (unformat
18183           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
18184         ;
18185       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
18186         ;
18187       else
18188         if (unformat
18189             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
18190         ;
18191       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
18192         ;
18193       else if (unformat (i, "disable"))
18194         state = 0;
18195       else if (unformat (i, "rx"))
18196         state = 1;
18197       else if (unformat (i, "tx"))
18198         state = 2;
18199       else if (unformat (i, "both"))
18200         state = 3;
18201       else if (unformat (i, "l2"))
18202         is_l2 = 1;
18203       else
18204         break;
18205     }
18206
18207   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
18208
18209   mp->sw_if_index_from = htonl (src_sw_if_index);
18210   mp->sw_if_index_to = htonl (dst_sw_if_index);
18211   mp->state = state;
18212   mp->is_l2 = is_l2;
18213
18214   S (mp);
18215   W (ret);
18216   return ret;
18217 }
18218
18219 static void
18220 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
18221                                             * mp)
18222 {
18223   vat_main_t *vam = &vat_main;
18224   u8 *sw_if_from_name = 0;
18225   u8 *sw_if_to_name = 0;
18226   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18227   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18228   char *states[] = { "none", "rx", "tx", "both" };
18229   hash_pair_t *p;
18230
18231   /* *INDENT-OFF* */
18232   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18233   ({
18234     if ((u32) p->value[0] == sw_if_index_from)
18235       {
18236         sw_if_from_name = (u8 *)(p->key);
18237         if (sw_if_to_name)
18238           break;
18239       }
18240     if ((u32) p->value[0] == sw_if_index_to)
18241       {
18242         sw_if_to_name = (u8 *)(p->key);
18243         if (sw_if_from_name)
18244           break;
18245       }
18246   }));
18247   /* *INDENT-ON* */
18248   print (vam->ofp, "%20s => %20s (%s)",
18249          sw_if_from_name, sw_if_to_name, states[mp->state]);
18250 }
18251
18252 static void
18253   vl_api_sw_interface_span_details_t_handler_json
18254   (vl_api_sw_interface_span_details_t * mp)
18255 {
18256   vat_main_t *vam = &vat_main;
18257   vat_json_node_t *node = NULL;
18258   u8 *sw_if_from_name = 0;
18259   u8 *sw_if_to_name = 0;
18260   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18261   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18262   hash_pair_t *p;
18263
18264   /* *INDENT-OFF* */
18265   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18266   ({
18267     if ((u32) p->value[0] == sw_if_index_from)
18268       {
18269         sw_if_from_name = (u8 *)(p->key);
18270         if (sw_if_to_name)
18271           break;
18272       }
18273     if ((u32) p->value[0] == sw_if_index_to)
18274       {
18275         sw_if_to_name = (u8 *)(p->key);
18276         if (sw_if_from_name)
18277           break;
18278       }
18279   }));
18280   /* *INDENT-ON* */
18281
18282   if (VAT_JSON_ARRAY != vam->json_tree.type)
18283     {
18284       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18285       vat_json_init_array (&vam->json_tree);
18286     }
18287   node = vat_json_array_add (&vam->json_tree);
18288
18289   vat_json_init_object (node);
18290   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
18291   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
18292   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
18293   if (0 != sw_if_to_name)
18294     {
18295       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
18296     }
18297   vat_json_object_add_uint (node, "state", mp->state);
18298 }
18299
18300 static int
18301 api_sw_interface_span_dump (vat_main_t * vam)
18302 {
18303   unformat_input_t *input = vam->input;
18304   vl_api_sw_interface_span_dump_t *mp;
18305   vl_api_control_ping_t *mp_ping;
18306   u8 is_l2 = 0;
18307   int ret;
18308
18309   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18310     {
18311       if (unformat (input, "l2"))
18312         is_l2 = 1;
18313       else
18314         break;
18315     }
18316
18317   M (SW_INTERFACE_SPAN_DUMP, mp);
18318   mp->is_l2 = is_l2;
18319   S (mp);
18320
18321   /* Use a control ping for synchronization */
18322   M (CONTROL_PING, mp_ping);
18323   S (mp_ping);
18324
18325   W (ret);
18326   return ret;
18327 }
18328
18329 int
18330 api_pg_create_interface (vat_main_t * vam)
18331 {
18332   unformat_input_t *input = vam->input;
18333   vl_api_pg_create_interface_t *mp;
18334
18335   u32 if_id = ~0;
18336   int ret;
18337   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18338     {
18339       if (unformat (input, "if_id %d", &if_id))
18340         ;
18341       else
18342         break;
18343     }
18344   if (if_id == ~0)
18345     {
18346       errmsg ("missing pg interface index");
18347       return -99;
18348     }
18349
18350   /* Construct the API message */
18351   M (PG_CREATE_INTERFACE, mp);
18352   mp->context = 0;
18353   mp->interface_id = ntohl (if_id);
18354
18355   S (mp);
18356   W (ret);
18357   return ret;
18358 }
18359
18360 int
18361 api_pg_capture (vat_main_t * vam)
18362 {
18363   unformat_input_t *input = vam->input;
18364   vl_api_pg_capture_t *mp;
18365
18366   u32 if_id = ~0;
18367   u8 enable = 1;
18368   u32 count = 1;
18369   u8 pcap_file_set = 0;
18370   u8 *pcap_file = 0;
18371   int ret;
18372   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18373     {
18374       if (unformat (input, "if_id %d", &if_id))
18375         ;
18376       else if (unformat (input, "pcap %s", &pcap_file))
18377         pcap_file_set = 1;
18378       else if (unformat (input, "count %d", &count))
18379         ;
18380       else if (unformat (input, "disable"))
18381         enable = 0;
18382       else
18383         break;
18384     }
18385   if (if_id == ~0)
18386     {
18387       errmsg ("missing pg interface index");
18388       return -99;
18389     }
18390   if (pcap_file_set > 0)
18391     {
18392       if (vec_len (pcap_file) > 255)
18393         {
18394           errmsg ("pcap file name is too long");
18395           return -99;
18396         }
18397     }
18398
18399   u32 name_len = vec_len (pcap_file);
18400   /* Construct the API message */
18401   M (PG_CAPTURE, mp);
18402   mp->context = 0;
18403   mp->interface_id = ntohl (if_id);
18404   mp->is_enabled = enable;
18405   mp->count = ntohl (count);
18406   mp->pcap_name_length = ntohl (name_len);
18407   if (pcap_file_set != 0)
18408     {
18409       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
18410     }
18411   vec_free (pcap_file);
18412
18413   S (mp);
18414   W (ret);
18415   return ret;
18416 }
18417
18418 int
18419 api_pg_enable_disable (vat_main_t * vam)
18420 {
18421   unformat_input_t *input = vam->input;
18422   vl_api_pg_enable_disable_t *mp;
18423
18424   u8 enable = 1;
18425   u8 stream_name_set = 0;
18426   u8 *stream_name = 0;
18427   int ret;
18428   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18429     {
18430       if (unformat (input, "stream %s", &stream_name))
18431         stream_name_set = 1;
18432       else if (unformat (input, "disable"))
18433         enable = 0;
18434       else
18435         break;
18436     }
18437
18438   if (stream_name_set > 0)
18439     {
18440       if (vec_len (stream_name) > 255)
18441         {
18442           errmsg ("stream name too long");
18443           return -99;
18444         }
18445     }
18446
18447   u32 name_len = vec_len (stream_name);
18448   /* Construct the API message */
18449   M (PG_ENABLE_DISABLE, mp);
18450   mp->context = 0;
18451   mp->is_enabled = enable;
18452   if (stream_name_set != 0)
18453     {
18454       mp->stream_name_length = ntohl (name_len);
18455       clib_memcpy (mp->stream_name, stream_name, name_len);
18456     }
18457   vec_free (stream_name);
18458
18459   S (mp);
18460   W (ret);
18461   return ret;
18462 }
18463
18464 int
18465 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
18466 {
18467   unformat_input_t *input = vam->input;
18468   vl_api_ip_source_and_port_range_check_add_del_t *mp;
18469
18470   u16 *low_ports = 0;
18471   u16 *high_ports = 0;
18472   u16 this_low;
18473   u16 this_hi;
18474   ip4_address_t ip4_addr;
18475   ip6_address_t ip6_addr;
18476   u32 length;
18477   u32 tmp, tmp2;
18478   u8 prefix_set = 0;
18479   u32 vrf_id = ~0;
18480   u8 is_add = 1;
18481   u8 is_ipv6 = 0;
18482   int ret;
18483
18484   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18485     {
18486       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
18487         {
18488           prefix_set = 1;
18489         }
18490       else
18491         if (unformat
18492             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
18493         {
18494           prefix_set = 1;
18495           is_ipv6 = 1;
18496         }
18497       else if (unformat (input, "vrf %d", &vrf_id))
18498         ;
18499       else if (unformat (input, "del"))
18500         is_add = 0;
18501       else if (unformat (input, "port %d", &tmp))
18502         {
18503           if (tmp == 0 || tmp > 65535)
18504             {
18505               errmsg ("port %d out of range", tmp);
18506               return -99;
18507             }
18508           this_low = tmp;
18509           this_hi = this_low + 1;
18510           vec_add1 (low_ports, this_low);
18511           vec_add1 (high_ports, this_hi);
18512         }
18513       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
18514         {
18515           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
18516             {
18517               errmsg ("incorrect range parameters");
18518               return -99;
18519             }
18520           this_low = tmp;
18521           /* Note: in debug CLI +1 is added to high before
18522              passing to real fn that does "the work"
18523              (ip_source_and_port_range_check_add_del).
18524              This fn is a wrapper around the binary API fn a
18525              control plane will call, which expects this increment
18526              to have occurred. Hence letting the binary API control
18527              plane fn do the increment for consistency between VAT
18528              and other control planes.
18529            */
18530           this_hi = tmp2;
18531           vec_add1 (low_ports, this_low);
18532           vec_add1 (high_ports, this_hi);
18533         }
18534       else
18535         break;
18536     }
18537
18538   if (prefix_set == 0)
18539     {
18540       errmsg ("<address>/<mask> not specified");
18541       return -99;
18542     }
18543
18544   if (vrf_id == ~0)
18545     {
18546       errmsg ("VRF ID required, not specified");
18547       return -99;
18548     }
18549
18550   if (vrf_id == 0)
18551     {
18552       errmsg
18553         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18554       return -99;
18555     }
18556
18557   if (vec_len (low_ports) == 0)
18558     {
18559       errmsg ("At least one port or port range required");
18560       return -99;
18561     }
18562
18563   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
18564
18565   mp->is_add = is_add;
18566
18567   if (is_ipv6)
18568     {
18569       mp->is_ipv6 = 1;
18570       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
18571     }
18572   else
18573     {
18574       mp->is_ipv6 = 0;
18575       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
18576     }
18577
18578   mp->mask_length = length;
18579   mp->number_of_ranges = vec_len (low_ports);
18580
18581   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
18582   vec_free (low_ports);
18583
18584   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
18585   vec_free (high_ports);
18586
18587   mp->vrf_id = ntohl (vrf_id);
18588
18589   S (mp);
18590   W (ret);
18591   return ret;
18592 }
18593
18594 int
18595 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
18596 {
18597   unformat_input_t *input = vam->input;
18598   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
18599   u32 sw_if_index = ~0;
18600   int vrf_set = 0;
18601   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
18602   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
18603   u8 is_add = 1;
18604   int ret;
18605
18606   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18607     {
18608       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18609         ;
18610       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18611         ;
18612       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
18613         vrf_set = 1;
18614       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
18615         vrf_set = 1;
18616       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
18617         vrf_set = 1;
18618       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
18619         vrf_set = 1;
18620       else if (unformat (input, "del"))
18621         is_add = 0;
18622       else
18623         break;
18624     }
18625
18626   if (sw_if_index == ~0)
18627     {
18628       errmsg ("Interface required but not specified");
18629       return -99;
18630     }
18631
18632   if (vrf_set == 0)
18633     {
18634       errmsg ("VRF ID required but not specified");
18635       return -99;
18636     }
18637
18638   if (tcp_out_vrf_id == 0
18639       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
18640     {
18641       errmsg
18642         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18643       return -99;
18644     }
18645
18646   /* Construct the API message */
18647   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
18648
18649   mp->sw_if_index = ntohl (sw_if_index);
18650   mp->is_add = is_add;
18651   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
18652   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
18653   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
18654   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
18655
18656   /* send it... */
18657   S (mp);
18658
18659   /* Wait for a reply... */
18660   W (ret);
18661   return ret;
18662 }
18663
18664 static int
18665 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
18666 {
18667   unformat_input_t *i = vam->input;
18668   vl_api_ipsec_gre_add_del_tunnel_t *mp;
18669   u32 local_sa_id = 0;
18670   u32 remote_sa_id = 0;
18671   ip4_address_t src_address;
18672   ip4_address_t dst_address;
18673   u8 is_add = 1;
18674   int ret;
18675
18676   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18677     {
18678       if (unformat (i, "local_sa %d", &local_sa_id))
18679         ;
18680       else if (unformat (i, "remote_sa %d", &remote_sa_id))
18681         ;
18682       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
18683         ;
18684       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
18685         ;
18686       else if (unformat (i, "del"))
18687         is_add = 0;
18688       else
18689         {
18690           clib_warning ("parse error '%U'", format_unformat_error, i);
18691           return -99;
18692         }
18693     }
18694
18695   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
18696
18697   mp->local_sa_id = ntohl (local_sa_id);
18698   mp->remote_sa_id = ntohl (remote_sa_id);
18699   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
18700   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
18701   mp->is_add = is_add;
18702
18703   S (mp);
18704   W (ret);
18705   return ret;
18706 }
18707
18708 static int
18709 api_punt (vat_main_t * vam)
18710 {
18711   unformat_input_t *i = vam->input;
18712   vl_api_punt_t *mp;
18713   u32 ipv = ~0;
18714   u32 protocol = ~0;
18715   u32 port = ~0;
18716   int is_add = 1;
18717   int ret;
18718
18719   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18720     {
18721       if (unformat (i, "ip %d", &ipv))
18722         ;
18723       else if (unformat (i, "protocol %d", &protocol))
18724         ;
18725       else if (unformat (i, "port %d", &port))
18726         ;
18727       else if (unformat (i, "del"))
18728         is_add = 0;
18729       else
18730         {
18731           clib_warning ("parse error '%U'", format_unformat_error, i);
18732           return -99;
18733         }
18734     }
18735
18736   M (PUNT, mp);
18737
18738   mp->is_add = (u8) is_add;
18739   mp->ipv = (u8) ipv;
18740   mp->l4_protocol = (u8) protocol;
18741   mp->l4_port = htons ((u16) port);
18742
18743   S (mp);
18744   W (ret);
18745   return ret;
18746 }
18747
18748 static void vl_api_ipsec_gre_tunnel_details_t_handler
18749   (vl_api_ipsec_gre_tunnel_details_t * mp)
18750 {
18751   vat_main_t *vam = &vat_main;
18752
18753   print (vam->ofp, "%11d%15U%15U%14d%14d",
18754          ntohl (mp->sw_if_index),
18755          format_ip4_address, &mp->src_address,
18756          format_ip4_address, &mp->dst_address,
18757          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
18758 }
18759
18760 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
18761   (vl_api_ipsec_gre_tunnel_details_t * mp)
18762 {
18763   vat_main_t *vam = &vat_main;
18764   vat_json_node_t *node = NULL;
18765   struct in_addr ip4;
18766
18767   if (VAT_JSON_ARRAY != vam->json_tree.type)
18768     {
18769       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18770       vat_json_init_array (&vam->json_tree);
18771     }
18772   node = vat_json_array_add (&vam->json_tree);
18773
18774   vat_json_init_object (node);
18775   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18776   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
18777   vat_json_object_add_ip4 (node, "src_address", ip4);
18778   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
18779   vat_json_object_add_ip4 (node, "dst_address", ip4);
18780   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
18781   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
18782 }
18783
18784 static int
18785 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
18786 {
18787   unformat_input_t *i = vam->input;
18788   vl_api_ipsec_gre_tunnel_dump_t *mp;
18789   vl_api_control_ping_t *mp_ping;
18790   u32 sw_if_index;
18791   u8 sw_if_index_set = 0;
18792   int ret;
18793
18794   /* Parse args required to build the message */
18795   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18796     {
18797       if (unformat (i, "sw_if_index %d", &sw_if_index))
18798         sw_if_index_set = 1;
18799       else
18800         break;
18801     }
18802
18803   if (sw_if_index_set == 0)
18804     {
18805       sw_if_index = ~0;
18806     }
18807
18808   if (!vam->json_output)
18809     {
18810       print (vam->ofp, "%11s%15s%15s%14s%14s",
18811              "sw_if_index", "src_address", "dst_address",
18812              "local_sa_id", "remote_sa_id");
18813     }
18814
18815   /* Get list of gre-tunnel interfaces */
18816   M (IPSEC_GRE_TUNNEL_DUMP, mp);
18817
18818   mp->sw_if_index = htonl (sw_if_index);
18819
18820   S (mp);
18821
18822   /* Use a control ping for synchronization */
18823   M (CONTROL_PING, mp_ping);
18824   S (mp_ping);
18825
18826   W (ret);
18827   return ret;
18828 }
18829
18830 static int
18831 api_delete_subif (vat_main_t * vam)
18832 {
18833   unformat_input_t *i = vam->input;
18834   vl_api_delete_subif_t *mp;
18835   u32 sw_if_index = ~0;
18836   int ret;
18837
18838   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18839     {
18840       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18841         ;
18842       if (unformat (i, "sw_if_index %d", &sw_if_index))
18843         ;
18844       else
18845         break;
18846     }
18847
18848   if (sw_if_index == ~0)
18849     {
18850       errmsg ("missing sw_if_index");
18851       return -99;
18852     }
18853
18854   /* Construct the API message */
18855   M (DELETE_SUBIF, mp);
18856   mp->sw_if_index = ntohl (sw_if_index);
18857
18858   S (mp);
18859   W (ret);
18860   return ret;
18861 }
18862
18863 #define foreach_pbb_vtr_op      \
18864 _("disable",  L2_VTR_DISABLED)  \
18865 _("pop",  L2_VTR_POP_2)         \
18866 _("push",  L2_VTR_PUSH_2)
18867
18868 static int
18869 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
18870 {
18871   unformat_input_t *i = vam->input;
18872   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
18873   u32 sw_if_index = ~0, vtr_op = ~0;
18874   u16 outer_tag = ~0;
18875   u8 dmac[6], smac[6];
18876   u8 dmac_set = 0, smac_set = 0;
18877   u16 vlanid = 0;
18878   u32 sid = ~0;
18879   u32 tmp;
18880   int ret;
18881
18882   /* Shut up coverity */
18883   memset (dmac, 0, sizeof (dmac));
18884   memset (smac, 0, sizeof (smac));
18885
18886   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18887     {
18888       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18889         ;
18890       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18891         ;
18892       else if (unformat (i, "vtr_op %d", &vtr_op))
18893         ;
18894 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
18895       foreach_pbb_vtr_op
18896 #undef _
18897         else if (unformat (i, "translate_pbb_stag"))
18898         {
18899           if (unformat (i, "%d", &tmp))
18900             {
18901               vtr_op = L2_VTR_TRANSLATE_2_1;
18902               outer_tag = tmp;
18903             }
18904           else
18905             {
18906               errmsg
18907                 ("translate_pbb_stag operation requires outer tag definition");
18908               return -99;
18909             }
18910         }
18911       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
18912         dmac_set++;
18913       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
18914         smac_set++;
18915       else if (unformat (i, "sid %d", &sid))
18916         ;
18917       else if (unformat (i, "vlanid %d", &tmp))
18918         vlanid = tmp;
18919       else
18920         {
18921           clib_warning ("parse error '%U'", format_unformat_error, i);
18922           return -99;
18923         }
18924     }
18925
18926   if ((sw_if_index == ~0) || (vtr_op == ~0))
18927     {
18928       errmsg ("missing sw_if_index or vtr operation");
18929       return -99;
18930     }
18931   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
18932       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
18933     {
18934       errmsg
18935         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
18936       return -99;
18937     }
18938
18939   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
18940   mp->sw_if_index = ntohl (sw_if_index);
18941   mp->vtr_op = ntohl (vtr_op);
18942   mp->outer_tag = ntohs (outer_tag);
18943   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
18944   clib_memcpy (mp->b_smac, smac, sizeof (smac));
18945   mp->b_vlanid = ntohs (vlanid);
18946   mp->i_sid = ntohl (sid);
18947
18948   S (mp);
18949   W (ret);
18950   return ret;
18951 }
18952
18953 static int
18954 api_flow_classify_set_interface (vat_main_t * vam)
18955 {
18956   unformat_input_t *i = vam->input;
18957   vl_api_flow_classify_set_interface_t *mp;
18958   u32 sw_if_index;
18959   int sw_if_index_set;
18960   u32 ip4_table_index = ~0;
18961   u32 ip6_table_index = ~0;
18962   u8 is_add = 1;
18963   int ret;
18964
18965   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18966     {
18967       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18968         sw_if_index_set = 1;
18969       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18970         sw_if_index_set = 1;
18971       else if (unformat (i, "del"))
18972         is_add = 0;
18973       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18974         ;
18975       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18976         ;
18977       else
18978         {
18979           clib_warning ("parse error '%U'", format_unformat_error, i);
18980           return -99;
18981         }
18982     }
18983
18984   if (sw_if_index_set == 0)
18985     {
18986       errmsg ("missing interface name or sw_if_index");
18987       return -99;
18988     }
18989
18990   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
18991
18992   mp->sw_if_index = ntohl (sw_if_index);
18993   mp->ip4_table_index = ntohl (ip4_table_index);
18994   mp->ip6_table_index = ntohl (ip6_table_index);
18995   mp->is_add = is_add;
18996
18997   S (mp);
18998   W (ret);
18999   return ret;
19000 }
19001
19002 static int
19003 api_flow_classify_dump (vat_main_t * vam)
19004 {
19005   unformat_input_t *i = vam->input;
19006   vl_api_flow_classify_dump_t *mp;
19007   vl_api_control_ping_t *mp_ping;
19008   u8 type = FLOW_CLASSIFY_N_TABLES;
19009   int ret;
19010
19011   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19012     ;
19013   else
19014     {
19015       errmsg ("classify table type must be specified");
19016       return -99;
19017     }
19018
19019   if (!vam->json_output)
19020     {
19021       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19022     }
19023
19024   M (FLOW_CLASSIFY_DUMP, mp);
19025   mp->type = type;
19026   /* send it... */
19027   S (mp);
19028
19029   /* Use a control ping for synchronization */
19030   M (CONTROL_PING, mp_ping);
19031   S (mp_ping);
19032
19033   /* Wait for a reply... */
19034   W (ret);
19035   return ret;
19036 }
19037
19038 static int
19039 api_feature_enable_disable (vat_main_t * vam)
19040 {
19041   unformat_input_t *i = vam->input;
19042   vl_api_feature_enable_disable_t *mp;
19043   u8 *arc_name = 0;
19044   u8 *feature_name = 0;
19045   u32 sw_if_index = ~0;
19046   u8 enable = 1;
19047   int ret;
19048
19049   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19050     {
19051       if (unformat (i, "arc_name %s", &arc_name))
19052         ;
19053       else if (unformat (i, "feature_name %s", &feature_name))
19054         ;
19055       else
19056         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19057         ;
19058       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19059         ;
19060       else if (unformat (i, "disable"))
19061         enable = 0;
19062       else
19063         break;
19064     }
19065
19066   if (arc_name == 0)
19067     {
19068       errmsg ("missing arc name");
19069       return -99;
19070     }
19071   if (vec_len (arc_name) > 63)
19072     {
19073       errmsg ("arc name too long");
19074     }
19075
19076   if (feature_name == 0)
19077     {
19078       errmsg ("missing feature name");
19079       return -99;
19080     }
19081   if (vec_len (feature_name) > 63)
19082     {
19083       errmsg ("feature name too long");
19084     }
19085
19086   if (sw_if_index == ~0)
19087     {
19088       errmsg ("missing interface name or sw_if_index");
19089       return -99;
19090     }
19091
19092   /* Construct the API message */
19093   M (FEATURE_ENABLE_DISABLE, mp);
19094   mp->sw_if_index = ntohl (sw_if_index);
19095   mp->enable = enable;
19096   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
19097   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
19098   vec_free (arc_name);
19099   vec_free (feature_name);
19100
19101   S (mp);
19102   W (ret);
19103   return ret;
19104 }
19105
19106 static int
19107 api_sw_interface_tag_add_del (vat_main_t * vam)
19108 {
19109   unformat_input_t *i = vam->input;
19110   vl_api_sw_interface_tag_add_del_t *mp;
19111   u32 sw_if_index = ~0;
19112   u8 *tag = 0;
19113   u8 enable = 1;
19114   int ret;
19115
19116   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19117     {
19118       if (unformat (i, "tag %s", &tag))
19119         ;
19120       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19121         ;
19122       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19123         ;
19124       else if (unformat (i, "del"))
19125         enable = 0;
19126       else
19127         break;
19128     }
19129
19130   if (sw_if_index == ~0)
19131     {
19132       errmsg ("missing interface name or sw_if_index");
19133       return -99;
19134     }
19135
19136   if (enable && (tag == 0))
19137     {
19138       errmsg ("no tag specified");
19139       return -99;
19140     }
19141
19142   /* Construct the API message */
19143   M (SW_INTERFACE_TAG_ADD_DEL, mp);
19144   mp->sw_if_index = ntohl (sw_if_index);
19145   mp->is_add = enable;
19146   if (enable)
19147     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
19148   vec_free (tag);
19149
19150   S (mp);
19151   W (ret);
19152   return ret;
19153 }
19154
19155 static void vl_api_l2_xconnect_details_t_handler
19156   (vl_api_l2_xconnect_details_t * mp)
19157 {
19158   vat_main_t *vam = &vat_main;
19159
19160   print (vam->ofp, "%15d%15d",
19161          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
19162 }
19163
19164 static void vl_api_l2_xconnect_details_t_handler_json
19165   (vl_api_l2_xconnect_details_t * mp)
19166 {
19167   vat_main_t *vam = &vat_main;
19168   vat_json_node_t *node = NULL;
19169
19170   if (VAT_JSON_ARRAY != vam->json_tree.type)
19171     {
19172       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19173       vat_json_init_array (&vam->json_tree);
19174     }
19175   node = vat_json_array_add (&vam->json_tree);
19176
19177   vat_json_init_object (node);
19178   vat_json_object_add_uint (node, "rx_sw_if_index",
19179                             ntohl (mp->rx_sw_if_index));
19180   vat_json_object_add_uint (node, "tx_sw_if_index",
19181                             ntohl (mp->tx_sw_if_index));
19182 }
19183
19184 static int
19185 api_l2_xconnect_dump (vat_main_t * vam)
19186 {
19187   vl_api_l2_xconnect_dump_t *mp;
19188   vl_api_control_ping_t *mp_ping;
19189   int ret;
19190
19191   if (!vam->json_output)
19192     {
19193       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
19194     }
19195
19196   M (L2_XCONNECT_DUMP, mp);
19197
19198   S (mp);
19199
19200   /* Use a control ping for synchronization */
19201   M (CONTROL_PING, mp_ping);
19202   S (mp_ping);
19203
19204   W (ret);
19205   return ret;
19206 }
19207
19208 static int
19209 api_sw_interface_set_mtu (vat_main_t * vam)
19210 {
19211   unformat_input_t *i = vam->input;
19212   vl_api_sw_interface_set_mtu_t *mp;
19213   u32 sw_if_index = ~0;
19214   u32 mtu = 0;
19215   int ret;
19216
19217   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19218     {
19219       if (unformat (i, "mtu %d", &mtu))
19220         ;
19221       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19222         ;
19223       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19224         ;
19225       else
19226         break;
19227     }
19228
19229   if (sw_if_index == ~0)
19230     {
19231       errmsg ("missing interface name or sw_if_index");
19232       return -99;
19233     }
19234
19235   if (mtu == 0)
19236     {
19237       errmsg ("no mtu specified");
19238       return -99;
19239     }
19240
19241   /* Construct the API message */
19242   M (SW_INTERFACE_SET_MTU, mp);
19243   mp->sw_if_index = ntohl (sw_if_index);
19244   mp->mtu = ntohs ((u16) mtu);
19245
19246   S (mp);
19247   W (ret);
19248   return ret;
19249 }
19250
19251 static int
19252 api_p2p_ethernet_add (vat_main_t * vam)
19253 {
19254   unformat_input_t *i = vam->input;
19255   vl_api_p2p_ethernet_add_t *mp;
19256   u32 parent_if_index = ~0;
19257   u32 sub_id = ~0;
19258   u8 remote_mac[6];
19259   u8 mac_set = 0;
19260   int ret;
19261
19262   memset (remote_mac, 0, sizeof (remote_mac));
19263   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19264     {
19265       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19266         ;
19267       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19268         ;
19269       else
19270         if (unformat
19271             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19272         mac_set++;
19273       else if (unformat (i, "sub_id %d", &sub_id))
19274         ;
19275       else
19276         {
19277           clib_warning ("parse error '%U'", format_unformat_error, i);
19278           return -99;
19279         }
19280     }
19281
19282   if (parent_if_index == ~0)
19283     {
19284       errmsg ("missing interface name or sw_if_index");
19285       return -99;
19286     }
19287   if (mac_set == 0)
19288     {
19289       errmsg ("missing remote mac address");
19290       return -99;
19291     }
19292   if (sub_id == ~0)
19293     {
19294       errmsg ("missing sub-interface id");
19295       return -99;
19296     }
19297
19298   M (P2P_ETHERNET_ADD, mp);
19299   mp->parent_if_index = ntohl (parent_if_index);
19300   mp->subif_id = ntohl (sub_id);
19301   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19302
19303   S (mp);
19304   W (ret);
19305   return ret;
19306 }
19307
19308 static int
19309 api_p2p_ethernet_del (vat_main_t * vam)
19310 {
19311   unformat_input_t *i = vam->input;
19312   vl_api_p2p_ethernet_del_t *mp;
19313   u32 parent_if_index = ~0;
19314   u8 remote_mac[6];
19315   u8 mac_set = 0;
19316   int ret;
19317
19318   memset (remote_mac, 0, sizeof (remote_mac));
19319   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19320     {
19321       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19322         ;
19323       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19324         ;
19325       else
19326         if (unformat
19327             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19328         mac_set++;
19329       else
19330         {
19331           clib_warning ("parse error '%U'", format_unformat_error, i);
19332           return -99;
19333         }
19334     }
19335
19336   if (parent_if_index == ~0)
19337     {
19338       errmsg ("missing interface name or sw_if_index");
19339       return -99;
19340     }
19341   if (mac_set == 0)
19342     {
19343       errmsg ("missing remote mac address");
19344       return -99;
19345     }
19346
19347   M (P2P_ETHERNET_DEL, mp);
19348   mp->parent_if_index = ntohl (parent_if_index);
19349   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19350
19351   S (mp);
19352   W (ret);
19353   return ret;
19354 }
19355
19356 static int
19357 api_lldp_config (vat_main_t * vam)
19358 {
19359   unformat_input_t *i = vam->input;
19360   vl_api_lldp_config_t *mp;
19361   int tx_hold = 0;
19362   int tx_interval = 0;
19363   u8 *sys_name = NULL;
19364   int ret;
19365
19366   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19367     {
19368       if (unformat (i, "system-name %s", &sys_name))
19369         ;
19370       else if (unformat (i, "tx-hold %d", &tx_hold))
19371         ;
19372       else if (unformat (i, "tx-interval %d", &tx_interval))
19373         ;
19374       else
19375         {
19376           clib_warning ("parse error '%U'", format_unformat_error, i);
19377           return -99;
19378         }
19379     }
19380
19381   vec_add1 (sys_name, 0);
19382
19383   M (LLDP_CONFIG, mp);
19384   mp->tx_hold = htonl (tx_hold);
19385   mp->tx_interval = htonl (tx_interval);
19386   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
19387   vec_free (sys_name);
19388
19389   S (mp);
19390   W (ret);
19391   return ret;
19392 }
19393
19394 static int
19395 api_sw_interface_set_lldp (vat_main_t * vam)
19396 {
19397   unformat_input_t *i = vam->input;
19398   vl_api_sw_interface_set_lldp_t *mp;
19399   u32 sw_if_index = ~0;
19400   u32 enable = 1;
19401   u8 *port_desc = NULL;
19402   int ret;
19403
19404   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19405     {
19406       if (unformat (i, "disable"))
19407         enable = 0;
19408       else
19409         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19410         ;
19411       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19412         ;
19413       else if (unformat (i, "port-desc %s", &port_desc))
19414         ;
19415       else
19416         break;
19417     }
19418
19419   if (sw_if_index == ~0)
19420     {
19421       errmsg ("missing interface name or sw_if_index");
19422       return -99;
19423     }
19424
19425   /* Construct the API message */
19426   vec_add1 (port_desc, 0);
19427   M (SW_INTERFACE_SET_LLDP, mp);
19428   mp->sw_if_index = ntohl (sw_if_index);
19429   mp->enable = enable;
19430   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
19431   vec_free (port_desc);
19432
19433   S (mp);
19434   W (ret);
19435   return ret;
19436 }
19437
19438 static int
19439 q_or_quit (vat_main_t * vam)
19440 {
19441 #if VPP_API_TEST_BUILTIN == 0
19442   longjmp (vam->jump_buf, 1);
19443 #endif
19444   return 0;                     /* not so much */
19445 }
19446
19447 static int
19448 q (vat_main_t * vam)
19449 {
19450   return q_or_quit (vam);
19451 }
19452
19453 static int
19454 quit (vat_main_t * vam)
19455 {
19456   return q_or_quit (vam);
19457 }
19458
19459 static int
19460 comment (vat_main_t * vam)
19461 {
19462   return 0;
19463 }
19464
19465 static int
19466 cmd_cmp (void *a1, void *a2)
19467 {
19468   u8 **c1 = a1;
19469   u8 **c2 = a2;
19470
19471   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
19472 }
19473
19474 static int
19475 help (vat_main_t * vam)
19476 {
19477   u8 **cmds = 0;
19478   u8 *name = 0;
19479   hash_pair_t *p;
19480   unformat_input_t *i = vam->input;
19481   int j;
19482
19483   if (unformat (i, "%s", &name))
19484     {
19485       uword *hs;
19486
19487       vec_add1 (name, 0);
19488
19489       hs = hash_get_mem (vam->help_by_name, name);
19490       if (hs)
19491         print (vam->ofp, "usage: %s %s", name, hs[0]);
19492       else
19493         print (vam->ofp, "No such msg / command '%s'", name);
19494       vec_free (name);
19495       return 0;
19496     }
19497
19498   print (vam->ofp, "Help is available for the following:");
19499
19500     /* *INDENT-OFF* */
19501     hash_foreach_pair (p, vam->function_by_name,
19502     ({
19503       vec_add1 (cmds, (u8 *)(p->key));
19504     }));
19505     /* *INDENT-ON* */
19506
19507   vec_sort_with_function (cmds, cmd_cmp);
19508
19509   for (j = 0; j < vec_len (cmds); j++)
19510     print (vam->ofp, "%s", cmds[j]);
19511
19512   vec_free (cmds);
19513   return 0;
19514 }
19515
19516 static int
19517 set (vat_main_t * vam)
19518 {
19519   u8 *name = 0, *value = 0;
19520   unformat_input_t *i = vam->input;
19521
19522   if (unformat (i, "%s", &name))
19523     {
19524       /* The input buffer is a vector, not a string. */
19525       value = vec_dup (i->buffer);
19526       vec_delete (value, i->index, 0);
19527       /* Almost certainly has a trailing newline */
19528       if (value[vec_len (value) - 1] == '\n')
19529         value[vec_len (value) - 1] = 0;
19530       /* Make sure it's a proper string, one way or the other */
19531       vec_add1 (value, 0);
19532       (void) clib_macro_set_value (&vam->macro_main,
19533                                    (char *) name, (char *) value);
19534     }
19535   else
19536     errmsg ("usage: set <name> <value>");
19537
19538   vec_free (name);
19539   vec_free (value);
19540   return 0;
19541 }
19542
19543 static int
19544 unset (vat_main_t * vam)
19545 {
19546   u8 *name = 0;
19547
19548   if (unformat (vam->input, "%s", &name))
19549     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
19550       errmsg ("unset: %s wasn't set", name);
19551   vec_free (name);
19552   return 0;
19553 }
19554
19555 typedef struct
19556 {
19557   u8 *name;
19558   u8 *value;
19559 } macro_sort_t;
19560
19561
19562 static int
19563 macro_sort_cmp (void *a1, void *a2)
19564 {
19565   macro_sort_t *s1 = a1;
19566   macro_sort_t *s2 = a2;
19567
19568   return strcmp ((char *) (s1->name), (char *) (s2->name));
19569 }
19570
19571 static int
19572 dump_macro_table (vat_main_t * vam)
19573 {
19574   macro_sort_t *sort_me = 0, *sm;
19575   int i;
19576   hash_pair_t *p;
19577
19578     /* *INDENT-OFF* */
19579     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
19580     ({
19581       vec_add2 (sort_me, sm, 1);
19582       sm->name = (u8 *)(p->key);
19583       sm->value = (u8 *) (p->value[0]);
19584     }));
19585     /* *INDENT-ON* */
19586
19587   vec_sort_with_function (sort_me, macro_sort_cmp);
19588
19589   if (vec_len (sort_me))
19590     print (vam->ofp, "%-15s%s", "Name", "Value");
19591   else
19592     print (vam->ofp, "The macro table is empty...");
19593
19594   for (i = 0; i < vec_len (sort_me); i++)
19595     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
19596   return 0;
19597 }
19598
19599 static int
19600 dump_node_table (vat_main_t * vam)
19601 {
19602   int i, j;
19603   vlib_node_t *node, *next_node;
19604
19605   if (vec_len (vam->graph_nodes) == 0)
19606     {
19607       print (vam->ofp, "Node table empty, issue get_node_graph...");
19608       return 0;
19609     }
19610
19611   for (i = 0; i < vec_len (vam->graph_nodes); i++)
19612     {
19613       node = vam->graph_nodes[i];
19614       print (vam->ofp, "[%d] %s", i, node->name);
19615       for (j = 0; j < vec_len (node->next_nodes); j++)
19616         {
19617           if (node->next_nodes[j] != ~0)
19618             {
19619               next_node = vam->graph_nodes[node->next_nodes[j]];
19620               print (vam->ofp, "  [%d] %s", j, next_node->name);
19621             }
19622         }
19623     }
19624   return 0;
19625 }
19626
19627 static int
19628 value_sort_cmp (void *a1, void *a2)
19629 {
19630   name_sort_t *n1 = a1;
19631   name_sort_t *n2 = a2;
19632
19633   if (n1->value < n2->value)
19634     return -1;
19635   if (n1->value > n2->value)
19636     return 1;
19637   return 0;
19638 }
19639
19640
19641 static int
19642 dump_msg_api_table (vat_main_t * vam)
19643 {
19644   api_main_t *am = &api_main;
19645   name_sort_t *nses = 0, *ns;
19646   hash_pair_t *hp;
19647   int i;
19648
19649   /* *INDENT-OFF* */
19650   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
19651   ({
19652     vec_add2 (nses, ns, 1);
19653     ns->name = (u8 *)(hp->key);
19654     ns->value = (u32) hp->value[0];
19655   }));
19656   /* *INDENT-ON* */
19657
19658   vec_sort_with_function (nses, value_sort_cmp);
19659
19660   for (i = 0; i < vec_len (nses); i++)
19661     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
19662   vec_free (nses);
19663   return 0;
19664 }
19665
19666 static int
19667 get_msg_id (vat_main_t * vam)
19668 {
19669   u8 *name_and_crc;
19670   u32 message_index;
19671
19672   if (unformat (vam->input, "%s", &name_and_crc))
19673     {
19674       message_index = vl_api_get_msg_index (name_and_crc);
19675       if (message_index == ~0)
19676         {
19677           print (vam->ofp, " '%s' not found", name_and_crc);
19678           return 0;
19679         }
19680       print (vam->ofp, " '%s' has message index %d",
19681              name_and_crc, message_index);
19682       return 0;
19683     }
19684   errmsg ("name_and_crc required...");
19685   return 0;
19686 }
19687
19688 static int
19689 search_node_table (vat_main_t * vam)
19690 {
19691   unformat_input_t *line_input = vam->input;
19692   u8 *node_to_find;
19693   int j;
19694   vlib_node_t *node, *next_node;
19695   uword *p;
19696
19697   if (vam->graph_node_index_by_name == 0)
19698     {
19699       print (vam->ofp, "Node table empty, issue get_node_graph...");
19700       return 0;
19701     }
19702
19703   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
19704     {
19705       if (unformat (line_input, "%s", &node_to_find))
19706         {
19707           vec_add1 (node_to_find, 0);
19708           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
19709           if (p == 0)
19710             {
19711               print (vam->ofp, "%s not found...", node_to_find);
19712               goto out;
19713             }
19714           node = vam->graph_nodes[p[0]];
19715           print (vam->ofp, "[%d] %s", p[0], node->name);
19716           for (j = 0; j < vec_len (node->next_nodes); j++)
19717             {
19718               if (node->next_nodes[j] != ~0)
19719                 {
19720                   next_node = vam->graph_nodes[node->next_nodes[j]];
19721                   print (vam->ofp, "  [%d] %s", j, next_node->name);
19722                 }
19723             }
19724         }
19725
19726       else
19727         {
19728           clib_warning ("parse error '%U'", format_unformat_error,
19729                         line_input);
19730           return -99;
19731         }
19732
19733     out:
19734       vec_free (node_to_find);
19735
19736     }
19737
19738   return 0;
19739 }
19740
19741
19742 static int
19743 script (vat_main_t * vam)
19744 {
19745 #if (VPP_API_TEST_BUILTIN==0)
19746   u8 *s = 0;
19747   char *save_current_file;
19748   unformat_input_t save_input;
19749   jmp_buf save_jump_buf;
19750   u32 save_line_number;
19751
19752   FILE *new_fp, *save_ifp;
19753
19754   if (unformat (vam->input, "%s", &s))
19755     {
19756       new_fp = fopen ((char *) s, "r");
19757       if (new_fp == 0)
19758         {
19759           errmsg ("Couldn't open script file %s", s);
19760           vec_free (s);
19761           return -99;
19762         }
19763     }
19764   else
19765     {
19766       errmsg ("Missing script name");
19767       return -99;
19768     }
19769
19770   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
19771   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
19772   save_ifp = vam->ifp;
19773   save_line_number = vam->input_line_number;
19774   save_current_file = (char *) vam->current_file;
19775
19776   vam->input_line_number = 0;
19777   vam->ifp = new_fp;
19778   vam->current_file = s;
19779   do_one_file (vam);
19780
19781   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
19782   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
19783   vam->ifp = save_ifp;
19784   vam->input_line_number = save_line_number;
19785   vam->current_file = (u8 *) save_current_file;
19786   vec_free (s);
19787
19788   return 0;
19789 #else
19790   clib_warning ("use the exec command...");
19791   return -99;
19792 #endif
19793 }
19794
19795 static int
19796 echo (vat_main_t * vam)
19797 {
19798   print (vam->ofp, "%v", vam->input->buffer);
19799   return 0;
19800 }
19801
19802 /* List of API message constructors, CLI names map to api_xxx */
19803 #define foreach_vpe_api_msg                                             \
19804 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
19805 _(sw_interface_dump,"")                                                 \
19806 _(sw_interface_set_flags,                                               \
19807   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
19808 _(sw_interface_add_del_address,                                         \
19809   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
19810 _(sw_interface_set_table,                                               \
19811   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
19812 _(sw_interface_set_mpls_enable,                                         \
19813   "<intfc> | sw_if_index [disable | dis]")                              \
19814 _(sw_interface_set_vpath,                                               \
19815   "<intfc> | sw_if_index <id> enable | disable")                        \
19816 _(sw_interface_set_vxlan_bypass,                                        \
19817   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
19818 _(sw_interface_set_l2_xconnect,                                         \
19819   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
19820   "enable | disable")                                                   \
19821 _(sw_interface_set_l2_bridge,                                           \
19822   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
19823   "[shg <split-horizon-group>] [bvi]\n"                                 \
19824   "enable | disable")                                                   \
19825 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
19826 _(bridge_domain_add_del,                                                \
19827   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [mac-age 0-255] [del]\n") \
19828 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
19829 _(l2fib_add_del,                                                        \
19830   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
19831 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
19832 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
19833 _(l2_flags,                                                             \
19834   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
19835 _(bridge_flags,                                                         \
19836   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
19837 _(tap_connect,                                                          \
19838   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
19839 _(tap_modify,                                                           \
19840   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
19841 _(tap_delete,                                                           \
19842   "<vpp-if-name> | sw_if_index <id>")                                   \
19843 _(sw_interface_tap_dump, "")                                            \
19844 _(ip_add_del_route,                                                     \
19845   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
19846   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
19847   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
19848   "[multipath] [count <n>]")                                            \
19849 _(ip_mroute_add_del,                                                    \
19850   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
19851   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
19852 _(mpls_route_add_del,                                                   \
19853   "<label> <eos> via <addr> [table-id <n>]\n"                           \
19854   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
19855   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
19856   "[multipath] [count <n>]")                                            \
19857 _(mpls_ip_bind_unbind,                                                  \
19858   "<label> <addr/len>")                                                 \
19859 _(mpls_tunnel_add_del,                                                  \
19860   " via <addr> [table-id <n>]\n"                                        \
19861   "sw_if_index <id>] [l2]  [del]")                                      \
19862 _(proxy_arp_add_del,                                                    \
19863   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
19864 _(proxy_arp_intfc_enable_disable,                                       \
19865   "<intfc> | sw_if_index <id> enable | disable")                        \
19866 _(sw_interface_set_unnumbered,                                          \
19867   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
19868 _(ip_neighbor_add_del,                                                  \
19869   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
19870   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
19871 _(reset_vrf, "vrf <id> [ipv6]")                                         \
19872 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
19873 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
19874   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
19875   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
19876   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
19877 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
19878 _(reset_fib, "vrf <n> [ipv6]")                                          \
19879 _(dhcp_proxy_config,                                                    \
19880   "svr <v46-address> src <v46-address>\n"                               \
19881    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
19882 _(dhcp_proxy_set_vss,                                                   \
19883   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
19884 _(dhcp_proxy_dump, "ip6")                                               \
19885 _(dhcp_client_config,                                                   \
19886   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
19887 _(set_ip_flow_hash,                                                     \
19888   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
19889 _(sw_interface_ip6_enable_disable,                                      \
19890   "<intfc> | sw_if_index <id> enable | disable")                        \
19891 _(sw_interface_ip6_set_link_local_address,                              \
19892   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
19893 _(ip6nd_proxy_add_del,                                                  \
19894   "<intfc> | sw_if_index <id> <ip6-address>")                           \
19895 _(ip6nd_proxy_dump, "")                                                 \
19896 _(sw_interface_ip6nd_ra_prefix,                                         \
19897   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
19898   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
19899   "[nolink] [isno]")                                                    \
19900 _(sw_interface_ip6nd_ra_config,                                         \
19901   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
19902   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
19903   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
19904 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
19905 _(l2_patch_add_del,                                                     \
19906   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
19907   "enable | disable")                                                   \
19908 _(sr_localsid_add_del,                                                  \
19909   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
19910   "fib-table <num> (end.psp) sw_if_index <num>")                        \
19911 _(classify_add_del_table,                                               \
19912   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
19913   " [del] [del-chain] mask <mask-value>\n"                              \
19914   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
19915   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
19916 _(classify_add_del_session,                                             \
19917   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
19918   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
19919   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
19920   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
19921 _(classify_set_interface_ip_table,                                      \
19922   "<intfc> | sw_if_index <nn> table <nn>")                              \
19923 _(classify_set_interface_l2_tables,                                     \
19924   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
19925   "  [other-table <nn>]")                                               \
19926 _(get_node_index, "node <node-name")                                    \
19927 _(add_node_next, "node <node-name> next <next-node-name>")              \
19928 _(l2tpv3_create_tunnel,                                                 \
19929   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
19930   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
19931   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
19932 _(l2tpv3_set_tunnel_cookies,                                            \
19933   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
19934   "[new_remote_cookie <nn>]\n")                                         \
19935 _(l2tpv3_interface_enable_disable,                                      \
19936   "<intfc> | sw_if_index <nn> enable | disable")                        \
19937 _(l2tpv3_set_lookup_key,                                                \
19938   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
19939 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
19940 _(vxlan_add_del_tunnel,                                                 \
19941   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
19942   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
19943   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
19944 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
19945 _(gre_add_del_tunnel,                                                   \
19946   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
19947 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
19948 _(l2_fib_clear_table, "")                                               \
19949 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
19950 _(l2_interface_vlan_tag_rewrite,                                        \
19951   "<intfc> | sw_if_index <nn> \n"                                       \
19952   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
19953   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
19954 _(create_vhost_user_if,                                                 \
19955         "socket <filename> [server] [renumber <dev_instance>] "         \
19956         "[mac <mac_address>]")                                          \
19957 _(modify_vhost_user_if,                                                 \
19958         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
19959         "[server] [renumber <dev_instance>]")                           \
19960 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
19961 _(sw_interface_vhost_user_dump, "")                                     \
19962 _(show_version, "")                                                     \
19963 _(vxlan_gpe_add_del_tunnel,                                             \
19964   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
19965   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
19966   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
19967   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
19968 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
19969 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
19970 _(interface_name_renumber,                                              \
19971   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
19972 _(input_acl_set_interface,                                              \
19973   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
19974   "  [l2-table <nn>] [del]")                                            \
19975 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
19976 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
19977 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
19978 _(ip_dump, "ipv4 | ipv6")                                               \
19979 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
19980 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
19981   "  spid_id <n> ")                                                     \
19982 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
19983   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
19984   "  integ_alg <alg> integ_key <hex>")                                  \
19985 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
19986   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
19987   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
19988   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
19989 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
19990 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
19991   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
19992   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
19993   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
19994 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
19995 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
19996   "(auth_data 0x<data> | auth_data <data>)")                            \
19997 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
19998   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
19999 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
20000   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
20001   "(local|remote)")                                                     \
20002 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
20003 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
20004 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
20005 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
20006 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
20007 _(ikev2_initiate_sa_init, "<profile_name>")                             \
20008 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
20009 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
20010 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
20011 _(delete_loopback,"sw_if_index <nn>")                                   \
20012 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
20013 _(map_add_domain,                                                       \
20014   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
20015   "ip6-src <ip6addr> "                                                  \
20016   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
20017 _(map_del_domain, "index <n>")                                          \
20018 _(map_add_del_rule,                                                     \
20019   "index <n> psid <n> dst <ip6addr> [del]")                             \
20020 _(map_domain_dump, "")                                                  \
20021 _(map_rule_dump, "index <map-domain>")                                  \
20022 _(want_interface_events,  "enable|disable")                             \
20023 _(want_stats,"enable|disable")                                          \
20024 _(get_first_msg_id, "client <name>")                                    \
20025 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
20026 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
20027   "fib-id <nn> [ip4][ip6][default]")                                    \
20028 _(get_node_graph, " ")                                                  \
20029 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
20030 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
20031 _(ioam_disable, "")                                                     \
20032 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
20033                             " sw_if_index <sw_if_index> p <priority> "  \
20034                             "w <weight>] [del]")                        \
20035 _(one_add_del_locator, "locator-set <locator_name> "                    \
20036                         "iface <intf> | sw_if_index <sw_if_index> "     \
20037                         "p <priority> w <weight> [del]")                \
20038 _(one_add_del_local_eid,"vni <vni> eid "                                \
20039                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20040                          "locator-set <locator_name> [del]"             \
20041                          "[key-id sha1|sha256 secret-key <secret-key>]")\
20042 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
20043 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
20044 _(one_enable_disable, "enable|disable")                                 \
20045 _(one_map_register_enable_disable, "enable|disable")                    \
20046 _(one_rloc_probe_enable_disable, "enable|disable")                      \
20047 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
20048                                "[seid <seid>] "                         \
20049                                "rloc <locator> p <prio> "               \
20050                                "w <weight> [rloc <loc> ... ] "          \
20051                                "action <action> [del-all]")             \
20052 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
20053                           "<local-eid>")                                \
20054 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
20055 _(one_use_petr, "ip-address> | disable")                                \
20056 _(one_map_request_mode, "src-dst|dst-only")                             \
20057 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
20058 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
20059 _(one_locator_set_dump, "[local | remote]")                             \
20060 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
20061 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
20062                        "[local] | [remote]")                            \
20063 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
20064 _(one_l2_arp_bd_get, "")                                                \
20065 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
20066 _(one_stats_enable_disable, "enable|disalbe")                           \
20067 _(show_one_stats_enable_disable, "")                                    \
20068 _(one_eid_table_vni_dump, "")                                           \
20069 _(one_eid_table_map_dump, "l2|l3")                                      \
20070 _(one_map_resolver_dump, "")                                            \
20071 _(one_map_server_dump, "")                                              \
20072 _(one_adjacencies_get, "vni <vni>")                                     \
20073 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
20074 _(show_one_rloc_probe_state, "")                                        \
20075 _(show_one_map_register_state, "")                                      \
20076 _(show_one_status, "")                                                  \
20077 _(one_stats_dump, "")                                                   \
20078 _(one_stats_flush, "")                                                  \
20079 _(one_get_map_request_itr_rlocs, "")                                    \
20080 _(one_map_register_set_ttl, "<ttl>")                                    \
20081 _(show_one_nsh_mapping, "")                                             \
20082 _(show_one_pitr, "")                                                    \
20083 _(show_one_use_petr, "")                                                \
20084 _(show_one_map_request_mode, "")                                        \
20085 _(show_one_map_register_ttl, "")                                        \
20086 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
20087                             " sw_if_index <sw_if_index> p <priority> "  \
20088                             "w <weight>] [del]")                        \
20089 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
20090                         "iface <intf> | sw_if_index <sw_if_index> "     \
20091                         "p <priority> w <weight> [del]")                \
20092 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
20093                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20094                          "locator-set <locator_name> [del]"             \
20095                          "[key-id sha1|sha256 secret-key <secret-key>]") \
20096 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
20097 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
20098 _(lisp_enable_disable, "enable|disable")                                \
20099 _(lisp_map_register_enable_disable, "enable|disable")                   \
20100 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
20101 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
20102                                "[seid <seid>] "                         \
20103                                "rloc <locator> p <prio> "               \
20104                                "w <weight> [rloc <loc> ... ] "          \
20105                                "action <action> [del-all]")             \
20106 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
20107                           "<local-eid>")                                \
20108 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
20109 _(lisp_use_petr, "<ip-address> | disable")                              \
20110 _(lisp_map_request_mode, "src-dst|dst-only")                            \
20111 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
20112 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
20113 _(lisp_locator_set_dump, "[local | remote]")                            \
20114 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
20115 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
20116                        "[local] | [remote]")                            \
20117 _(lisp_eid_table_vni_dump, "")                                          \
20118 _(lisp_eid_table_map_dump, "l2|l3")                                     \
20119 _(lisp_map_resolver_dump, "")                                           \
20120 _(lisp_map_server_dump, "")                                             \
20121 _(lisp_adjacencies_get, "vni <vni>")                                    \
20122 _(gpe_fwd_entry_vnis_get, "")                                           \
20123 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
20124 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
20125                                 "[table <table-id>]")                   \
20126 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
20127 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
20128 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
20129 _(gpe_get_encap_mode, "")                                               \
20130 _(lisp_gpe_add_del_iface, "up|down")                                    \
20131 _(lisp_gpe_enable_disable, "enable|disable")                            \
20132 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
20133   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
20134 _(show_lisp_rloc_probe_state, "")                                       \
20135 _(show_lisp_map_register_state, "")                                     \
20136 _(show_lisp_status, "")                                                 \
20137 _(lisp_get_map_request_itr_rlocs, "")                                   \
20138 _(show_lisp_pitr, "")                                                   \
20139 _(show_lisp_use_petr, "")                                               \
20140 _(show_lisp_map_request_mode, "")                                       \
20141 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
20142 _(af_packet_delete, "name <host interface name>")                       \
20143 _(policer_add_del, "name <policer name> <params> [del]")                \
20144 _(policer_dump, "[name <policer name>]")                                \
20145 _(policer_classify_set_interface,                                       \
20146   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20147   "  [l2-table <nn>] [del]")                                            \
20148 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
20149 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
20150     "[master|slave]")                                                   \
20151 _(netmap_delete, "name <interface name>")                               \
20152 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
20153 _(mpls_fib_dump, "")                                                    \
20154 _(classify_table_ids, "")                                               \
20155 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
20156 _(classify_table_info, "table_id <nn>")                                 \
20157 _(classify_session_dump, "table_id <nn>")                               \
20158 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
20159     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
20160     "[template_interval <nn>] [udp_checksum]")                          \
20161 _(ipfix_exporter_dump, "")                                              \
20162 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
20163 _(ipfix_classify_stream_dump, "")                                       \
20164 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
20165 _(ipfix_classify_table_dump, "")                                        \
20166 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
20167 _(sw_interface_span_dump, "[l2]")                                           \
20168 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
20169 _(pg_create_interface, "if_id <nn>")                                    \
20170 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
20171 _(pg_enable_disable, "[stream <id>] disable")                           \
20172 _(ip_source_and_port_range_check_add_del,                               \
20173   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
20174 _(ip_source_and_port_range_check_interface_add_del,                     \
20175   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
20176   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
20177 _(ipsec_gre_add_del_tunnel,                                             \
20178   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
20179 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
20180 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
20181 _(l2_interface_pbb_tag_rewrite,                                         \
20182   "<intfc> | sw_if_index <nn> \n"                                       \
20183   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
20184   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
20185 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
20186 _(flow_classify_set_interface,                                          \
20187   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
20188 _(flow_classify_dump, "type [ip4|ip6]")                                 \
20189 _(ip_fib_dump, "")                                                      \
20190 _(ip_mfib_dump, "")                                                     \
20191 _(ip6_fib_dump, "")                                                     \
20192 _(ip6_mfib_dump, "")                                                    \
20193 _(feature_enable_disable, "arc_name <arc_name> "                        \
20194   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
20195 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
20196 "[disable]")                                                            \
20197 _(l2_xconnect_dump, "")                                                 \
20198 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
20199 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
20200 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
20201 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
20202 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
20203 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
20204 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>] [disable]")
20205
20206 /* List of command functions, CLI names map directly to functions */
20207 #define foreach_cli_function                                    \
20208 _(comment, "usage: comment <ignore-rest-of-line>")              \
20209 _(dump_interface_table, "usage: dump_interface_table")          \
20210 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
20211 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
20212 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
20213 _(dump_stats_table, "usage: dump_stats_table")                  \
20214 _(dump_macro_table, "usage: dump_macro_table ")                 \
20215 _(dump_node_table, "usage: dump_node_table")                    \
20216 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
20217 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
20218 _(echo, "usage: echo <message>")                                \
20219 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
20220 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
20221 _(help, "usage: help")                                          \
20222 _(q, "usage: quit")                                             \
20223 _(quit, "usage: quit")                                          \
20224 _(search_node_table, "usage: search_node_table <name>...")      \
20225 _(set, "usage: set <variable-name> <value>")                    \
20226 _(script, "usage: script <file-name>")                          \
20227 _(unset, "usage: unset <variable-name>")
20228 #define _(N,n)                                  \
20229     static void vl_api_##n##_t_handler_uni      \
20230     (vl_api_##n##_t * mp)                       \
20231     {                                           \
20232         vat_main_t * vam = &vat_main;           \
20233         if (vam->json_output) {                 \
20234             vl_api_##n##_t_handler_json(mp);    \
20235         } else {                                \
20236             vl_api_##n##_t_handler(mp);         \
20237         }                                       \
20238     }
20239 foreach_vpe_api_reply_msg;
20240 #if VPP_API_TEST_BUILTIN == 0
20241 foreach_standalone_reply_msg;
20242 #endif
20243 #undef _
20244
20245 void
20246 vat_api_hookup (vat_main_t * vam)
20247 {
20248 #define _(N,n)                                                  \
20249     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
20250                            vl_api_##n##_t_handler_uni,          \
20251                            vl_noop_handler,                     \
20252                            vl_api_##n##_t_endian,               \
20253                            vl_api_##n##_t_print,                \
20254                            sizeof(vl_api_##n##_t), 1);
20255   foreach_vpe_api_reply_msg;
20256 #if VPP_API_TEST_BUILTIN == 0
20257   foreach_standalone_reply_msg;
20258 #endif
20259 #undef _
20260
20261 #if (VPP_API_TEST_BUILTIN==0)
20262   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
20263
20264   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
20265
20266   vam->function_by_name = hash_create_string (0, sizeof (uword));
20267
20268   vam->help_by_name = hash_create_string (0, sizeof (uword));
20269 #endif
20270
20271   /* API messages we can send */
20272 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
20273   foreach_vpe_api_msg;
20274 #undef _
20275
20276   /* Help strings */
20277 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
20278   foreach_vpe_api_msg;
20279 #undef _
20280
20281   /* CLI functions */
20282 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
20283   foreach_cli_function;
20284 #undef _
20285
20286   /* Help strings */
20287 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
20288   foreach_cli_function;
20289 #undef _
20290 }
20291
20292 #if VPP_API_TEST_BUILTIN
20293 static clib_error_t *
20294 vat_api_hookup_shim (vlib_main_t * vm)
20295 {
20296   vat_api_hookup (&vat_main);
20297   return 0;
20298 }
20299
20300 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
20301 #endif
20302
20303 /*
20304  * fd.io coding-style-patch-verification: ON
20305  *
20306  * Local Variables:
20307  * eval: (c-set-style "gnu")
20308  * End:
20309  */