LISP: support for neighbor discovery
[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_event_t_handler
976   (vl_api_sw_interface_event_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_event_t_handler_json
988   (vl_api_sw_interface_event_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 static void
1287 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1288 {
1289   u32 n_macs = ntohl (mp->n_macs);
1290   errmsg ("L2MAC event recived with pid %d cl-idx %d for %d macs: \n",
1291           ntohl (mp->pid), mp->client_index, n_macs);
1292   int i;
1293   for (i = 0; i < n_macs; i++)
1294     {
1295       vl_api_mac_entry_t *mac = &mp->mac[i];
1296       errmsg (" [%d] sw_if_index %d  mac_addr %U  is_del %d \n",
1297               i + 1, ntohl (mac->sw_if_index),
1298               format_ethernet_address, mac->mac_addr, mac->is_del);
1299       if (i == 1000)
1300         break;
1301     }
1302 }
1303
1304 static void
1305 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1306 {
1307   /* JSON output not supported */
1308 }
1309
1310 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1311 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1312
1313 /*
1314  * Special-case: build the bridge domain table, maintain
1315  * the next bd id vbl.
1316  */
1317 static void vl_api_bridge_domain_details_t_handler
1318   (vl_api_bridge_domain_details_t * mp)
1319 {
1320   vat_main_t *vam = &vat_main;
1321   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1322   int i;
1323
1324   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1325          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1326
1327   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1328          ntohl (mp->bd_id), mp->learn, mp->forward,
1329          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1330
1331   if (n_sw_ifs)
1332     {
1333       vl_api_bridge_domain_sw_if_t *sw_ifs;
1334       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1335              "Interface Name");
1336
1337       sw_ifs = mp->sw_if_details;
1338       for (i = 0; i < n_sw_ifs; i++)
1339         {
1340           u8 *sw_if_name = 0;
1341           u32 sw_if_index;
1342           hash_pair_t *p;
1343
1344           sw_if_index = ntohl (sw_ifs->sw_if_index);
1345
1346           /* *INDENT-OFF* */
1347           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1348                              ({
1349                                if ((u32) p->value[0] == sw_if_index)
1350                                  {
1351                                    sw_if_name = (u8 *)(p->key);
1352                                    break;
1353                                  }
1354                              }));
1355           /* *INDENT-ON* */
1356           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1357                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1358                  "sw_if_index not found!");
1359
1360           sw_ifs++;
1361         }
1362     }
1363 }
1364
1365 static void vl_api_bridge_domain_details_t_handler_json
1366   (vl_api_bridge_domain_details_t * mp)
1367 {
1368   vat_main_t *vam = &vat_main;
1369   vat_json_node_t *node, *array = NULL;
1370   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1371
1372   if (VAT_JSON_ARRAY != vam->json_tree.type)
1373     {
1374       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1375       vat_json_init_array (&vam->json_tree);
1376     }
1377   node = vat_json_array_add (&vam->json_tree);
1378
1379   vat_json_init_object (node);
1380   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1381   vat_json_object_add_uint (node, "flood", mp->flood);
1382   vat_json_object_add_uint (node, "forward", mp->forward);
1383   vat_json_object_add_uint (node, "learn", mp->learn);
1384   vat_json_object_add_uint (node, "bvi_sw_if_index",
1385                             ntohl (mp->bvi_sw_if_index));
1386   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1387   array = vat_json_object_add (node, "sw_if");
1388   vat_json_init_array (array);
1389
1390
1391
1392   if (n_sw_ifs)
1393     {
1394       vl_api_bridge_domain_sw_if_t *sw_ifs;
1395       int i;
1396
1397       sw_ifs = mp->sw_if_details;
1398       for (i = 0; i < n_sw_ifs; i++)
1399         {
1400           node = vat_json_array_add (array);
1401           vat_json_init_object (node);
1402           vat_json_object_add_uint (node, "sw_if_index",
1403                                     ntohl (sw_ifs->sw_if_index));
1404           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1405           sw_ifs++;
1406         }
1407     }
1408 }
1409
1410 static void vl_api_control_ping_reply_t_handler
1411   (vl_api_control_ping_reply_t * mp)
1412 {
1413   vat_main_t *vam = &vat_main;
1414   i32 retval = ntohl (mp->retval);
1415   if (vam->async_mode)
1416     {
1417       vam->async_errors += (retval < 0);
1418     }
1419   else
1420     {
1421       vam->retval = retval;
1422       vam->result_ready = 1;
1423     }
1424 }
1425
1426 static void vl_api_control_ping_reply_t_handler_json
1427   (vl_api_control_ping_reply_t * mp)
1428 {
1429   vat_main_t *vam = &vat_main;
1430   i32 retval = ntohl (mp->retval);
1431
1432   if (VAT_JSON_NONE != vam->json_tree.type)
1433     {
1434       vat_json_print (vam->ofp, &vam->json_tree);
1435       vat_json_free (&vam->json_tree);
1436       vam->json_tree.type = VAT_JSON_NONE;
1437     }
1438   else
1439     {
1440       /* just print [] */
1441       vat_json_init_array (&vam->json_tree);
1442       vat_json_print (vam->ofp, &vam->json_tree);
1443       vam->json_tree.type = VAT_JSON_NONE;
1444     }
1445
1446   vam->retval = retval;
1447   vam->result_ready = 1;
1448 }
1449
1450 static void
1451   vl_api_bridge_domain_set_mac_age_reply_t_handler
1452   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1453 {
1454   vat_main_t *vam = &vat_main;
1455   i32 retval = ntohl (mp->retval);
1456   if (vam->async_mode)
1457     {
1458       vam->async_errors += (retval < 0);
1459     }
1460   else
1461     {
1462       vam->retval = retval;
1463       vam->result_ready = 1;
1464     }
1465 }
1466
1467 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1468   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1469 {
1470   vat_main_t *vam = &vat_main;
1471   vat_json_node_t node;
1472
1473   vat_json_init_object (&node);
1474   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1475
1476   vat_json_print (vam->ofp, &node);
1477   vat_json_free (&node);
1478
1479   vam->retval = ntohl (mp->retval);
1480   vam->result_ready = 1;
1481 }
1482
1483 static void
1484 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1485 {
1486   vat_main_t *vam = &vat_main;
1487   i32 retval = ntohl (mp->retval);
1488   if (vam->async_mode)
1489     {
1490       vam->async_errors += (retval < 0);
1491     }
1492   else
1493     {
1494       vam->retval = retval;
1495       vam->result_ready = 1;
1496     }
1497 }
1498
1499 static void vl_api_l2_flags_reply_t_handler_json
1500   (vl_api_l2_flags_reply_t * mp)
1501 {
1502   vat_main_t *vam = &vat_main;
1503   vat_json_node_t node;
1504
1505   vat_json_init_object (&node);
1506   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1507   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1508                             ntohl (mp->resulting_feature_bitmap));
1509
1510   vat_json_print (vam->ofp, &node);
1511   vat_json_free (&node);
1512
1513   vam->retval = ntohl (mp->retval);
1514   vam->result_ready = 1;
1515 }
1516
1517 static void vl_api_bridge_flags_reply_t_handler
1518   (vl_api_bridge_flags_reply_t * mp)
1519 {
1520   vat_main_t *vam = &vat_main;
1521   i32 retval = ntohl (mp->retval);
1522   if (vam->async_mode)
1523     {
1524       vam->async_errors += (retval < 0);
1525     }
1526   else
1527     {
1528       vam->retval = retval;
1529       vam->result_ready = 1;
1530     }
1531 }
1532
1533 static void vl_api_bridge_flags_reply_t_handler_json
1534   (vl_api_bridge_flags_reply_t * mp)
1535 {
1536   vat_main_t *vam = &vat_main;
1537   vat_json_node_t node;
1538
1539   vat_json_init_object (&node);
1540   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1541   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1542                             ntohl (mp->resulting_feature_bitmap));
1543
1544   vat_json_print (vam->ofp, &node);
1545   vat_json_free (&node);
1546
1547   vam->retval = ntohl (mp->retval);
1548   vam->result_ready = 1;
1549 }
1550
1551 static void vl_api_tap_connect_reply_t_handler
1552   (vl_api_tap_connect_reply_t * mp)
1553 {
1554   vat_main_t *vam = &vat_main;
1555   i32 retval = ntohl (mp->retval);
1556   if (vam->async_mode)
1557     {
1558       vam->async_errors += (retval < 0);
1559     }
1560   else
1561     {
1562       vam->retval = retval;
1563       vam->sw_if_index = ntohl (mp->sw_if_index);
1564       vam->result_ready = 1;
1565     }
1566
1567 }
1568
1569 static void vl_api_tap_connect_reply_t_handler_json
1570   (vl_api_tap_connect_reply_t * mp)
1571 {
1572   vat_main_t *vam = &vat_main;
1573   vat_json_node_t node;
1574
1575   vat_json_init_object (&node);
1576   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1577   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1578
1579   vat_json_print (vam->ofp, &node);
1580   vat_json_free (&node);
1581
1582   vam->retval = ntohl (mp->retval);
1583   vam->result_ready = 1;
1584
1585 }
1586
1587 static void
1588 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1589 {
1590   vat_main_t *vam = &vat_main;
1591   i32 retval = ntohl (mp->retval);
1592   if (vam->async_mode)
1593     {
1594       vam->async_errors += (retval < 0);
1595     }
1596   else
1597     {
1598       vam->retval = retval;
1599       vam->sw_if_index = ntohl (mp->sw_if_index);
1600       vam->result_ready = 1;
1601     }
1602 }
1603
1604 static void vl_api_tap_modify_reply_t_handler_json
1605   (vl_api_tap_modify_reply_t * mp)
1606 {
1607   vat_main_t *vam = &vat_main;
1608   vat_json_node_t node;
1609
1610   vat_json_init_object (&node);
1611   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1612   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1613
1614   vat_json_print (vam->ofp, &node);
1615   vat_json_free (&node);
1616
1617   vam->retval = ntohl (mp->retval);
1618   vam->result_ready = 1;
1619 }
1620
1621 static void
1622 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1623 {
1624   vat_main_t *vam = &vat_main;
1625   i32 retval = ntohl (mp->retval);
1626   if (vam->async_mode)
1627     {
1628       vam->async_errors += (retval < 0);
1629     }
1630   else
1631     {
1632       vam->retval = retval;
1633       vam->result_ready = 1;
1634     }
1635 }
1636
1637 static void vl_api_tap_delete_reply_t_handler_json
1638   (vl_api_tap_delete_reply_t * mp)
1639 {
1640   vat_main_t *vam = &vat_main;
1641   vat_json_node_t node;
1642
1643   vat_json_init_object (&node);
1644   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1645
1646   vat_json_print (vam->ofp, &node);
1647   vat_json_free (&node);
1648
1649   vam->retval = ntohl (mp->retval);
1650   vam->result_ready = 1;
1651 }
1652
1653 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1654   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1655 {
1656   vat_main_t *vam = &vat_main;
1657   i32 retval = ntohl (mp->retval);
1658   if (vam->async_mode)
1659     {
1660       vam->async_errors += (retval < 0);
1661     }
1662   else
1663     {
1664       vam->retval = retval;
1665       vam->result_ready = 1;
1666     }
1667 }
1668
1669 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1670   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1671 {
1672   vat_main_t *vam = &vat_main;
1673   vat_json_node_t node;
1674
1675   vat_json_init_object (&node);
1676   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1677   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1678                             ntohl (mp->sw_if_index));
1679
1680   vat_json_print (vam->ofp, &node);
1681   vat_json_free (&node);
1682
1683   vam->retval = ntohl (mp->retval);
1684   vam->result_ready = 1;
1685 }
1686
1687 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1688   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1689 {
1690   vat_main_t *vam = &vat_main;
1691   i32 retval = ntohl (mp->retval);
1692   if (vam->async_mode)
1693     {
1694       vam->async_errors += (retval < 0);
1695     }
1696   else
1697     {
1698       vam->retval = retval;
1699       vam->sw_if_index = ntohl (mp->sw_if_index);
1700       vam->result_ready = 1;
1701     }
1702 }
1703
1704 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1705   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1706 {
1707   vat_main_t *vam = &vat_main;
1708   vat_json_node_t node;
1709
1710   vat_json_init_object (&node);
1711   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1712   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1713
1714   vat_json_print (vam->ofp, &node);
1715   vat_json_free (&node);
1716
1717   vam->retval = ntohl (mp->retval);
1718   vam->result_ready = 1;
1719 }
1720
1721 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
1722   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1723 {
1724   vat_main_t *vam = &vat_main;
1725   i32 retval = ntohl (mp->retval);
1726   if (vam->async_mode)
1727     {
1728       vam->async_errors += (retval < 0);
1729     }
1730   else
1731     {
1732       vam->retval = retval;
1733       vam->result_ready = 1;
1734     }
1735 }
1736
1737 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
1738   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1739 {
1740   vat_main_t *vam = &vat_main;
1741   vat_json_node_t node;
1742
1743   vat_json_init_object (&node);
1744   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1745   vat_json_object_add_uint (&node, "fwd_entry_index",
1746                             clib_net_to_host_u32 (mp->fwd_entry_index));
1747
1748   vat_json_print (vam->ofp, &node);
1749   vat_json_free (&node);
1750
1751   vam->retval = ntohl (mp->retval);
1752   vam->result_ready = 1;
1753 }
1754
1755 static void vl_api_one_add_del_locator_set_reply_t_handler
1756   (vl_api_one_add_del_locator_set_reply_t * mp)
1757 {
1758   vat_main_t *vam = &vat_main;
1759   i32 retval = ntohl (mp->retval);
1760   if (vam->async_mode)
1761     {
1762       vam->async_errors += (retval < 0);
1763     }
1764   else
1765     {
1766       vam->retval = retval;
1767       vam->result_ready = 1;
1768     }
1769 }
1770
1771 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1772   (vl_api_one_add_del_locator_set_reply_t * mp)
1773 {
1774   vat_main_t *vam = &vat_main;
1775   vat_json_node_t node;
1776
1777   vat_json_init_object (&node);
1778   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1779   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1780
1781   vat_json_print (vam->ofp, &node);
1782   vat_json_free (&node);
1783
1784   vam->retval = ntohl (mp->retval);
1785   vam->result_ready = 1;
1786 }
1787
1788 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1789   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1790 {
1791   vat_main_t *vam = &vat_main;
1792   i32 retval = ntohl (mp->retval);
1793   if (vam->async_mode)
1794     {
1795       vam->async_errors += (retval < 0);
1796     }
1797   else
1798     {
1799       vam->retval = retval;
1800       vam->sw_if_index = ntohl (mp->sw_if_index);
1801       vam->result_ready = 1;
1802     }
1803 }
1804
1805 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1806   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1807 {
1808   vat_main_t *vam = &vat_main;
1809   vat_json_node_t node;
1810
1811   vat_json_init_object (&node);
1812   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1813   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1814
1815   vat_json_print (vam->ofp, &node);
1816   vat_json_free (&node);
1817
1818   vam->retval = ntohl (mp->retval);
1819   vam->result_ready = 1;
1820 }
1821
1822 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
1823   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
1824 {
1825   vat_main_t *vam = &vat_main;
1826   i32 retval = ntohl (mp->retval);
1827   if (vam->async_mode)
1828     {
1829       vam->async_errors += (retval < 0);
1830     }
1831   else
1832     {
1833       vam->retval = retval;
1834       vam->sw_if_index = ntohl (mp->sw_if_index);
1835       vam->result_ready = 1;
1836     }
1837 }
1838
1839 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
1840   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
1841 {
1842   vat_main_t *vam = &vat_main;
1843   vat_json_node_t node;
1844
1845   vat_json_init_object (&node);
1846   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1847   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1848
1849   vat_json_print (vam->ofp, &node);
1850   vat_json_free (&node);
1851
1852   vam->retval = ntohl (mp->retval);
1853   vam->result_ready = 1;
1854 }
1855
1856 static void vl_api_gre_add_del_tunnel_reply_t_handler
1857   (vl_api_gre_add_del_tunnel_reply_t * mp)
1858 {
1859   vat_main_t *vam = &vat_main;
1860   i32 retval = ntohl (mp->retval);
1861   if (vam->async_mode)
1862     {
1863       vam->async_errors += (retval < 0);
1864     }
1865   else
1866     {
1867       vam->retval = retval;
1868       vam->sw_if_index = ntohl (mp->sw_if_index);
1869       vam->result_ready = 1;
1870     }
1871 }
1872
1873 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1874   (vl_api_gre_add_del_tunnel_reply_t * mp)
1875 {
1876   vat_main_t *vam = &vat_main;
1877   vat_json_node_t node;
1878
1879   vat_json_init_object (&node);
1880   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1881   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1882
1883   vat_json_print (vam->ofp, &node);
1884   vat_json_free (&node);
1885
1886   vam->retval = ntohl (mp->retval);
1887   vam->result_ready = 1;
1888 }
1889
1890 static void vl_api_create_vhost_user_if_reply_t_handler
1891   (vl_api_create_vhost_user_if_reply_t * mp)
1892 {
1893   vat_main_t *vam = &vat_main;
1894   i32 retval = ntohl (mp->retval);
1895   if (vam->async_mode)
1896     {
1897       vam->async_errors += (retval < 0);
1898     }
1899   else
1900     {
1901       vam->retval = retval;
1902       vam->sw_if_index = ntohl (mp->sw_if_index);
1903       vam->result_ready = 1;
1904     }
1905 }
1906
1907 static void vl_api_create_vhost_user_if_reply_t_handler_json
1908   (vl_api_create_vhost_user_if_reply_t * mp)
1909 {
1910   vat_main_t *vam = &vat_main;
1911   vat_json_node_t node;
1912
1913   vat_json_init_object (&node);
1914   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1915   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1916
1917   vat_json_print (vam->ofp, &node);
1918   vat_json_free (&node);
1919
1920   vam->retval = ntohl (mp->retval);
1921   vam->result_ready = 1;
1922 }
1923
1924 static void vl_api_ip_address_details_t_handler
1925   (vl_api_ip_address_details_t * mp)
1926 {
1927   vat_main_t *vam = &vat_main;
1928   static ip_address_details_t empty_ip_address_details = { {0} };
1929   ip_address_details_t *address = NULL;
1930   ip_details_t *current_ip_details = NULL;
1931   ip_details_t *details = NULL;
1932
1933   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1934
1935   if (!details || vam->current_sw_if_index >= vec_len (details)
1936       || !details[vam->current_sw_if_index].present)
1937     {
1938       errmsg ("ip address details arrived but not stored");
1939       errmsg ("ip_dump should be called first");
1940       return;
1941     }
1942
1943   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1944
1945 #define addresses (current_ip_details->addr)
1946
1947   vec_validate_init_empty (addresses, vec_len (addresses),
1948                            empty_ip_address_details);
1949
1950   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1951
1952   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1953   address->prefix_length = mp->prefix_length;
1954 #undef addresses
1955 }
1956
1957 static void vl_api_ip_address_details_t_handler_json
1958   (vl_api_ip_address_details_t * mp)
1959 {
1960   vat_main_t *vam = &vat_main;
1961   vat_json_node_t *node = NULL;
1962   struct in6_addr ip6;
1963   struct in_addr ip4;
1964
1965   if (VAT_JSON_ARRAY != vam->json_tree.type)
1966     {
1967       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1968       vat_json_init_array (&vam->json_tree);
1969     }
1970   node = vat_json_array_add (&vam->json_tree);
1971
1972   vat_json_init_object (node);
1973   if (vam->is_ipv6)
1974     {
1975       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1976       vat_json_object_add_ip6 (node, "ip", ip6);
1977     }
1978   else
1979     {
1980       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1981       vat_json_object_add_ip4 (node, "ip", ip4);
1982     }
1983   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1984 }
1985
1986 static void
1987 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1988 {
1989   vat_main_t *vam = &vat_main;
1990   static ip_details_t empty_ip_details = { 0 };
1991   ip_details_t *ip = NULL;
1992   u32 sw_if_index = ~0;
1993
1994   sw_if_index = ntohl (mp->sw_if_index);
1995
1996   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1997                            sw_if_index, empty_ip_details);
1998
1999   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2000                          sw_if_index);
2001
2002   ip->present = 1;
2003 }
2004
2005 static void
2006 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2007 {
2008   vat_main_t *vam = &vat_main;
2009
2010   if (VAT_JSON_ARRAY != vam->json_tree.type)
2011     {
2012       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2013       vat_json_init_array (&vam->json_tree);
2014     }
2015   vat_json_array_add_uint (&vam->json_tree,
2016                            clib_net_to_host_u32 (mp->sw_if_index));
2017 }
2018
2019 static void vl_api_map_domain_details_t_handler_json
2020   (vl_api_map_domain_details_t * mp)
2021 {
2022   vat_json_node_t *node = NULL;
2023   vat_main_t *vam = &vat_main;
2024   struct in6_addr ip6;
2025   struct in_addr ip4;
2026
2027   if (VAT_JSON_ARRAY != vam->json_tree.type)
2028     {
2029       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2030       vat_json_init_array (&vam->json_tree);
2031     }
2032
2033   node = vat_json_array_add (&vam->json_tree);
2034   vat_json_init_object (node);
2035
2036   vat_json_object_add_uint (node, "domain_index",
2037                             clib_net_to_host_u32 (mp->domain_index));
2038   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
2039   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
2040   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
2041   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
2042   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
2043   vat_json_object_add_ip6 (node, "ip6_src", ip6);
2044   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
2045   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
2046   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
2047   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
2048   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
2049   vat_json_object_add_int (node, "psid_length", mp->psid_length);
2050   vat_json_object_add_uint (node, "flags", mp->flags);
2051   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
2052   vat_json_object_add_int (node, "is_translation", mp->is_translation);
2053 }
2054
2055 static void vl_api_map_domain_details_t_handler
2056   (vl_api_map_domain_details_t * mp)
2057 {
2058   vat_main_t *vam = &vat_main;
2059
2060   if (mp->is_translation)
2061     {
2062       print (vam->ofp,
2063              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2064              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2065              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2066              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2067              clib_net_to_host_u32 (mp->domain_index));
2068     }
2069   else
2070     {
2071       print (vam->ofp,
2072              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2073              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2074              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2075              format_ip6_address, mp->ip6_src,
2076              clib_net_to_host_u32 (mp->domain_index));
2077     }
2078   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2079          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2080          mp->is_translation ? "map-t" : "");
2081 }
2082
2083 static void vl_api_map_rule_details_t_handler_json
2084   (vl_api_map_rule_details_t * mp)
2085 {
2086   struct in6_addr ip6;
2087   vat_json_node_t *node = NULL;
2088   vat_main_t *vam = &vat_main;
2089
2090   if (VAT_JSON_ARRAY != vam->json_tree.type)
2091     {
2092       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2093       vat_json_init_array (&vam->json_tree);
2094     }
2095
2096   node = vat_json_array_add (&vam->json_tree);
2097   vat_json_init_object (node);
2098
2099   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2100   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2101   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2102 }
2103
2104 static void
2105 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2106 {
2107   vat_main_t *vam = &vat_main;
2108   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2109          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2110 }
2111
2112 static void
2113 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2114 {
2115   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2116           "router_addr %U host_mac %U",
2117           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2118           format_ip4_address, &mp->host_address,
2119           format_ip4_address, &mp->router_address,
2120           format_ethernet_address, mp->host_mac);
2121 }
2122
2123 static void vl_api_dhcp_compl_event_t_handler_json
2124   (vl_api_dhcp_compl_event_t * mp)
2125 {
2126   /* JSON output not supported */
2127 }
2128
2129 static void
2130 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2131                               u32 counter)
2132 {
2133   vat_main_t *vam = &vat_main;
2134   static u64 default_counter = 0;
2135
2136   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2137                            NULL);
2138   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2139                            sw_if_index, default_counter);
2140   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2141 }
2142
2143 static void
2144 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2145                                 interface_counter_t counter)
2146 {
2147   vat_main_t *vam = &vat_main;
2148   static interface_counter_t default_counter = { 0, };
2149
2150   vec_validate_init_empty (vam->combined_interface_counters,
2151                            vnet_counter_type, NULL);
2152   vec_validate_init_empty (vam->combined_interface_counters
2153                            [vnet_counter_type], sw_if_index, default_counter);
2154   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2155 }
2156
2157 static void vl_api_vnet_interface_simple_counters_t_handler
2158   (vl_api_vnet_interface_simple_counters_t * mp)
2159 {
2160   /* not supported */
2161 }
2162
2163 static void vl_api_vnet_interface_combined_counters_t_handler
2164   (vl_api_vnet_interface_combined_counters_t * mp)
2165 {
2166   /* not supported */
2167 }
2168
2169 static void vl_api_vnet_interface_simple_counters_t_handler_json
2170   (vl_api_vnet_interface_simple_counters_t * mp)
2171 {
2172   u64 *v_packets;
2173   u64 packets;
2174   u32 count;
2175   u32 first_sw_if_index;
2176   int i;
2177
2178   count = ntohl (mp->count);
2179   first_sw_if_index = ntohl (mp->first_sw_if_index);
2180
2181   v_packets = (u64 *) & mp->data;
2182   for (i = 0; i < count; i++)
2183     {
2184       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2185       set_simple_interface_counter (mp->vnet_counter_type,
2186                                     first_sw_if_index + i, packets);
2187       v_packets++;
2188     }
2189 }
2190
2191 static void vl_api_vnet_interface_combined_counters_t_handler_json
2192   (vl_api_vnet_interface_combined_counters_t * mp)
2193 {
2194   interface_counter_t counter;
2195   vlib_counter_t *v;
2196   u32 first_sw_if_index;
2197   int i;
2198   u32 count;
2199
2200   count = ntohl (mp->count);
2201   first_sw_if_index = ntohl (mp->first_sw_if_index);
2202
2203   v = (vlib_counter_t *) & mp->data;
2204   for (i = 0; i < count; i++)
2205     {
2206       counter.packets =
2207         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2208       counter.bytes =
2209         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2210       set_combined_interface_counter (mp->vnet_counter_type,
2211                                       first_sw_if_index + i, counter);
2212       v++;
2213     }
2214 }
2215
2216 static u32
2217 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2218 {
2219   vat_main_t *vam = &vat_main;
2220   u32 i;
2221
2222   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2223     {
2224       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2225         {
2226           return i;
2227         }
2228     }
2229   return ~0;
2230 }
2231
2232 static u32
2233 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2234 {
2235   vat_main_t *vam = &vat_main;
2236   u32 i;
2237
2238   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2239     {
2240       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2241         {
2242           return i;
2243         }
2244     }
2245   return ~0;
2246 }
2247
2248 static void vl_api_vnet_ip4_fib_counters_t_handler
2249   (vl_api_vnet_ip4_fib_counters_t * mp)
2250 {
2251   /* not supported */
2252 }
2253
2254 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2255   (vl_api_vnet_ip4_fib_counters_t * mp)
2256 {
2257   vat_main_t *vam = &vat_main;
2258   vl_api_ip4_fib_counter_t *v;
2259   ip4_fib_counter_t *counter;
2260   struct in_addr ip4;
2261   u32 vrf_id;
2262   u32 vrf_index;
2263   u32 count;
2264   int i;
2265
2266   vrf_id = ntohl (mp->vrf_id);
2267   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2268   if (~0 == vrf_index)
2269     {
2270       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2271       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2272       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2273       vec_validate (vam->ip4_fib_counters, vrf_index);
2274       vam->ip4_fib_counters[vrf_index] = NULL;
2275     }
2276
2277   vec_free (vam->ip4_fib_counters[vrf_index]);
2278   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2279   count = ntohl (mp->count);
2280   for (i = 0; i < count; i++)
2281     {
2282       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2283       counter = &vam->ip4_fib_counters[vrf_index][i];
2284       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2285       counter->address = ip4;
2286       counter->address_length = v->address_length;
2287       counter->packets = clib_net_to_host_u64 (v->packets);
2288       counter->bytes = clib_net_to_host_u64 (v->bytes);
2289       v++;
2290     }
2291 }
2292
2293 static void vl_api_vnet_ip4_nbr_counters_t_handler
2294   (vl_api_vnet_ip4_nbr_counters_t * mp)
2295 {
2296   /* not supported */
2297 }
2298
2299 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2300   (vl_api_vnet_ip4_nbr_counters_t * mp)
2301 {
2302   vat_main_t *vam = &vat_main;
2303   vl_api_ip4_nbr_counter_t *v;
2304   ip4_nbr_counter_t *counter;
2305   u32 sw_if_index;
2306   u32 count;
2307   int i;
2308
2309   sw_if_index = ntohl (mp->sw_if_index);
2310   count = ntohl (mp->count);
2311   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2312
2313   if (mp->begin)
2314     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2315
2316   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2317   for (i = 0; i < count; i++)
2318     {
2319       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2320       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2321       counter->address.s_addr = v->address;
2322       counter->packets = clib_net_to_host_u64 (v->packets);
2323       counter->bytes = clib_net_to_host_u64 (v->bytes);
2324       counter->linkt = v->link_type;
2325       v++;
2326     }
2327 }
2328
2329 static void vl_api_vnet_ip6_fib_counters_t_handler
2330   (vl_api_vnet_ip6_fib_counters_t * mp)
2331 {
2332   /* not supported */
2333 }
2334
2335 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2336   (vl_api_vnet_ip6_fib_counters_t * mp)
2337 {
2338   vat_main_t *vam = &vat_main;
2339   vl_api_ip6_fib_counter_t *v;
2340   ip6_fib_counter_t *counter;
2341   struct in6_addr ip6;
2342   u32 vrf_id;
2343   u32 vrf_index;
2344   u32 count;
2345   int i;
2346
2347   vrf_id = ntohl (mp->vrf_id);
2348   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2349   if (~0 == vrf_index)
2350     {
2351       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2352       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2353       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2354       vec_validate (vam->ip6_fib_counters, vrf_index);
2355       vam->ip6_fib_counters[vrf_index] = NULL;
2356     }
2357
2358   vec_free (vam->ip6_fib_counters[vrf_index]);
2359   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2360   count = ntohl (mp->count);
2361   for (i = 0; i < count; i++)
2362     {
2363       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2364       counter = &vam->ip6_fib_counters[vrf_index][i];
2365       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2366       counter->address = ip6;
2367       counter->address_length = v->address_length;
2368       counter->packets = clib_net_to_host_u64 (v->packets);
2369       counter->bytes = clib_net_to_host_u64 (v->bytes);
2370       v++;
2371     }
2372 }
2373
2374 static void vl_api_vnet_ip6_nbr_counters_t_handler
2375   (vl_api_vnet_ip6_nbr_counters_t * mp)
2376 {
2377   /* not supported */
2378 }
2379
2380 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2381   (vl_api_vnet_ip6_nbr_counters_t * mp)
2382 {
2383   vat_main_t *vam = &vat_main;
2384   vl_api_ip6_nbr_counter_t *v;
2385   ip6_nbr_counter_t *counter;
2386   struct in6_addr ip6;
2387   u32 sw_if_index;
2388   u32 count;
2389   int i;
2390
2391   sw_if_index = ntohl (mp->sw_if_index);
2392   count = ntohl (mp->count);
2393   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2394
2395   if (mp->begin)
2396     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2397
2398   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2399   for (i = 0; i < count; i++)
2400     {
2401       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2402       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2403       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2404       counter->address = ip6;
2405       counter->packets = clib_net_to_host_u64 (v->packets);
2406       counter->bytes = clib_net_to_host_u64 (v->bytes);
2407       v++;
2408     }
2409 }
2410
2411 static void vl_api_get_first_msg_id_reply_t_handler
2412   (vl_api_get_first_msg_id_reply_t * mp)
2413 {
2414   vat_main_t *vam = &vat_main;
2415   i32 retval = ntohl (mp->retval);
2416
2417   if (vam->async_mode)
2418     {
2419       vam->async_errors += (retval < 0);
2420     }
2421   else
2422     {
2423       vam->retval = retval;
2424       vam->result_ready = 1;
2425     }
2426   if (retval >= 0)
2427     {
2428       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2429     }
2430 }
2431
2432 static void vl_api_get_first_msg_id_reply_t_handler_json
2433   (vl_api_get_first_msg_id_reply_t * mp)
2434 {
2435   vat_main_t *vam = &vat_main;
2436   vat_json_node_t node;
2437
2438   vat_json_init_object (&node);
2439   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2440   vat_json_object_add_uint (&node, "first_msg_id",
2441                             (uint) ntohs (mp->first_msg_id));
2442
2443   vat_json_print (vam->ofp, &node);
2444   vat_json_free (&node);
2445
2446   vam->retval = ntohl (mp->retval);
2447   vam->result_ready = 1;
2448 }
2449
2450 static void vl_api_get_node_graph_reply_t_handler
2451   (vl_api_get_node_graph_reply_t * mp)
2452 {
2453   vat_main_t *vam = &vat_main;
2454   api_main_t *am = &api_main;
2455   i32 retval = ntohl (mp->retval);
2456   u8 *pvt_copy, *reply;
2457   void *oldheap;
2458   vlib_node_t *node;
2459   int i;
2460
2461   if (vam->async_mode)
2462     {
2463       vam->async_errors += (retval < 0);
2464     }
2465   else
2466     {
2467       vam->retval = retval;
2468       vam->result_ready = 1;
2469     }
2470
2471   /* "Should never happen..." */
2472   if (retval != 0)
2473     return;
2474
2475   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2476   pvt_copy = vec_dup (reply);
2477
2478   /* Toss the shared-memory original... */
2479   pthread_mutex_lock (&am->vlib_rp->mutex);
2480   oldheap = svm_push_data_heap (am->vlib_rp);
2481
2482   vec_free (reply);
2483
2484   svm_pop_heap (oldheap);
2485   pthread_mutex_unlock (&am->vlib_rp->mutex);
2486
2487   if (vam->graph_nodes)
2488     {
2489       hash_free (vam->graph_node_index_by_name);
2490
2491       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2492         {
2493           node = vam->graph_nodes[i];
2494           vec_free (node->name);
2495           vec_free (node->next_nodes);
2496           vec_free (node);
2497         }
2498       vec_free (vam->graph_nodes);
2499     }
2500
2501   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2502   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2503   vec_free (pvt_copy);
2504
2505   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2506     {
2507       node = vam->graph_nodes[i];
2508       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2509     }
2510 }
2511
2512 static void vl_api_get_node_graph_reply_t_handler_json
2513   (vl_api_get_node_graph_reply_t * mp)
2514 {
2515   vat_main_t *vam = &vat_main;
2516   api_main_t *am = &api_main;
2517   void *oldheap;
2518   vat_json_node_t node;
2519   u8 *reply;
2520
2521   /* $$$$ make this real? */
2522   vat_json_init_object (&node);
2523   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2524   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2525
2526   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2527
2528   /* Toss the shared-memory original... */
2529   pthread_mutex_lock (&am->vlib_rp->mutex);
2530   oldheap = svm_push_data_heap (am->vlib_rp);
2531
2532   vec_free (reply);
2533
2534   svm_pop_heap (oldheap);
2535   pthread_mutex_unlock (&am->vlib_rp->mutex);
2536
2537   vat_json_print (vam->ofp, &node);
2538   vat_json_free (&node);
2539
2540   vam->retval = ntohl (mp->retval);
2541   vam->result_ready = 1;
2542 }
2543
2544 static void
2545 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2546 {
2547   vat_main_t *vam = &vat_main;
2548   u8 *s = 0;
2549
2550   if (mp->local)
2551     {
2552       s = format (s, "%=16d%=16d%=16d",
2553                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2554     }
2555   else
2556     {
2557       s = format (s, "%=16U%=16d%=16d",
2558                   mp->is_ipv6 ? format_ip6_address :
2559                   format_ip4_address,
2560                   mp->ip_address, mp->priority, mp->weight);
2561     }
2562
2563   print (vam->ofp, "%v", s);
2564   vec_free (s);
2565 }
2566
2567 static void
2568 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2569 {
2570   vat_main_t *vam = &vat_main;
2571   vat_json_node_t *node = NULL;
2572   struct in6_addr ip6;
2573   struct in_addr ip4;
2574
2575   if (VAT_JSON_ARRAY != vam->json_tree.type)
2576     {
2577       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2578       vat_json_init_array (&vam->json_tree);
2579     }
2580   node = vat_json_array_add (&vam->json_tree);
2581   vat_json_init_object (node);
2582
2583   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2584   vat_json_object_add_uint (node, "priority", mp->priority);
2585   vat_json_object_add_uint (node, "weight", mp->weight);
2586
2587   if (mp->local)
2588     vat_json_object_add_uint (node, "sw_if_index",
2589                               clib_net_to_host_u32 (mp->sw_if_index));
2590   else
2591     {
2592       if (mp->is_ipv6)
2593         {
2594           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2595           vat_json_object_add_ip6 (node, "address", ip6);
2596         }
2597       else
2598         {
2599           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2600           vat_json_object_add_ip4 (node, "address", ip4);
2601         }
2602     }
2603 }
2604
2605 static void
2606 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2607                                           mp)
2608 {
2609   vat_main_t *vam = &vat_main;
2610   u8 *ls_name = 0;
2611
2612   ls_name = format (0, "%s", mp->ls_name);
2613
2614   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2615          ls_name);
2616   vec_free (ls_name);
2617 }
2618
2619 static void
2620   vl_api_one_locator_set_details_t_handler_json
2621   (vl_api_one_locator_set_details_t * mp)
2622 {
2623   vat_main_t *vam = &vat_main;
2624   vat_json_node_t *node = 0;
2625   u8 *ls_name = 0;
2626
2627   ls_name = format (0, "%s", mp->ls_name);
2628   vec_add1 (ls_name, 0);
2629
2630   if (VAT_JSON_ARRAY != vam->json_tree.type)
2631     {
2632       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2633       vat_json_init_array (&vam->json_tree);
2634     }
2635   node = vat_json_array_add (&vam->json_tree);
2636
2637   vat_json_init_object (node);
2638   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2639   vat_json_object_add_uint (node, "ls_index",
2640                             clib_net_to_host_u32 (mp->ls_index));
2641   vec_free (ls_name);
2642 }
2643
2644 typedef struct
2645 {
2646   u32 spi;
2647   u8 si;
2648 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2649
2650 uword
2651 unformat_nsh_address (unformat_input_t * input, va_list * args)
2652 {
2653   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2654   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2655 }
2656
2657 u8 *
2658 format_nsh_address_vat (u8 * s, va_list * args)
2659 {
2660   nsh_t *a = va_arg (*args, nsh_t *);
2661   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2662 }
2663
2664 static u8 *
2665 format_lisp_flat_eid (u8 * s, va_list * args)
2666 {
2667   u32 type = va_arg (*args, u32);
2668   u8 *eid = va_arg (*args, u8 *);
2669   u32 eid_len = va_arg (*args, u32);
2670
2671   switch (type)
2672     {
2673     case 0:
2674       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2675     case 1:
2676       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2677     case 2:
2678       return format (s, "%U", format_ethernet_address, eid);
2679     case 3:
2680       return format (s, "%U", format_nsh_address_vat, eid);
2681     }
2682   return 0;
2683 }
2684
2685 static u8 *
2686 format_lisp_eid_vat (u8 * s, va_list * args)
2687 {
2688   u32 type = va_arg (*args, u32);
2689   u8 *eid = va_arg (*args, u8 *);
2690   u32 eid_len = va_arg (*args, u32);
2691   u8 *seid = va_arg (*args, u8 *);
2692   u32 seid_len = va_arg (*args, u32);
2693   u32 is_src_dst = va_arg (*args, u32);
2694
2695   if (is_src_dst)
2696     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2697
2698   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2699
2700   return s;
2701 }
2702
2703 static void
2704 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2705 {
2706   vat_main_t *vam = &vat_main;
2707   u8 *s = 0, *eid = 0;
2708
2709   if (~0 == mp->locator_set_index)
2710     s = format (0, "action: %d", mp->action);
2711   else
2712     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2713
2714   eid = format (0, "%U", format_lisp_eid_vat,
2715                 mp->eid_type,
2716                 mp->eid,
2717                 mp->eid_prefix_len,
2718                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2719   vec_add1 (eid, 0);
2720
2721   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2722          clib_net_to_host_u32 (mp->vni),
2723          eid,
2724          mp->is_local ? "local" : "remote",
2725          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2726          clib_net_to_host_u16 (mp->key_id), mp->key);
2727
2728   vec_free (s);
2729   vec_free (eid);
2730 }
2731
2732 static void
2733 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2734                                              * mp)
2735 {
2736   vat_main_t *vam = &vat_main;
2737   vat_json_node_t *node = 0;
2738   u8 *eid = 0;
2739
2740   if (VAT_JSON_ARRAY != vam->json_tree.type)
2741     {
2742       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2743       vat_json_init_array (&vam->json_tree);
2744     }
2745   node = vat_json_array_add (&vam->json_tree);
2746
2747   vat_json_init_object (node);
2748   if (~0 == mp->locator_set_index)
2749     vat_json_object_add_uint (node, "action", mp->action);
2750   else
2751     vat_json_object_add_uint (node, "locator_set_index",
2752                               clib_net_to_host_u32 (mp->locator_set_index));
2753
2754   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2755   if (mp->eid_type == 3)
2756     {
2757       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
2758       vat_json_init_object (nsh_json);
2759       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
2760       vat_json_object_add_uint (nsh_json, "spi",
2761                                 clib_net_to_host_u32 (nsh->spi));
2762       vat_json_object_add_uint (nsh_json, "si", nsh->si);
2763     }
2764   else
2765     {
2766       eid = format (0, "%U", format_lisp_eid_vat,
2767                     mp->eid_type,
2768                     mp->eid,
2769                     mp->eid_prefix_len,
2770                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2771       vec_add1 (eid, 0);
2772       vat_json_object_add_string_copy (node, "eid", eid);
2773       vec_free (eid);
2774     }
2775   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2776   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2777   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2778
2779   if (mp->key_id)
2780     {
2781       vat_json_object_add_uint (node, "key_id",
2782                                 clib_net_to_host_u16 (mp->key_id));
2783       vat_json_object_add_string_copy (node, "key", mp->key);
2784     }
2785 }
2786
2787 static void
2788 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
2789 {
2790   vat_main_t *vam = &vat_main;
2791   u8 *seid = 0, *deid = 0;
2792   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2793
2794   deid = format (0, "%U", format_lisp_eid_vat,
2795                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2796
2797   seid = format (0, "%U", format_lisp_eid_vat,
2798                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2799
2800   vec_add1 (deid, 0);
2801   vec_add1 (seid, 0);
2802
2803   if (mp->is_ip4)
2804     format_ip_address_fcn = format_ip4_address;
2805   else
2806     format_ip_address_fcn = format_ip6_address;
2807
2808
2809   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
2810          clib_net_to_host_u32 (mp->vni),
2811          seid, deid,
2812          format_ip_address_fcn, mp->lloc,
2813          format_ip_address_fcn, mp->rloc,
2814          clib_net_to_host_u32 (mp->pkt_count),
2815          clib_net_to_host_u32 (mp->bytes));
2816
2817   vec_free (deid);
2818   vec_free (seid);
2819 }
2820
2821 static void
2822 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
2823 {
2824   struct in6_addr ip6;
2825   struct in_addr ip4;
2826   vat_main_t *vam = &vat_main;
2827   vat_json_node_t *node = 0;
2828   u8 *deid = 0, *seid = 0;
2829
2830   if (VAT_JSON_ARRAY != vam->json_tree.type)
2831     {
2832       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2833       vat_json_init_array (&vam->json_tree);
2834     }
2835   node = vat_json_array_add (&vam->json_tree);
2836
2837   vat_json_init_object (node);
2838   deid = format (0, "%U", format_lisp_eid_vat,
2839                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2840
2841   seid = format (0, "%U", format_lisp_eid_vat,
2842                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2843
2844   vec_add1 (deid, 0);
2845   vec_add1 (seid, 0);
2846
2847   vat_json_object_add_string_copy (node, "seid", seid);
2848   vat_json_object_add_string_copy (node, "deid", deid);
2849   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2850
2851   if (mp->is_ip4)
2852     {
2853       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
2854       vat_json_object_add_ip4 (node, "lloc", ip4);
2855       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
2856       vat_json_object_add_ip4 (node, "rloc", ip4);
2857     }
2858   else
2859     {
2860       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
2861       vat_json_object_add_ip6 (node, "lloc", ip6);
2862       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
2863       vat_json_object_add_ip6 (node, "rloc", ip6);
2864     }
2865   vat_json_object_add_uint (node, "pkt_count",
2866                             clib_net_to_host_u32 (mp->pkt_count));
2867   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
2868
2869   vec_free (deid);
2870   vec_free (seid);
2871 }
2872
2873 static void
2874   vl_api_one_eid_table_map_details_t_handler
2875   (vl_api_one_eid_table_map_details_t * mp)
2876 {
2877   vat_main_t *vam = &vat_main;
2878
2879   u8 *line = format (0, "%=10d%=10d",
2880                      clib_net_to_host_u32 (mp->vni),
2881                      clib_net_to_host_u32 (mp->dp_table));
2882   print (vam->ofp, "%v", line);
2883   vec_free (line);
2884 }
2885
2886 static void
2887   vl_api_one_eid_table_map_details_t_handler_json
2888   (vl_api_one_eid_table_map_details_t * mp)
2889 {
2890   vat_main_t *vam = &vat_main;
2891   vat_json_node_t *node = NULL;
2892
2893   if (VAT_JSON_ARRAY != vam->json_tree.type)
2894     {
2895       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2896       vat_json_init_array (&vam->json_tree);
2897     }
2898   node = vat_json_array_add (&vam->json_tree);
2899   vat_json_init_object (node);
2900   vat_json_object_add_uint (node, "dp_table",
2901                             clib_net_to_host_u32 (mp->dp_table));
2902   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2903 }
2904
2905 static void
2906   vl_api_one_eid_table_vni_details_t_handler
2907   (vl_api_one_eid_table_vni_details_t * mp)
2908 {
2909   vat_main_t *vam = &vat_main;
2910
2911   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2912   print (vam->ofp, "%v", line);
2913   vec_free (line);
2914 }
2915
2916 static void
2917   vl_api_one_eid_table_vni_details_t_handler_json
2918   (vl_api_one_eid_table_vni_details_t * mp)
2919 {
2920   vat_main_t *vam = &vat_main;
2921   vat_json_node_t *node = NULL;
2922
2923   if (VAT_JSON_ARRAY != vam->json_tree.type)
2924     {
2925       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2926       vat_json_init_array (&vam->json_tree);
2927     }
2928   node = vat_json_array_add (&vam->json_tree);
2929   vat_json_init_object (node);
2930   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2931 }
2932
2933 static void
2934   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
2935   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
2936 {
2937   vat_main_t *vam = &vat_main;
2938   int retval = clib_net_to_host_u32 (mp->retval);
2939
2940   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
2941   print (vam->ofp, "fallback threshold value: %d", mp->value);
2942
2943   vam->retval = retval;
2944   vam->result_ready = 1;
2945 }
2946
2947 static void
2948   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
2949   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
2950 {
2951   vat_main_t *vam = &vat_main;
2952   vat_json_node_t _node, *node = &_node;
2953   int retval = clib_net_to_host_u32 (mp->retval);
2954
2955   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
2956   vat_json_init_object (node);
2957   vat_json_object_add_uint (node, "value", mp->value);
2958
2959   vat_json_print (vam->ofp, node);
2960   vat_json_free (node);
2961
2962   vam->retval = retval;
2963   vam->result_ready = 1;
2964 }
2965
2966 static void
2967   vl_api_show_one_map_register_state_reply_t_handler
2968   (vl_api_show_one_map_register_state_reply_t * mp)
2969 {
2970   vat_main_t *vam = &vat_main;
2971   int retval = clib_net_to_host_u32 (mp->retval);
2972
2973   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2974
2975   vam->retval = retval;
2976   vam->result_ready = 1;
2977 }
2978
2979 static void
2980   vl_api_show_one_map_register_state_reply_t_handler_json
2981   (vl_api_show_one_map_register_state_reply_t * mp)
2982 {
2983   vat_main_t *vam = &vat_main;
2984   vat_json_node_t _node, *node = &_node;
2985   int retval = clib_net_to_host_u32 (mp->retval);
2986
2987   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2988
2989   vat_json_init_object (node);
2990   vat_json_object_add_string_copy (node, "state", s);
2991
2992   vat_json_print (vam->ofp, node);
2993   vat_json_free (node);
2994
2995   vam->retval = retval;
2996   vam->result_ready = 1;
2997   vec_free (s);
2998 }
2999
3000 static void
3001   vl_api_show_one_rloc_probe_state_reply_t_handler
3002   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3003 {
3004   vat_main_t *vam = &vat_main;
3005   int retval = clib_net_to_host_u32 (mp->retval);
3006
3007   if (retval)
3008     goto end;
3009
3010   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3011 end:
3012   vam->retval = retval;
3013   vam->result_ready = 1;
3014 }
3015
3016 static void
3017   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3018   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3019 {
3020   vat_main_t *vam = &vat_main;
3021   vat_json_node_t _node, *node = &_node;
3022   int retval = clib_net_to_host_u32 (mp->retval);
3023
3024   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3025   vat_json_init_object (node);
3026   vat_json_object_add_string_copy (node, "state", s);
3027
3028   vat_json_print (vam->ofp, node);
3029   vat_json_free (node);
3030
3031   vam->retval = retval;
3032   vam->result_ready = 1;
3033   vec_free (s);
3034 }
3035
3036 static void
3037   vl_api_show_one_stats_enable_disable_reply_t_handler
3038   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3039 {
3040   vat_main_t *vam = &vat_main;
3041   int retval = clib_net_to_host_u32 (mp->retval);
3042
3043   if (retval)
3044     goto end;
3045
3046   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3047 end:
3048   vam->retval = retval;
3049   vam->result_ready = 1;
3050 }
3051
3052 static void
3053   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3054   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3055 {
3056   vat_main_t *vam = &vat_main;
3057   vat_json_node_t _node, *node = &_node;
3058   int retval = clib_net_to_host_u32 (mp->retval);
3059
3060   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3061   vat_json_init_object (node);
3062   vat_json_object_add_string_copy (node, "state", s);
3063
3064   vat_json_print (vam->ofp, node);
3065   vat_json_free (node);
3066
3067   vam->retval = retval;
3068   vam->result_ready = 1;
3069   vec_free (s);
3070 }
3071
3072 static void
3073 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3074 {
3075   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3076   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3077   e->vni = clib_net_to_host_u32 (e->vni);
3078 }
3079
3080 static void
3081   gpe_fwd_entries_get_reply_t_net_to_host
3082   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3083 {
3084   u32 i;
3085
3086   mp->count = clib_net_to_host_u32 (mp->count);
3087   for (i = 0; i < mp->count; i++)
3088     {
3089       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3090     }
3091 }
3092
3093 static u8 *
3094 format_gpe_encap_mode (u8 * s, va_list * args)
3095 {
3096   u32 mode = va_arg (*args, u32);
3097
3098   switch (mode)
3099     {
3100     case 0:
3101       return format (s, "lisp");
3102     case 1:
3103       return format (s, "vxlan");
3104     }
3105   return 0;
3106 }
3107
3108 static void
3109   vl_api_gpe_get_encap_mode_reply_t_handler
3110   (vl_api_gpe_get_encap_mode_reply_t * mp)
3111 {
3112   vat_main_t *vam = &vat_main;
3113
3114   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3115   vam->retval = ntohl (mp->retval);
3116   vam->result_ready = 1;
3117 }
3118
3119 static void
3120   vl_api_gpe_get_encap_mode_reply_t_handler_json
3121   (vl_api_gpe_get_encap_mode_reply_t * mp)
3122 {
3123   vat_main_t *vam = &vat_main;
3124   vat_json_node_t node;
3125
3126   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3127   vec_add1 (encap_mode, 0);
3128
3129   vat_json_init_object (&node);
3130   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3131
3132   vec_free (encap_mode);
3133   vat_json_print (vam->ofp, &node);
3134   vat_json_free (&node);
3135
3136   vam->retval = ntohl (mp->retval);
3137   vam->result_ready = 1;
3138 }
3139
3140 static void
3141   vl_api_gpe_fwd_entry_path_details_t_handler
3142   (vl_api_gpe_fwd_entry_path_details_t * mp)
3143 {
3144   vat_main_t *vam = &vat_main;
3145   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3146
3147   if (mp->lcl_loc.is_ip4)
3148     format_ip_address_fcn = format_ip4_address;
3149   else
3150     format_ip_address_fcn = format_ip6_address;
3151
3152   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3153          format_ip_address_fcn, &mp->lcl_loc,
3154          format_ip_address_fcn, &mp->rmt_loc);
3155 }
3156
3157 static void
3158 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3159 {
3160   struct in6_addr ip6;
3161   struct in_addr ip4;
3162
3163   if (loc->is_ip4)
3164     {
3165       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3166       vat_json_object_add_ip4 (n, "address", ip4);
3167     }
3168   else
3169     {
3170       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3171       vat_json_object_add_ip6 (n, "address", ip6);
3172     }
3173   vat_json_object_add_uint (n, "weight", loc->weight);
3174 }
3175
3176 static void
3177   vl_api_gpe_fwd_entry_path_details_t_handler_json
3178   (vl_api_gpe_fwd_entry_path_details_t * mp)
3179 {
3180   vat_main_t *vam = &vat_main;
3181   vat_json_node_t *node = NULL;
3182   vat_json_node_t *loc_node;
3183
3184   if (VAT_JSON_ARRAY != vam->json_tree.type)
3185     {
3186       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3187       vat_json_init_array (&vam->json_tree);
3188     }
3189   node = vat_json_array_add (&vam->json_tree);
3190   vat_json_init_object (node);
3191
3192   loc_node = vat_json_object_add (node, "local_locator");
3193   vat_json_init_object (loc_node);
3194   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3195
3196   loc_node = vat_json_object_add (node, "remote_locator");
3197   vat_json_init_object (loc_node);
3198   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3199 }
3200
3201 static void
3202   vl_api_gpe_fwd_entries_get_reply_t_handler
3203   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3204 {
3205   vat_main_t *vam = &vat_main;
3206   u32 i;
3207   int retval = clib_net_to_host_u32 (mp->retval);
3208   vl_api_gpe_fwd_entry_t *e;
3209
3210   if (retval)
3211     goto end;
3212
3213   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3214
3215   for (i = 0; i < mp->count; i++)
3216     {
3217       e = &mp->entries[i];
3218       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3219              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3220              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3221     }
3222
3223 end:
3224   vam->retval = retval;
3225   vam->result_ready = 1;
3226 }
3227
3228 static void
3229   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3230   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3231 {
3232   u8 *s = 0;
3233   vat_main_t *vam = &vat_main;
3234   vat_json_node_t *e = 0, root;
3235   u32 i;
3236   int retval = clib_net_to_host_u32 (mp->retval);
3237   vl_api_gpe_fwd_entry_t *fwd;
3238
3239   if (retval)
3240     goto end;
3241
3242   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3243   vat_json_init_array (&root);
3244
3245   for (i = 0; i < mp->count; i++)
3246     {
3247       e = vat_json_array_add (&root);
3248       fwd = &mp->entries[i];
3249
3250       vat_json_init_object (e);
3251       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3252       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3253       vat_json_object_add_int (e, "vni", fwd->vni);
3254       vat_json_object_add_int (e, "action", fwd->action);
3255
3256       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3257                   fwd->leid_prefix_len);
3258       vec_add1 (s, 0);
3259       vat_json_object_add_string_copy (e, "leid", s);
3260       vec_free (s);
3261
3262       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3263                   fwd->reid_prefix_len);
3264       vec_add1 (s, 0);
3265       vat_json_object_add_string_copy (e, "reid", s);
3266       vec_free (s);
3267     }
3268
3269   vat_json_print (vam->ofp, &root);
3270   vat_json_free (&root);
3271
3272 end:
3273   vam->retval = retval;
3274   vam->result_ready = 1;
3275 }
3276
3277 static void
3278   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3279   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3280 {
3281   vat_main_t *vam = &vat_main;
3282   u32 i, n;
3283   int retval = clib_net_to_host_u32 (mp->retval);
3284   vl_api_gpe_native_fwd_rpath_t *r;
3285
3286   if (retval)
3287     goto end;
3288
3289   n = clib_net_to_host_u32 (mp->count);
3290
3291   for (i = 0; i < n; i++)
3292     {
3293       r = &mp->entries[i];
3294       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3295              clib_net_to_host_u32 (r->fib_index),
3296              clib_net_to_host_u32 (r->nh_sw_if_index),
3297              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3298     }
3299
3300 end:
3301   vam->retval = retval;
3302   vam->result_ready = 1;
3303 }
3304
3305 static void
3306   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3307   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3308 {
3309   vat_main_t *vam = &vat_main;
3310   vat_json_node_t root, *e;
3311   u32 i, n;
3312   int retval = clib_net_to_host_u32 (mp->retval);
3313   vl_api_gpe_native_fwd_rpath_t *r;
3314   u8 *s;
3315
3316   if (retval)
3317     goto end;
3318
3319   n = clib_net_to_host_u32 (mp->count);
3320   vat_json_init_array (&root);
3321
3322   for (i = 0; i < n; i++)
3323     {
3324       e = vat_json_array_add (&root);
3325       vat_json_init_object (e);
3326       r = &mp->entries[i];
3327       s =
3328         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3329                 r->nh_addr);
3330       vec_add1 (s, 0);
3331       vat_json_object_add_string_copy (e, "ip4", s);
3332       vec_free (s);
3333
3334       vat_json_object_add_uint (e, "fib_index",
3335                                 clib_net_to_host_u32 (r->fib_index));
3336       vat_json_object_add_uint (e, "nh_sw_if_index",
3337                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3338     }
3339
3340   vat_json_print (vam->ofp, &root);
3341   vat_json_free (&root);
3342
3343 end:
3344   vam->retval = retval;
3345   vam->result_ready = 1;
3346 }
3347
3348 static void
3349   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3350   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3351 {
3352   vat_main_t *vam = &vat_main;
3353   u32 i, n;
3354   int retval = clib_net_to_host_u32 (mp->retval);
3355
3356   if (retval)
3357     goto end;
3358
3359   n = clib_net_to_host_u32 (mp->count);
3360
3361   for (i = 0; i < n; i++)
3362     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3363
3364 end:
3365   vam->retval = retval;
3366   vam->result_ready = 1;
3367 }
3368
3369 static void
3370   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3371   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3372 {
3373   vat_main_t *vam = &vat_main;
3374   vat_json_node_t root;
3375   u32 i, n;
3376   int retval = clib_net_to_host_u32 (mp->retval);
3377
3378   if (retval)
3379     goto end;
3380
3381   n = clib_net_to_host_u32 (mp->count);
3382   vat_json_init_array (&root);
3383
3384   for (i = 0; i < n; i++)
3385     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3386
3387   vat_json_print (vam->ofp, &root);
3388   vat_json_free (&root);
3389
3390 end:
3391   vam->retval = retval;
3392   vam->result_ready = 1;
3393 }
3394
3395 static void
3396   vl_api_one_ndp_entries_get_reply_t_handler
3397   (vl_api_one_ndp_entries_get_reply_t * mp)
3398 {
3399   vat_main_t *vam = &vat_main;
3400   u32 i, n;
3401   int retval = clib_net_to_host_u32 (mp->retval);
3402
3403   if (retval)
3404     goto end;
3405
3406   n = clib_net_to_host_u32 (mp->count);
3407
3408   for (i = 0; i < n; i++)
3409     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3410            format_ethernet_address, mp->entries[i].mac);
3411
3412 end:
3413   vam->retval = retval;
3414   vam->result_ready = 1;
3415 }
3416
3417 static void
3418   vl_api_one_ndp_entries_get_reply_t_handler_json
3419   (vl_api_one_ndp_entries_get_reply_t * mp)
3420 {
3421   u8 *s = 0;
3422   vat_main_t *vam = &vat_main;
3423   vat_json_node_t *e = 0, root;
3424   u32 i, n;
3425   int retval = clib_net_to_host_u32 (mp->retval);
3426   vl_api_one_ndp_entry_t *arp_entry;
3427
3428   if (retval)
3429     goto end;
3430
3431   n = clib_net_to_host_u32 (mp->count);
3432   vat_json_init_array (&root);
3433
3434   for (i = 0; i < n; i++)
3435     {
3436       e = vat_json_array_add (&root);
3437       arp_entry = &mp->entries[i];
3438
3439       vat_json_init_object (e);
3440       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3441       vec_add1 (s, 0);
3442
3443       vat_json_object_add_string_copy (e, "mac", s);
3444       vec_free (s);
3445
3446       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3447       vec_add1 (s, 0);
3448       vat_json_object_add_string_copy (e, "ip6", s);
3449       vec_free (s);
3450     }
3451
3452   vat_json_print (vam->ofp, &root);
3453   vat_json_free (&root);
3454
3455 end:
3456   vam->retval = retval;
3457   vam->result_ready = 1;
3458 }
3459
3460 static void
3461   vl_api_one_l2_arp_entries_get_reply_t_handler
3462   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3463 {
3464   vat_main_t *vam = &vat_main;
3465   u32 i, n;
3466   int retval = clib_net_to_host_u32 (mp->retval);
3467
3468   if (retval)
3469     goto end;
3470
3471   n = clib_net_to_host_u32 (mp->count);
3472
3473   for (i = 0; i < n; i++)
3474     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3475            format_ethernet_address, mp->entries[i].mac);
3476
3477 end:
3478   vam->retval = retval;
3479   vam->result_ready = 1;
3480 }
3481
3482 static void
3483   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3484   (vl_api_one_l2_arp_entries_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_l2_arp_entry_t *arp_entry;
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       arp_entry = &mp->entries[i];
3503
3504       vat_json_init_object (e);
3505       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3506       vec_add1 (s, 0);
3507
3508       vat_json_object_add_string_copy (e, "mac", s);
3509       vec_free (s);
3510
3511       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3512       vec_add1 (s, 0);
3513       vat_json_object_add_string_copy (e, "ip4", s);
3514       vec_free (s);
3515     }
3516
3517   vat_json_print (vam->ofp, &root);
3518   vat_json_free (&root);
3519
3520 end:
3521   vam->retval = retval;
3522   vam->result_ready = 1;
3523 }
3524
3525 static void
3526 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3527 {
3528   vat_main_t *vam = &vat_main;
3529   u32 i, n;
3530   int retval = clib_net_to_host_u32 (mp->retval);
3531
3532   if (retval)
3533     goto end;
3534
3535   n = clib_net_to_host_u32 (mp->count);
3536
3537   for (i = 0; i < n; i++)
3538     {
3539       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3540     }
3541
3542 end:
3543   vam->retval = retval;
3544   vam->result_ready = 1;
3545 }
3546
3547 static void
3548   vl_api_one_ndp_bd_get_reply_t_handler_json
3549   (vl_api_one_ndp_bd_get_reply_t * mp)
3550 {
3551   vat_main_t *vam = &vat_main;
3552   vat_json_node_t root;
3553   u32 i, n;
3554   int retval = clib_net_to_host_u32 (mp->retval);
3555
3556   if (retval)
3557     goto end;
3558
3559   n = clib_net_to_host_u32 (mp->count);
3560   vat_json_init_array (&root);
3561
3562   for (i = 0; i < n; i++)
3563     {
3564       vat_json_array_add_uint (&root,
3565                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3566     }
3567
3568   vat_json_print (vam->ofp, &root);
3569   vat_json_free (&root);
3570
3571 end:
3572   vam->retval = retval;
3573   vam->result_ready = 1;
3574 }
3575
3576 static void
3577   vl_api_one_l2_arp_bd_get_reply_t_handler
3578   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3579 {
3580   vat_main_t *vam = &vat_main;
3581   u32 i, n;
3582   int retval = clib_net_to_host_u32 (mp->retval);
3583
3584   if (retval)
3585     goto end;
3586
3587   n = clib_net_to_host_u32 (mp->count);
3588
3589   for (i = 0; i < n; i++)
3590     {
3591       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3592     }
3593
3594 end:
3595   vam->retval = retval;
3596   vam->result_ready = 1;
3597 }
3598
3599 static void
3600   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3601   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3602 {
3603   vat_main_t *vam = &vat_main;
3604   vat_json_node_t root;
3605   u32 i, n;
3606   int retval = clib_net_to_host_u32 (mp->retval);
3607
3608   if (retval)
3609     goto end;
3610
3611   n = clib_net_to_host_u32 (mp->count);
3612   vat_json_init_array (&root);
3613
3614   for (i = 0; i < n; i++)
3615     {
3616       vat_json_array_add_uint (&root,
3617                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3618     }
3619
3620   vat_json_print (vam->ofp, &root);
3621   vat_json_free (&root);
3622
3623 end:
3624   vam->retval = retval;
3625   vam->result_ready = 1;
3626 }
3627
3628 static void
3629   vl_api_one_adjacencies_get_reply_t_handler
3630   (vl_api_one_adjacencies_get_reply_t * mp)
3631 {
3632   vat_main_t *vam = &vat_main;
3633   u32 i, n;
3634   int retval = clib_net_to_host_u32 (mp->retval);
3635   vl_api_one_adjacency_t *a;
3636
3637   if (retval)
3638     goto end;
3639
3640   n = clib_net_to_host_u32 (mp->count);
3641
3642   for (i = 0; i < n; i++)
3643     {
3644       a = &mp->adjacencies[i];
3645       print (vam->ofp, "%U %40U",
3646              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3647              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3648     }
3649
3650 end:
3651   vam->retval = retval;
3652   vam->result_ready = 1;
3653 }
3654
3655 static void
3656   vl_api_one_adjacencies_get_reply_t_handler_json
3657   (vl_api_one_adjacencies_get_reply_t * mp)
3658 {
3659   u8 *s = 0;
3660   vat_main_t *vam = &vat_main;
3661   vat_json_node_t *e = 0, root;
3662   u32 i, n;
3663   int retval = clib_net_to_host_u32 (mp->retval);
3664   vl_api_one_adjacency_t *a;
3665
3666   if (retval)
3667     goto end;
3668
3669   n = clib_net_to_host_u32 (mp->count);
3670   vat_json_init_array (&root);
3671
3672   for (i = 0; i < n; i++)
3673     {
3674       e = vat_json_array_add (&root);
3675       a = &mp->adjacencies[i];
3676
3677       vat_json_init_object (e);
3678       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3679                   a->leid_prefix_len);
3680       vec_add1 (s, 0);
3681       vat_json_object_add_string_copy (e, "leid", s);
3682       vec_free (s);
3683
3684       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3685                   a->reid_prefix_len);
3686       vec_add1 (s, 0);
3687       vat_json_object_add_string_copy (e, "reid", s);
3688       vec_free (s);
3689     }
3690
3691   vat_json_print (vam->ofp, &root);
3692   vat_json_free (&root);
3693
3694 end:
3695   vam->retval = retval;
3696   vam->result_ready = 1;
3697 }
3698
3699 static void
3700 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3701 {
3702   vat_main_t *vam = &vat_main;
3703
3704   print (vam->ofp, "%=20U",
3705          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3706          mp->ip_address);
3707 }
3708
3709 static void
3710   vl_api_one_map_server_details_t_handler_json
3711   (vl_api_one_map_server_details_t * mp)
3712 {
3713   vat_main_t *vam = &vat_main;
3714   vat_json_node_t *node = NULL;
3715   struct in6_addr ip6;
3716   struct in_addr ip4;
3717
3718   if (VAT_JSON_ARRAY != vam->json_tree.type)
3719     {
3720       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3721       vat_json_init_array (&vam->json_tree);
3722     }
3723   node = vat_json_array_add (&vam->json_tree);
3724
3725   vat_json_init_object (node);
3726   if (mp->is_ipv6)
3727     {
3728       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3729       vat_json_object_add_ip6 (node, "map-server", ip6);
3730     }
3731   else
3732     {
3733       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3734       vat_json_object_add_ip4 (node, "map-server", ip4);
3735     }
3736 }
3737
3738 static void
3739 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3740                                            * mp)
3741 {
3742   vat_main_t *vam = &vat_main;
3743
3744   print (vam->ofp, "%=20U",
3745          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3746          mp->ip_address);
3747 }
3748
3749 static void
3750   vl_api_one_map_resolver_details_t_handler_json
3751   (vl_api_one_map_resolver_details_t * mp)
3752 {
3753   vat_main_t *vam = &vat_main;
3754   vat_json_node_t *node = NULL;
3755   struct in6_addr ip6;
3756   struct in_addr ip4;
3757
3758   if (VAT_JSON_ARRAY != vam->json_tree.type)
3759     {
3760       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3761       vat_json_init_array (&vam->json_tree);
3762     }
3763   node = vat_json_array_add (&vam->json_tree);
3764
3765   vat_json_init_object (node);
3766   if (mp->is_ipv6)
3767     {
3768       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3769       vat_json_object_add_ip6 (node, "map resolver", ip6);
3770     }
3771   else
3772     {
3773       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3774       vat_json_object_add_ip4 (node, "map resolver", ip4);
3775     }
3776 }
3777
3778 static void
3779 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
3780 {
3781   vat_main_t *vam = &vat_main;
3782   i32 retval = ntohl (mp->retval);
3783
3784   if (0 <= retval)
3785     {
3786       print (vam->ofp, "feature: %s\ngpe: %s",
3787              mp->feature_status ? "enabled" : "disabled",
3788              mp->gpe_status ? "enabled" : "disabled");
3789     }
3790
3791   vam->retval = retval;
3792   vam->result_ready = 1;
3793 }
3794
3795 static void
3796   vl_api_show_one_status_reply_t_handler_json
3797   (vl_api_show_one_status_reply_t * mp)
3798 {
3799   vat_main_t *vam = &vat_main;
3800   vat_json_node_t node;
3801   u8 *gpe_status = NULL;
3802   u8 *feature_status = NULL;
3803
3804   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
3805   feature_status = format (0, "%s",
3806                            mp->feature_status ? "enabled" : "disabled");
3807   vec_add1 (gpe_status, 0);
3808   vec_add1 (feature_status, 0);
3809
3810   vat_json_init_object (&node);
3811   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
3812   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
3813
3814   vec_free (gpe_status);
3815   vec_free (feature_status);
3816
3817   vat_json_print (vam->ofp, &node);
3818   vat_json_free (&node);
3819
3820   vam->retval = ntohl (mp->retval);
3821   vam->result_ready = 1;
3822 }
3823
3824 static void
3825   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
3826   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3827 {
3828   vat_main_t *vam = &vat_main;
3829   i32 retval = ntohl (mp->retval);
3830
3831   if (retval >= 0)
3832     {
3833       print (vam->ofp, "%=20s", mp->locator_set_name);
3834     }
3835
3836   vam->retval = retval;
3837   vam->result_ready = 1;
3838 }
3839
3840 static void
3841   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
3842   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3843 {
3844   vat_main_t *vam = &vat_main;
3845   vat_json_node_t *node = NULL;
3846
3847   if (VAT_JSON_ARRAY != vam->json_tree.type)
3848     {
3849       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3850       vat_json_init_array (&vam->json_tree);
3851     }
3852   node = vat_json_array_add (&vam->json_tree);
3853
3854   vat_json_init_object (node);
3855   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
3856
3857   vat_json_print (vam->ofp, node);
3858   vat_json_free (node);
3859
3860   vam->retval = ntohl (mp->retval);
3861   vam->result_ready = 1;
3862 }
3863
3864 static u8 *
3865 format_lisp_map_request_mode (u8 * s, va_list * args)
3866 {
3867   u32 mode = va_arg (*args, u32);
3868
3869   switch (mode)
3870     {
3871     case 0:
3872       return format (0, "dst-only");
3873     case 1:
3874       return format (0, "src-dst");
3875     }
3876   return 0;
3877 }
3878
3879 static void
3880   vl_api_show_one_map_request_mode_reply_t_handler
3881   (vl_api_show_one_map_request_mode_reply_t * mp)
3882 {
3883   vat_main_t *vam = &vat_main;
3884   i32 retval = ntohl (mp->retval);
3885
3886   if (0 <= retval)
3887     {
3888       u32 mode = mp->mode;
3889       print (vam->ofp, "map_request_mode: %U",
3890              format_lisp_map_request_mode, mode);
3891     }
3892
3893   vam->retval = retval;
3894   vam->result_ready = 1;
3895 }
3896
3897 static void
3898   vl_api_show_one_map_request_mode_reply_t_handler_json
3899   (vl_api_show_one_map_request_mode_reply_t * mp)
3900 {
3901   vat_main_t *vam = &vat_main;
3902   vat_json_node_t node;
3903   u8 *s = 0;
3904   u32 mode;
3905
3906   mode = mp->mode;
3907   s = format (0, "%U", format_lisp_map_request_mode, mode);
3908   vec_add1 (s, 0);
3909
3910   vat_json_init_object (&node);
3911   vat_json_object_add_string_copy (&node, "map_request_mode", s);
3912   vat_json_print (vam->ofp, &node);
3913   vat_json_free (&node);
3914
3915   vec_free (s);
3916   vam->retval = ntohl (mp->retval);
3917   vam->result_ready = 1;
3918 }
3919
3920 static void
3921   vl_api_show_one_use_petr_reply_t_handler
3922   (vl_api_show_one_use_petr_reply_t * mp)
3923 {
3924   vat_main_t *vam = &vat_main;
3925   i32 retval = ntohl (mp->retval);
3926
3927   if (0 <= retval)
3928     {
3929       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
3930       if (mp->status)
3931         {
3932           print (vam->ofp, "Proxy-ETR address; %U",
3933                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
3934                  mp->address);
3935         }
3936     }
3937
3938   vam->retval = retval;
3939   vam->result_ready = 1;
3940 }
3941
3942 static void
3943   vl_api_show_one_use_petr_reply_t_handler_json
3944   (vl_api_show_one_use_petr_reply_t * mp)
3945 {
3946   vat_main_t *vam = &vat_main;
3947   vat_json_node_t node;
3948   u8 *status = 0;
3949   struct in_addr ip4;
3950   struct in6_addr ip6;
3951
3952   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3953   vec_add1 (status, 0);
3954
3955   vat_json_init_object (&node);
3956   vat_json_object_add_string_copy (&node, "status", status);
3957   if (mp->status)
3958     {
3959       if (mp->is_ip4)
3960         {
3961           clib_memcpy (&ip6, mp->address, sizeof (ip6));
3962           vat_json_object_add_ip6 (&node, "address", ip6);
3963         }
3964       else
3965         {
3966           clib_memcpy (&ip4, mp->address, sizeof (ip4));
3967           vat_json_object_add_ip4 (&node, "address", ip4);
3968         }
3969     }
3970
3971   vec_free (status);
3972
3973   vat_json_print (vam->ofp, &node);
3974   vat_json_free (&node);
3975
3976   vam->retval = ntohl (mp->retval);
3977   vam->result_ready = 1;
3978 }
3979
3980 static void
3981   vl_api_show_one_nsh_mapping_reply_t_handler
3982   (vl_api_show_one_nsh_mapping_reply_t * mp)
3983 {
3984   vat_main_t *vam = &vat_main;
3985   i32 retval = ntohl (mp->retval);
3986
3987   if (0 <= retval)
3988     {
3989       print (vam->ofp, "%-20s%-16s",
3990              mp->is_set ? "set" : "not-set",
3991              mp->is_set ? (char *) mp->locator_set_name : "");
3992     }
3993
3994   vam->retval = retval;
3995   vam->result_ready = 1;
3996 }
3997
3998 static void
3999   vl_api_show_one_nsh_mapping_reply_t_handler_json
4000   (vl_api_show_one_nsh_mapping_reply_t * mp)
4001 {
4002   vat_main_t *vam = &vat_main;
4003   vat_json_node_t node;
4004   u8 *status = 0;
4005
4006   status = format (0, "%s", mp->is_set ? "yes" : "no");
4007   vec_add1 (status, 0);
4008
4009   vat_json_init_object (&node);
4010   vat_json_object_add_string_copy (&node, "is_set", status);
4011   if (mp->is_set)
4012     {
4013       vat_json_object_add_string_copy (&node, "locator_set",
4014                                        mp->locator_set_name);
4015     }
4016
4017   vec_free (status);
4018
4019   vat_json_print (vam->ofp, &node);
4020   vat_json_free (&node);
4021
4022   vam->retval = ntohl (mp->retval);
4023   vam->result_ready = 1;
4024 }
4025
4026 static void
4027   vl_api_show_one_map_register_ttl_reply_t_handler
4028   (vl_api_show_one_map_register_ttl_reply_t * mp)
4029 {
4030   vat_main_t *vam = &vat_main;
4031   i32 retval = ntohl (mp->retval);
4032
4033   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4034
4035   if (0 <= retval)
4036     {
4037       print (vam->ofp, "ttl: %u", mp->ttl);
4038     }
4039
4040   vam->retval = retval;
4041   vam->result_ready = 1;
4042 }
4043
4044 static void
4045   vl_api_show_one_map_register_ttl_reply_t_handler_json
4046   (vl_api_show_one_map_register_ttl_reply_t * mp)
4047 {
4048   vat_main_t *vam = &vat_main;
4049   vat_json_node_t node;
4050
4051   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4052   vat_json_init_object (&node);
4053   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4054
4055   vat_json_print (vam->ofp, &node);
4056   vat_json_free (&node);
4057
4058   vam->retval = ntohl (mp->retval);
4059   vam->result_ready = 1;
4060 }
4061
4062 static void
4063 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4064 {
4065   vat_main_t *vam = &vat_main;
4066   i32 retval = ntohl (mp->retval);
4067
4068   if (0 <= retval)
4069     {
4070       print (vam->ofp, "%-20s%-16s",
4071              mp->status ? "enabled" : "disabled",
4072              mp->status ? (char *) mp->locator_set_name : "");
4073     }
4074
4075   vam->retval = retval;
4076   vam->result_ready = 1;
4077 }
4078
4079 static void
4080 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4081 {
4082   vat_main_t *vam = &vat_main;
4083   vat_json_node_t node;
4084   u8 *status = 0;
4085
4086   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4087   vec_add1 (status, 0);
4088
4089   vat_json_init_object (&node);
4090   vat_json_object_add_string_copy (&node, "status", status);
4091   if (mp->status)
4092     {
4093       vat_json_object_add_string_copy (&node, "locator_set",
4094                                        mp->locator_set_name);
4095     }
4096
4097   vec_free (status);
4098
4099   vat_json_print (vam->ofp, &node);
4100   vat_json_free (&node);
4101
4102   vam->retval = ntohl (mp->retval);
4103   vam->result_ready = 1;
4104 }
4105
4106 static u8 *
4107 format_policer_type (u8 * s, va_list * va)
4108 {
4109   u32 i = va_arg (*va, u32);
4110
4111   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4112     s = format (s, "1r2c");
4113   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4114     s = format (s, "1r3c");
4115   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4116     s = format (s, "2r3c-2698");
4117   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4118     s = format (s, "2r3c-4115");
4119   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4120     s = format (s, "2r3c-mef5cf1");
4121   else
4122     s = format (s, "ILLEGAL");
4123   return s;
4124 }
4125
4126 static u8 *
4127 format_policer_rate_type (u8 * s, va_list * va)
4128 {
4129   u32 i = va_arg (*va, u32);
4130
4131   if (i == SSE2_QOS_RATE_KBPS)
4132     s = format (s, "kbps");
4133   else if (i == SSE2_QOS_RATE_PPS)
4134     s = format (s, "pps");
4135   else
4136     s = format (s, "ILLEGAL");
4137   return s;
4138 }
4139
4140 static u8 *
4141 format_policer_round_type (u8 * s, va_list * va)
4142 {
4143   u32 i = va_arg (*va, u32);
4144
4145   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4146     s = format (s, "closest");
4147   else if (i == SSE2_QOS_ROUND_TO_UP)
4148     s = format (s, "up");
4149   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4150     s = format (s, "down");
4151   else
4152     s = format (s, "ILLEGAL");
4153   return s;
4154 }
4155
4156 static u8 *
4157 format_policer_action_type (u8 * s, va_list * va)
4158 {
4159   u32 i = va_arg (*va, u32);
4160
4161   if (i == SSE2_QOS_ACTION_DROP)
4162     s = format (s, "drop");
4163   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4164     s = format (s, "transmit");
4165   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4166     s = format (s, "mark-and-transmit");
4167   else
4168     s = format (s, "ILLEGAL");
4169   return s;
4170 }
4171
4172 static u8 *
4173 format_dscp (u8 * s, va_list * va)
4174 {
4175   u32 i = va_arg (*va, u32);
4176   char *t = 0;
4177
4178   switch (i)
4179     {
4180 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4181       foreach_vnet_dscp
4182 #undef _
4183     default:
4184       return format (s, "ILLEGAL");
4185     }
4186   s = format (s, "%s", t);
4187   return s;
4188 }
4189
4190 static void
4191 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4192 {
4193   vat_main_t *vam = &vat_main;
4194   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4195
4196   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4197     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4198   else
4199     conform_dscp_str = format (0, "");
4200
4201   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4202     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4203   else
4204     exceed_dscp_str = format (0, "");
4205
4206   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4207     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4208   else
4209     violate_dscp_str = format (0, "");
4210
4211   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4212          "rate type %U, round type %U, %s rate, %s color-aware, "
4213          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4214          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4215          "conform action %U%s, exceed action %U%s, violate action %U%s",
4216          mp->name,
4217          format_policer_type, mp->type,
4218          ntohl (mp->cir),
4219          ntohl (mp->eir),
4220          clib_net_to_host_u64 (mp->cb),
4221          clib_net_to_host_u64 (mp->eb),
4222          format_policer_rate_type, mp->rate_type,
4223          format_policer_round_type, mp->round_type,
4224          mp->single_rate ? "single" : "dual",
4225          mp->color_aware ? "is" : "not",
4226          ntohl (mp->cir_tokens_per_period),
4227          ntohl (mp->pir_tokens_per_period),
4228          ntohl (mp->scale),
4229          ntohl (mp->current_limit),
4230          ntohl (mp->current_bucket),
4231          ntohl (mp->extended_limit),
4232          ntohl (mp->extended_bucket),
4233          clib_net_to_host_u64 (mp->last_update_time),
4234          format_policer_action_type, mp->conform_action_type,
4235          conform_dscp_str,
4236          format_policer_action_type, mp->exceed_action_type,
4237          exceed_dscp_str,
4238          format_policer_action_type, mp->violate_action_type,
4239          violate_dscp_str);
4240
4241   vec_free (conform_dscp_str);
4242   vec_free (exceed_dscp_str);
4243   vec_free (violate_dscp_str);
4244 }
4245
4246 static void vl_api_policer_details_t_handler_json
4247   (vl_api_policer_details_t * mp)
4248 {
4249   vat_main_t *vam = &vat_main;
4250   vat_json_node_t *node;
4251   u8 *rate_type_str, *round_type_str, *type_str;
4252   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4253
4254   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4255   round_type_str =
4256     format (0, "%U", format_policer_round_type, mp->round_type);
4257   type_str = format (0, "%U", format_policer_type, mp->type);
4258   conform_action_str = format (0, "%U", format_policer_action_type,
4259                                mp->conform_action_type);
4260   exceed_action_str = format (0, "%U", format_policer_action_type,
4261                               mp->exceed_action_type);
4262   violate_action_str = format (0, "%U", format_policer_action_type,
4263                                mp->violate_action_type);
4264
4265   if (VAT_JSON_ARRAY != vam->json_tree.type)
4266     {
4267       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4268       vat_json_init_array (&vam->json_tree);
4269     }
4270   node = vat_json_array_add (&vam->json_tree);
4271
4272   vat_json_init_object (node);
4273   vat_json_object_add_string_copy (node, "name", mp->name);
4274   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4275   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4276   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4277   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4278   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4279   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4280   vat_json_object_add_string_copy (node, "type", type_str);
4281   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4282   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4283   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4284   vat_json_object_add_uint (node, "cir_tokens_per_period",
4285                             ntohl (mp->cir_tokens_per_period));
4286   vat_json_object_add_uint (node, "eir_tokens_per_period",
4287                             ntohl (mp->pir_tokens_per_period));
4288   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4289   vat_json_object_add_uint (node, "current_bucket",
4290                             ntohl (mp->current_bucket));
4291   vat_json_object_add_uint (node, "extended_limit",
4292                             ntohl (mp->extended_limit));
4293   vat_json_object_add_uint (node, "extended_bucket",
4294                             ntohl (mp->extended_bucket));
4295   vat_json_object_add_uint (node, "last_update_time",
4296                             ntohl (mp->last_update_time));
4297   vat_json_object_add_string_copy (node, "conform_action",
4298                                    conform_action_str);
4299   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4300     {
4301       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4302       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4303       vec_free (dscp_str);
4304     }
4305   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4306   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4307     {
4308       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4309       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4310       vec_free (dscp_str);
4311     }
4312   vat_json_object_add_string_copy (node, "violate_action",
4313                                    violate_action_str);
4314   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4315     {
4316       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4317       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4318       vec_free (dscp_str);
4319     }
4320
4321   vec_free (rate_type_str);
4322   vec_free (round_type_str);
4323   vec_free (type_str);
4324   vec_free (conform_action_str);
4325   vec_free (exceed_action_str);
4326   vec_free (violate_action_str);
4327 }
4328
4329 static void
4330 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4331                                            mp)
4332 {
4333   vat_main_t *vam = &vat_main;
4334   int i, count = ntohl (mp->count);
4335
4336   if (count > 0)
4337     print (vam->ofp, "classify table ids (%d) : ", count);
4338   for (i = 0; i < count; i++)
4339     {
4340       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4341       print (vam->ofp, (i < count - 1) ? "," : "");
4342     }
4343   vam->retval = ntohl (mp->retval);
4344   vam->result_ready = 1;
4345 }
4346
4347 static void
4348   vl_api_classify_table_ids_reply_t_handler_json
4349   (vl_api_classify_table_ids_reply_t * mp)
4350 {
4351   vat_main_t *vam = &vat_main;
4352   int i, count = ntohl (mp->count);
4353
4354   if (count > 0)
4355     {
4356       vat_json_node_t node;
4357
4358       vat_json_init_object (&node);
4359       for (i = 0; i < count; i++)
4360         {
4361           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4362         }
4363       vat_json_print (vam->ofp, &node);
4364       vat_json_free (&node);
4365     }
4366   vam->retval = ntohl (mp->retval);
4367   vam->result_ready = 1;
4368 }
4369
4370 static void
4371   vl_api_classify_table_by_interface_reply_t_handler
4372   (vl_api_classify_table_by_interface_reply_t * mp)
4373 {
4374   vat_main_t *vam = &vat_main;
4375   u32 table_id;
4376
4377   table_id = ntohl (mp->l2_table_id);
4378   if (table_id != ~0)
4379     print (vam->ofp, "l2 table id : %d", table_id);
4380   else
4381     print (vam->ofp, "l2 table id : No input ACL tables configured");
4382   table_id = ntohl (mp->ip4_table_id);
4383   if (table_id != ~0)
4384     print (vam->ofp, "ip4 table id : %d", table_id);
4385   else
4386     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4387   table_id = ntohl (mp->ip6_table_id);
4388   if (table_id != ~0)
4389     print (vam->ofp, "ip6 table id : %d", table_id);
4390   else
4391     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4392   vam->retval = ntohl (mp->retval);
4393   vam->result_ready = 1;
4394 }
4395
4396 static void
4397   vl_api_classify_table_by_interface_reply_t_handler_json
4398   (vl_api_classify_table_by_interface_reply_t * mp)
4399 {
4400   vat_main_t *vam = &vat_main;
4401   vat_json_node_t node;
4402
4403   vat_json_init_object (&node);
4404
4405   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4406   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4407   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4408
4409   vat_json_print (vam->ofp, &node);
4410   vat_json_free (&node);
4411
4412   vam->retval = ntohl (mp->retval);
4413   vam->result_ready = 1;
4414 }
4415
4416 static void vl_api_policer_add_del_reply_t_handler
4417   (vl_api_policer_add_del_reply_t * mp)
4418 {
4419   vat_main_t *vam = &vat_main;
4420   i32 retval = ntohl (mp->retval);
4421   if (vam->async_mode)
4422     {
4423       vam->async_errors += (retval < 0);
4424     }
4425   else
4426     {
4427       vam->retval = retval;
4428       vam->result_ready = 1;
4429       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4430         /*
4431          * Note: this is just barely thread-safe, depends on
4432          * the main thread spinning waiting for an answer...
4433          */
4434         errmsg ("policer index %d", ntohl (mp->policer_index));
4435     }
4436 }
4437
4438 static void vl_api_policer_add_del_reply_t_handler_json
4439   (vl_api_policer_add_del_reply_t * mp)
4440 {
4441   vat_main_t *vam = &vat_main;
4442   vat_json_node_t node;
4443
4444   vat_json_init_object (&node);
4445   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4446   vat_json_object_add_uint (&node, "policer_index",
4447                             ntohl (mp->policer_index));
4448
4449   vat_json_print (vam->ofp, &node);
4450   vat_json_free (&node);
4451
4452   vam->retval = ntohl (mp->retval);
4453   vam->result_ready = 1;
4454 }
4455
4456 /* Format hex dump. */
4457 u8 *
4458 format_hex_bytes (u8 * s, va_list * va)
4459 {
4460   u8 *bytes = va_arg (*va, u8 *);
4461   int n_bytes = va_arg (*va, int);
4462   uword i;
4463
4464   /* Print short or long form depending on byte count. */
4465   uword short_form = n_bytes <= 32;
4466   uword indent = format_get_indent (s);
4467
4468   if (n_bytes == 0)
4469     return s;
4470
4471   for (i = 0; i < n_bytes; i++)
4472     {
4473       if (!short_form && (i % 32) == 0)
4474         s = format (s, "%08x: ", i);
4475       s = format (s, "%02x", bytes[i]);
4476       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4477         s = format (s, "\n%U", format_white_space, indent);
4478     }
4479
4480   return s;
4481 }
4482
4483 static void
4484 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4485                                             * mp)
4486 {
4487   vat_main_t *vam = &vat_main;
4488   i32 retval = ntohl (mp->retval);
4489   if (retval == 0)
4490     {
4491       print (vam->ofp, "classify table info :");
4492       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4493              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4494              ntohl (mp->miss_next_index));
4495       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4496              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4497              ntohl (mp->match_n_vectors));
4498       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4499              ntohl (mp->mask_length));
4500     }
4501   vam->retval = retval;
4502   vam->result_ready = 1;
4503 }
4504
4505 static void
4506   vl_api_classify_table_info_reply_t_handler_json
4507   (vl_api_classify_table_info_reply_t * mp)
4508 {
4509   vat_main_t *vam = &vat_main;
4510   vat_json_node_t node;
4511
4512   i32 retval = ntohl (mp->retval);
4513   if (retval == 0)
4514     {
4515       vat_json_init_object (&node);
4516
4517       vat_json_object_add_int (&node, "sessions",
4518                                ntohl (mp->active_sessions));
4519       vat_json_object_add_int (&node, "nexttbl",
4520                                ntohl (mp->next_table_index));
4521       vat_json_object_add_int (&node, "nextnode",
4522                                ntohl (mp->miss_next_index));
4523       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4524       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4525       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4526       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4527                       ntohl (mp->mask_length), 0);
4528       vat_json_object_add_string_copy (&node, "mask", s);
4529
4530       vat_json_print (vam->ofp, &node);
4531       vat_json_free (&node);
4532     }
4533   vam->retval = ntohl (mp->retval);
4534   vam->result_ready = 1;
4535 }
4536
4537 static void
4538 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4539                                            mp)
4540 {
4541   vat_main_t *vam = &vat_main;
4542
4543   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4544          ntohl (mp->hit_next_index), ntohl (mp->advance),
4545          ntohl (mp->opaque_index));
4546   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4547          ntohl (mp->match_length));
4548 }
4549
4550 static void
4551   vl_api_classify_session_details_t_handler_json
4552   (vl_api_classify_session_details_t * mp)
4553 {
4554   vat_main_t *vam = &vat_main;
4555   vat_json_node_t *node = NULL;
4556
4557   if (VAT_JSON_ARRAY != vam->json_tree.type)
4558     {
4559       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4560       vat_json_init_array (&vam->json_tree);
4561     }
4562   node = vat_json_array_add (&vam->json_tree);
4563
4564   vat_json_init_object (node);
4565   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4566   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4567   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4568   u8 *s =
4569     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4570             0);
4571   vat_json_object_add_string_copy (node, "match", s);
4572 }
4573
4574 static void vl_api_pg_create_interface_reply_t_handler
4575   (vl_api_pg_create_interface_reply_t * mp)
4576 {
4577   vat_main_t *vam = &vat_main;
4578
4579   vam->retval = ntohl (mp->retval);
4580   vam->result_ready = 1;
4581 }
4582
4583 static void vl_api_pg_create_interface_reply_t_handler_json
4584   (vl_api_pg_create_interface_reply_t * mp)
4585 {
4586   vat_main_t *vam = &vat_main;
4587   vat_json_node_t node;
4588
4589   i32 retval = ntohl (mp->retval);
4590   if (retval == 0)
4591     {
4592       vat_json_init_object (&node);
4593
4594       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4595
4596       vat_json_print (vam->ofp, &node);
4597       vat_json_free (&node);
4598     }
4599   vam->retval = ntohl (mp->retval);
4600   vam->result_ready = 1;
4601 }
4602
4603 static void vl_api_policer_classify_details_t_handler
4604   (vl_api_policer_classify_details_t * mp)
4605 {
4606   vat_main_t *vam = &vat_main;
4607
4608   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4609          ntohl (mp->table_index));
4610 }
4611
4612 static void vl_api_policer_classify_details_t_handler_json
4613   (vl_api_policer_classify_details_t * mp)
4614 {
4615   vat_main_t *vam = &vat_main;
4616   vat_json_node_t *node;
4617
4618   if (VAT_JSON_ARRAY != vam->json_tree.type)
4619     {
4620       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4621       vat_json_init_array (&vam->json_tree);
4622     }
4623   node = vat_json_array_add (&vam->json_tree);
4624
4625   vat_json_init_object (node);
4626   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4627   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4628 }
4629
4630 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
4631   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4632 {
4633   vat_main_t *vam = &vat_main;
4634   i32 retval = ntohl (mp->retval);
4635   if (vam->async_mode)
4636     {
4637       vam->async_errors += (retval < 0);
4638     }
4639   else
4640     {
4641       vam->retval = retval;
4642       vam->sw_if_index = ntohl (mp->sw_if_index);
4643       vam->result_ready = 1;
4644     }
4645 }
4646
4647 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
4648   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4649 {
4650   vat_main_t *vam = &vat_main;
4651   vat_json_node_t node;
4652
4653   vat_json_init_object (&node);
4654   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4655   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
4656
4657   vat_json_print (vam->ofp, &node);
4658   vat_json_free (&node);
4659
4660   vam->retval = ntohl (mp->retval);
4661   vam->result_ready = 1;
4662 }
4663
4664 static void vl_api_flow_classify_details_t_handler
4665   (vl_api_flow_classify_details_t * mp)
4666 {
4667   vat_main_t *vam = &vat_main;
4668
4669   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4670          ntohl (mp->table_index));
4671 }
4672
4673 static void vl_api_flow_classify_details_t_handler_json
4674   (vl_api_flow_classify_details_t * mp)
4675 {
4676   vat_main_t *vam = &vat_main;
4677   vat_json_node_t *node;
4678
4679   if (VAT_JSON_ARRAY != vam->json_tree.type)
4680     {
4681       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4682       vat_json_init_array (&vam->json_tree);
4683     }
4684   node = vat_json_array_add (&vam->json_tree);
4685
4686   vat_json_init_object (node);
4687   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4688   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4689 }
4690
4691 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
4692 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
4693 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
4694 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
4695 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
4696 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
4697 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
4698 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
4699 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
4700 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
4701 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
4702 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
4703 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
4704 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
4705 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
4706 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
4707 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
4708 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
4709 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
4710 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
4711 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
4712 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
4713
4714 /*
4715  * Generate boilerplate reply handlers, which
4716  * dig the return value out of the xxx_reply_t API message,
4717  * stick it into vam->retval, and set vam->result_ready
4718  *
4719  * Could also do this by pointing N message decode slots at
4720  * a single function, but that could break in subtle ways.
4721  */
4722
4723 #define foreach_standard_reply_retval_handler           \
4724 _(sw_interface_set_flags_reply)                         \
4725 _(sw_interface_add_del_address_reply)                   \
4726 _(sw_interface_set_table_reply)                         \
4727 _(sw_interface_set_mpls_enable_reply)                   \
4728 _(sw_interface_set_vpath_reply)                         \
4729 _(sw_interface_set_vxlan_bypass_reply)                  \
4730 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
4731 _(sw_interface_set_l2_bridge_reply)                     \
4732 _(bridge_domain_add_del_reply)                          \
4733 _(sw_interface_set_l2_xconnect_reply)                   \
4734 _(l2fib_add_del_reply)                                  \
4735 _(l2fib_flush_int_reply)                                \
4736 _(l2fib_flush_bd_reply)                                 \
4737 _(ip_add_del_route_reply)                               \
4738 _(ip_table_add_del_reply)                               \
4739 _(ip_mroute_add_del_reply)                              \
4740 _(mpls_route_add_del_reply)                             \
4741 _(mpls_table_add_del_reply)                             \
4742 _(mpls_ip_bind_unbind_reply)                            \
4743 _(proxy_arp_add_del_reply)                              \
4744 _(proxy_arp_intfc_enable_disable_reply)                 \
4745 _(sw_interface_set_unnumbered_reply)                    \
4746 _(ip_neighbor_add_del_reply)                            \
4747 _(reset_vrf_reply)                                      \
4748 _(oam_add_del_reply)                                    \
4749 _(reset_fib_reply)                                      \
4750 _(dhcp_proxy_config_reply)                              \
4751 _(dhcp_proxy_set_vss_reply)                             \
4752 _(dhcp_client_config_reply)                             \
4753 _(set_ip_flow_hash_reply)                               \
4754 _(sw_interface_ip6_enable_disable_reply)                \
4755 _(sw_interface_ip6_set_link_local_address_reply)        \
4756 _(ip6nd_proxy_add_del_reply)                            \
4757 _(sw_interface_ip6nd_ra_prefix_reply)                   \
4758 _(sw_interface_ip6nd_ra_config_reply)                   \
4759 _(set_arp_neighbor_limit_reply)                         \
4760 _(l2_patch_add_del_reply)                               \
4761 _(sr_policy_add_reply)                                  \
4762 _(sr_policy_mod_reply)                                  \
4763 _(sr_policy_del_reply)                                  \
4764 _(sr_localsid_add_del_reply)                            \
4765 _(sr_steering_add_del_reply)                            \
4766 _(classify_add_del_session_reply)                       \
4767 _(classify_set_interface_ip_table_reply)                \
4768 _(classify_set_interface_l2_tables_reply)               \
4769 _(l2tpv3_set_tunnel_cookies_reply)                      \
4770 _(l2tpv3_interface_enable_disable_reply)                \
4771 _(l2tpv3_set_lookup_key_reply)                          \
4772 _(l2_fib_clear_table_reply)                             \
4773 _(l2_interface_efp_filter_reply)                        \
4774 _(l2_interface_vlan_tag_rewrite_reply)                  \
4775 _(modify_vhost_user_if_reply)                           \
4776 _(delete_vhost_user_if_reply)                           \
4777 _(want_ip4_arp_events_reply)                            \
4778 _(want_ip6_nd_events_reply)                             \
4779 _(want_l2_macs_events_reply)                            \
4780 _(input_acl_set_interface_reply)                        \
4781 _(ipsec_spd_add_del_reply)                              \
4782 _(ipsec_interface_add_del_spd_reply)                    \
4783 _(ipsec_spd_add_del_entry_reply)                        \
4784 _(ipsec_sad_add_del_entry_reply)                        \
4785 _(ipsec_sa_set_key_reply)                               \
4786 _(ipsec_tunnel_if_add_del_reply)                        \
4787 _(ikev2_profile_add_del_reply)                          \
4788 _(ikev2_profile_set_auth_reply)                         \
4789 _(ikev2_profile_set_id_reply)                           \
4790 _(ikev2_profile_set_ts_reply)                           \
4791 _(ikev2_set_local_key_reply)                            \
4792 _(ikev2_set_responder_reply)                            \
4793 _(ikev2_set_ike_transforms_reply)                       \
4794 _(ikev2_set_esp_transforms_reply)                       \
4795 _(ikev2_set_sa_lifetime_reply)                          \
4796 _(ikev2_initiate_sa_init_reply)                         \
4797 _(ikev2_initiate_del_ike_sa_reply)                      \
4798 _(ikev2_initiate_del_child_sa_reply)                    \
4799 _(ikev2_initiate_rekey_child_sa_reply)                  \
4800 _(delete_loopback_reply)                                \
4801 _(bd_ip_mac_add_del_reply)                              \
4802 _(map_del_domain_reply)                                 \
4803 _(map_add_del_rule_reply)                               \
4804 _(want_interface_events_reply)                          \
4805 _(want_stats_reply)                                     \
4806 _(cop_interface_enable_disable_reply)                   \
4807 _(cop_whitelist_enable_disable_reply)                   \
4808 _(sw_interface_clear_stats_reply)                       \
4809 _(ioam_enable_reply)                              \
4810 _(ioam_disable_reply)                              \
4811 _(one_add_del_locator_reply)                            \
4812 _(one_add_del_local_eid_reply)                          \
4813 _(one_add_del_remote_mapping_reply)                     \
4814 _(one_add_del_adjacency_reply)                          \
4815 _(one_add_del_map_resolver_reply)                       \
4816 _(one_add_del_map_server_reply)                         \
4817 _(one_enable_disable_reply)                             \
4818 _(one_rloc_probe_enable_disable_reply)                  \
4819 _(one_map_register_enable_disable_reply)                \
4820 _(one_map_register_set_ttl_reply)                       \
4821 _(one_map_register_fallback_threshold_reply)            \
4822 _(one_pitr_set_locator_set_reply)                       \
4823 _(one_map_request_mode_reply)                           \
4824 _(one_add_del_map_request_itr_rlocs_reply)              \
4825 _(one_eid_table_add_del_map_reply)                      \
4826 _(one_use_petr_reply)                                   \
4827 _(one_stats_enable_disable_reply)                       \
4828 _(one_add_del_l2_arp_entry_reply)                       \
4829 _(one_add_del_ndp_entry_reply)                          \
4830 _(one_stats_flush_reply)                                \
4831 _(gpe_enable_disable_reply)                             \
4832 _(gpe_set_encap_mode_reply)                             \
4833 _(gpe_add_del_iface_reply)                              \
4834 _(gpe_add_del_native_fwd_rpath_reply)                   \
4835 _(af_packet_delete_reply)                               \
4836 _(policer_classify_set_interface_reply)                 \
4837 _(netmap_create_reply)                                  \
4838 _(netmap_delete_reply)                                  \
4839 _(set_ipfix_exporter_reply)                             \
4840 _(set_ipfix_classify_stream_reply)                      \
4841 _(ipfix_classify_table_add_del_reply)                   \
4842 _(flow_classify_set_interface_reply)                    \
4843 _(sw_interface_span_enable_disable_reply)               \
4844 _(pg_capture_reply)                                     \
4845 _(pg_enable_disable_reply)                              \
4846 _(ip_source_and_port_range_check_add_del_reply)         \
4847 _(ip_source_and_port_range_check_interface_add_del_reply)\
4848 _(delete_subif_reply)                                   \
4849 _(l2_interface_pbb_tag_rewrite_reply)                   \
4850 _(punt_reply)                                           \
4851 _(feature_enable_disable_reply)                         \
4852 _(sw_interface_tag_add_del_reply)                       \
4853 _(sw_interface_set_mtu_reply)                           \
4854 _(p2p_ethernet_add_reply)                               \
4855 _(p2p_ethernet_del_reply)                               \
4856 _(lldp_config_reply)                                    \
4857 _(sw_interface_set_lldp_reply)                          \
4858 _(tcp_configure_src_addresses_reply)
4859
4860 #define _(n)                                    \
4861     static void vl_api_##n##_t_handler          \
4862     (vl_api_##n##_t * mp)                       \
4863     {                                           \
4864         vat_main_t * vam = &vat_main;           \
4865         i32 retval = ntohl(mp->retval);         \
4866         if (vam->async_mode) {                  \
4867             vam->async_errors += (retval < 0);  \
4868         } else {                                \
4869             vam->retval = retval;               \
4870             vam->result_ready = 1;              \
4871         }                                       \
4872     }
4873 foreach_standard_reply_retval_handler;
4874 #undef _
4875
4876 #define _(n)                                    \
4877     static void vl_api_##n##_t_handler_json     \
4878     (vl_api_##n##_t * mp)                       \
4879     {                                           \
4880         vat_main_t * vam = &vat_main;           \
4881         vat_json_node_t node;                   \
4882         vat_json_init_object(&node);            \
4883         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
4884         vat_json_print(vam->ofp, &node);        \
4885         vam->retval = ntohl(mp->retval);        \
4886         vam->result_ready = 1;                  \
4887     }
4888 foreach_standard_reply_retval_handler;
4889 #undef _
4890
4891 /*
4892  * Table of message reply handlers, must include boilerplate handlers
4893  * we just generated
4894  */
4895
4896 #define foreach_vpe_api_reply_msg                                       \
4897 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
4898 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
4899 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
4900 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
4901 _(CONTROL_PING_REPLY, control_ping_reply)                               \
4902 _(CLI_REPLY, cli_reply)                                                 \
4903 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
4904 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
4905   sw_interface_add_del_address_reply)                                   \
4906 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
4907 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
4908 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
4909 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
4910 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
4911 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
4912   sw_interface_set_l2_xconnect_reply)                                   \
4913 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
4914   sw_interface_set_l2_bridge_reply)                                     \
4915 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
4916 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
4917 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
4918 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
4919 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
4920 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
4921 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
4922 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
4923 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
4924 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
4925 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
4926 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
4927 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
4928 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
4929 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
4930 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
4931 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
4932 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
4933 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
4934 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
4935   proxy_arp_intfc_enable_disable_reply)                                 \
4936 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
4937 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
4938   sw_interface_set_unnumbered_reply)                                    \
4939 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
4940 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
4941 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
4942 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
4943 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
4944 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
4945 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
4946 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
4947 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
4948 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
4949 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
4950 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
4951   sw_interface_ip6_enable_disable_reply)                                \
4952 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
4953   sw_interface_ip6_set_link_local_address_reply)                        \
4954 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
4955 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
4956 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
4957   sw_interface_ip6nd_ra_prefix_reply)                                   \
4958 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
4959   sw_interface_ip6nd_ra_config_reply)                                   \
4960 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
4961 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
4962 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
4963 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
4964 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
4965 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
4966 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
4967 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
4968 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
4969 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
4970 classify_set_interface_ip_table_reply)                                  \
4971 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
4972   classify_set_interface_l2_tables_reply)                               \
4973 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
4974 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
4975 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
4976 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
4977 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
4978   l2tpv3_interface_enable_disable_reply)                                \
4979 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
4980 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
4981 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
4982 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
4983 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
4984 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
4985 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
4986 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
4987 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4988 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
4989 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
4990 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
4991 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
4992 _(SHOW_VERSION_REPLY, show_version_reply)                               \
4993 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
4994 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
4995 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
4996 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
4997 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
4998 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
4999 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5000 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5001 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5002 _(L2_MACS_EVENT, l2_macs_event)                                         \
5003 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5004 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5005 _(IP_DETAILS, ip_details)                                               \
5006 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5007 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5008 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5009 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5010 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5011 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5012 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5013 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5014 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5015 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5016 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5017 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5018 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5019 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5020 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5021 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5022 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5023 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5024 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5025 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5026 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5027 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5028 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
5029 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
5030 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
5031 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
5032 _(MAP_RULE_DETAILS, map_rule_details)                                   \
5033 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5034 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5035 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5036 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5037 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5038 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5039 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5040 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5041 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5042 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5043 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5044 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5045 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5046 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5047 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5048 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5049 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5050 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5051   one_map_register_enable_disable_reply)                                \
5052 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5053 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5054   one_map_register_fallback_threshold_reply)                            \
5055 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5056   one_rloc_probe_enable_disable_reply)                                  \
5057 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5058 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5059 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5060 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5061 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5062 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5063 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5064 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5065 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5066 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5067 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5068 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5069 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5070 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5071 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5072 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5073   show_one_stats_enable_disable_reply)                                  \
5074 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5075 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5076 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5077 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5078 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5079 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5080 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5081 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5082 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5083 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5084 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5085 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5086 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5087 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5088 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5089   gpe_add_del_native_fwd_rpath_reply)                                   \
5090 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5091   gpe_fwd_entry_path_details)                                           \
5092 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5093 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5094   one_add_del_map_request_itr_rlocs_reply)                              \
5095 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5096   one_get_map_request_itr_rlocs_reply)                                  \
5097 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5098 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5099 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5100 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5101 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5102 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5103   show_one_map_register_state_reply)                                    \
5104 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5105 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5106   show_one_map_register_fallback_threshold_reply)                       \
5107 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5108 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5109 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5110 _(POLICER_DETAILS, policer_details)                                     \
5111 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5112 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5113 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5114 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5115 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5116 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5117 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5118 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5119 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5120 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5121 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5122 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5123 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5124 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5125 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5126 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5127 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5128 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5129 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5130 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5131 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5132 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5133 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5134 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5135 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5136  ip_source_and_port_range_check_add_del_reply)                          \
5137 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5138  ip_source_and_port_range_check_interface_add_del_reply)                \
5139 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5140 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5141 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5142 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5143 _(PUNT_REPLY, punt_reply)                                               \
5144 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5145 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5146 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5147 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5148 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5149 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5150 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5151 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5152 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5153 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5154 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5155 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5156 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply)
5157
5158 #define foreach_standalone_reply_msg                                    \
5159 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5160 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5161 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5162 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5163 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5164 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5165 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
5166
5167 typedef struct
5168 {
5169   u8 *name;
5170   u32 value;
5171 } name_sort_t;
5172
5173
5174 #define STR_VTR_OP_CASE(op)     \
5175     case L2_VTR_ ## op:         \
5176         return "" # op;
5177
5178 static const char *
5179 str_vtr_op (u32 vtr_op)
5180 {
5181   switch (vtr_op)
5182     {
5183       STR_VTR_OP_CASE (DISABLED);
5184       STR_VTR_OP_CASE (PUSH_1);
5185       STR_VTR_OP_CASE (PUSH_2);
5186       STR_VTR_OP_CASE (POP_1);
5187       STR_VTR_OP_CASE (POP_2);
5188       STR_VTR_OP_CASE (TRANSLATE_1_1);
5189       STR_VTR_OP_CASE (TRANSLATE_1_2);
5190       STR_VTR_OP_CASE (TRANSLATE_2_1);
5191       STR_VTR_OP_CASE (TRANSLATE_2_2);
5192     }
5193
5194   return "UNKNOWN";
5195 }
5196
5197 static int
5198 dump_sub_interface_table (vat_main_t * vam)
5199 {
5200   const sw_interface_subif_t *sub = NULL;
5201
5202   if (vam->json_output)
5203     {
5204       clib_warning
5205         ("JSON output supported only for VPE API calls and dump_stats_table");
5206       return -99;
5207     }
5208
5209   print (vam->ofp,
5210          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5211          "Interface", "sw_if_index",
5212          "sub id", "dot1ad", "tags", "outer id",
5213          "inner id", "exact", "default", "outer any", "inner any");
5214
5215   vec_foreach (sub, vam->sw_if_subif_table)
5216   {
5217     print (vam->ofp,
5218            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5219            sub->interface_name,
5220            sub->sw_if_index,
5221            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5222            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5223            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5224            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5225     if (sub->vtr_op != L2_VTR_DISABLED)
5226       {
5227         print (vam->ofp,
5228                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5229                "tag1: %d tag2: %d ]",
5230                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5231                sub->vtr_tag1, sub->vtr_tag2);
5232       }
5233   }
5234
5235   return 0;
5236 }
5237
5238 static int
5239 name_sort_cmp (void *a1, void *a2)
5240 {
5241   name_sort_t *n1 = a1;
5242   name_sort_t *n2 = a2;
5243
5244   return strcmp ((char *) n1->name, (char *) n2->name);
5245 }
5246
5247 static int
5248 dump_interface_table (vat_main_t * vam)
5249 {
5250   hash_pair_t *p;
5251   name_sort_t *nses = 0, *ns;
5252
5253   if (vam->json_output)
5254     {
5255       clib_warning
5256         ("JSON output supported only for VPE API calls and dump_stats_table");
5257       return -99;
5258     }
5259
5260   /* *INDENT-OFF* */
5261   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5262   ({
5263     vec_add2 (nses, ns, 1);
5264     ns->name = (u8 *)(p->key);
5265     ns->value = (u32) p->value[0];
5266   }));
5267   /* *INDENT-ON* */
5268
5269   vec_sort_with_function (nses, name_sort_cmp);
5270
5271   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5272   vec_foreach (ns, nses)
5273   {
5274     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5275   }
5276   vec_free (nses);
5277   return 0;
5278 }
5279
5280 static int
5281 dump_ip_table (vat_main_t * vam, int is_ipv6)
5282 {
5283   const ip_details_t *det = NULL;
5284   const ip_address_details_t *address = NULL;
5285   u32 i = ~0;
5286
5287   print (vam->ofp, "%-12s", "sw_if_index");
5288
5289   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5290   {
5291     i++;
5292     if (!det->present)
5293       {
5294         continue;
5295       }
5296     print (vam->ofp, "%-12d", i);
5297     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5298     if (!det->addr)
5299       {
5300         continue;
5301       }
5302     vec_foreach (address, det->addr)
5303     {
5304       print (vam->ofp,
5305              "            %-30U%-13d",
5306              is_ipv6 ? format_ip6_address : format_ip4_address,
5307              address->ip, address->prefix_length);
5308     }
5309   }
5310
5311   return 0;
5312 }
5313
5314 static int
5315 dump_ipv4_table (vat_main_t * vam)
5316 {
5317   if (vam->json_output)
5318     {
5319       clib_warning
5320         ("JSON output supported only for VPE API calls and dump_stats_table");
5321       return -99;
5322     }
5323
5324   return dump_ip_table (vam, 0);
5325 }
5326
5327 static int
5328 dump_ipv6_table (vat_main_t * vam)
5329 {
5330   if (vam->json_output)
5331     {
5332       clib_warning
5333         ("JSON output supported only for VPE API calls and dump_stats_table");
5334       return -99;
5335     }
5336
5337   return dump_ip_table (vam, 1);
5338 }
5339
5340 static char *
5341 counter_type_to_str (u8 counter_type, u8 is_combined)
5342 {
5343   if (!is_combined)
5344     {
5345       switch (counter_type)
5346         {
5347         case VNET_INTERFACE_COUNTER_DROP:
5348           return "drop";
5349         case VNET_INTERFACE_COUNTER_PUNT:
5350           return "punt";
5351         case VNET_INTERFACE_COUNTER_IP4:
5352           return "ip4";
5353         case VNET_INTERFACE_COUNTER_IP6:
5354           return "ip6";
5355         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
5356           return "rx-no-buf";
5357         case VNET_INTERFACE_COUNTER_RX_MISS:
5358           return "rx-miss";
5359         case VNET_INTERFACE_COUNTER_RX_ERROR:
5360           return "rx-error";
5361         case VNET_INTERFACE_COUNTER_TX_ERROR:
5362           return "tx-error";
5363         default:
5364           return "INVALID-COUNTER-TYPE";
5365         }
5366     }
5367   else
5368     {
5369       switch (counter_type)
5370         {
5371         case VNET_INTERFACE_COUNTER_RX:
5372           return "rx";
5373         case VNET_INTERFACE_COUNTER_TX:
5374           return "tx";
5375         default:
5376           return "INVALID-COUNTER-TYPE";
5377         }
5378     }
5379 }
5380
5381 static int
5382 dump_stats_table (vat_main_t * vam)
5383 {
5384   vat_json_node_t node;
5385   vat_json_node_t *msg_array;
5386   vat_json_node_t *msg;
5387   vat_json_node_t *counter_array;
5388   vat_json_node_t *counter;
5389   interface_counter_t c;
5390   u64 packets;
5391   ip4_fib_counter_t *c4;
5392   ip6_fib_counter_t *c6;
5393   ip4_nbr_counter_t *n4;
5394   ip6_nbr_counter_t *n6;
5395   int i, j;
5396
5397   if (!vam->json_output)
5398     {
5399       clib_warning ("dump_stats_table supported only in JSON format");
5400       return -99;
5401     }
5402
5403   vat_json_init_object (&node);
5404
5405   /* interface counters */
5406   msg_array = vat_json_object_add (&node, "interface_counters");
5407   vat_json_init_array (msg_array);
5408   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
5409     {
5410       msg = vat_json_array_add (msg_array);
5411       vat_json_init_object (msg);
5412       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5413                                        (u8 *) counter_type_to_str (i, 0));
5414       vat_json_object_add_int (msg, "is_combined", 0);
5415       counter_array = vat_json_object_add (msg, "data");
5416       vat_json_init_array (counter_array);
5417       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
5418         {
5419           packets = vam->simple_interface_counters[i][j];
5420           vat_json_array_add_uint (counter_array, packets);
5421         }
5422     }
5423   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
5424     {
5425       msg = vat_json_array_add (msg_array);
5426       vat_json_init_object (msg);
5427       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5428                                        (u8 *) counter_type_to_str (i, 1));
5429       vat_json_object_add_int (msg, "is_combined", 1);
5430       counter_array = vat_json_object_add (msg, "data");
5431       vat_json_init_array (counter_array);
5432       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
5433         {
5434           c = vam->combined_interface_counters[i][j];
5435           counter = vat_json_array_add (counter_array);
5436           vat_json_init_object (counter);
5437           vat_json_object_add_uint (counter, "packets", c.packets);
5438           vat_json_object_add_uint (counter, "bytes", c.bytes);
5439         }
5440     }
5441
5442   /* ip4 fib counters */
5443   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
5444   vat_json_init_array (msg_array);
5445   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
5446     {
5447       msg = vat_json_array_add (msg_array);
5448       vat_json_init_object (msg);
5449       vat_json_object_add_uint (msg, "vrf_id",
5450                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
5451       counter_array = vat_json_object_add (msg, "c");
5452       vat_json_init_array (counter_array);
5453       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
5454         {
5455           counter = vat_json_array_add (counter_array);
5456           vat_json_init_object (counter);
5457           c4 = &vam->ip4_fib_counters[i][j];
5458           vat_json_object_add_ip4 (counter, "address", c4->address);
5459           vat_json_object_add_uint (counter, "address_length",
5460                                     c4->address_length);
5461           vat_json_object_add_uint (counter, "packets", c4->packets);
5462           vat_json_object_add_uint (counter, "bytes", c4->bytes);
5463         }
5464     }
5465
5466   /* ip6 fib counters */
5467   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
5468   vat_json_init_array (msg_array);
5469   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
5470     {
5471       msg = vat_json_array_add (msg_array);
5472       vat_json_init_object (msg);
5473       vat_json_object_add_uint (msg, "vrf_id",
5474                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
5475       counter_array = vat_json_object_add (msg, "c");
5476       vat_json_init_array (counter_array);
5477       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
5478         {
5479           counter = vat_json_array_add (counter_array);
5480           vat_json_init_object (counter);
5481           c6 = &vam->ip6_fib_counters[i][j];
5482           vat_json_object_add_ip6 (counter, "address", c6->address);
5483           vat_json_object_add_uint (counter, "address_length",
5484                                     c6->address_length);
5485           vat_json_object_add_uint (counter, "packets", c6->packets);
5486           vat_json_object_add_uint (counter, "bytes", c6->bytes);
5487         }
5488     }
5489
5490   /* ip4 nbr counters */
5491   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
5492   vat_json_init_array (msg_array);
5493   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
5494     {
5495       msg = vat_json_array_add (msg_array);
5496       vat_json_init_object (msg);
5497       vat_json_object_add_uint (msg, "sw_if_index", i);
5498       counter_array = vat_json_object_add (msg, "c");
5499       vat_json_init_array (counter_array);
5500       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
5501         {
5502           counter = vat_json_array_add (counter_array);
5503           vat_json_init_object (counter);
5504           n4 = &vam->ip4_nbr_counters[i][j];
5505           vat_json_object_add_ip4 (counter, "address", n4->address);
5506           vat_json_object_add_uint (counter, "link-type", n4->linkt);
5507           vat_json_object_add_uint (counter, "packets", n4->packets);
5508           vat_json_object_add_uint (counter, "bytes", n4->bytes);
5509         }
5510     }
5511
5512   /* ip6 nbr counters */
5513   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
5514   vat_json_init_array (msg_array);
5515   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
5516     {
5517       msg = vat_json_array_add (msg_array);
5518       vat_json_init_object (msg);
5519       vat_json_object_add_uint (msg, "sw_if_index", i);
5520       counter_array = vat_json_object_add (msg, "c");
5521       vat_json_init_array (counter_array);
5522       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
5523         {
5524           counter = vat_json_array_add (counter_array);
5525           vat_json_init_object (counter);
5526           n6 = &vam->ip6_nbr_counters[i][j];
5527           vat_json_object_add_ip6 (counter, "address", n6->address);
5528           vat_json_object_add_uint (counter, "packets", n6->packets);
5529           vat_json_object_add_uint (counter, "bytes", n6->bytes);
5530         }
5531     }
5532
5533   vat_json_print (vam->ofp, &node);
5534   vat_json_free (&node);
5535
5536   return 0;
5537 }
5538
5539 int
5540 exec (vat_main_t * vam)
5541 {
5542   api_main_t *am = &api_main;
5543   vl_api_cli_t *mp;
5544   f64 timeout;
5545   void *oldheap;
5546   u8 *cmd = 0;
5547   unformat_input_t *i = vam->input;
5548
5549   if (vec_len (i->buffer) == 0)
5550     return -1;
5551
5552   if (vam->exec_mode == 0 && unformat (i, "mode"))
5553     {
5554       vam->exec_mode = 1;
5555       return 0;
5556     }
5557   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5558     {
5559       vam->exec_mode = 0;
5560       return 0;
5561     }
5562
5563
5564   M (CLI, mp);
5565
5566   /*
5567    * Copy cmd into shared memory.
5568    * In order for the CLI command to work, it
5569    * must be a vector ending in \n, not a C-string ending
5570    * in \n\0.
5571    */
5572   pthread_mutex_lock (&am->vlib_rp->mutex);
5573   oldheap = svm_push_data_heap (am->vlib_rp);
5574
5575   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
5576   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
5577
5578   svm_pop_heap (oldheap);
5579   pthread_mutex_unlock (&am->vlib_rp->mutex);
5580
5581   mp->cmd_in_shmem = pointer_to_uword (cmd);
5582   S (mp);
5583   timeout = vat_time_now (vam) + 10.0;
5584
5585   while (vat_time_now (vam) < timeout)
5586     {
5587       if (vam->result_ready == 1)
5588         {
5589           u8 *free_me;
5590           if (vam->shmem_result != NULL)
5591             print (vam->ofp, "%s", vam->shmem_result);
5592           pthread_mutex_lock (&am->vlib_rp->mutex);
5593           oldheap = svm_push_data_heap (am->vlib_rp);
5594
5595           free_me = (u8 *) vam->shmem_result;
5596           vec_free (free_me);
5597
5598           svm_pop_heap (oldheap);
5599           pthread_mutex_unlock (&am->vlib_rp->mutex);
5600           return 0;
5601         }
5602     }
5603   return -99;
5604 }
5605
5606 /*
5607  * Future replacement of exec() that passes CLI buffers directly in
5608  * the API messages instead of an additional shared memory area.
5609  */
5610 static int
5611 exec_inband (vat_main_t * vam)
5612 {
5613   vl_api_cli_inband_t *mp;
5614   unformat_input_t *i = vam->input;
5615   int ret;
5616
5617   if (vec_len (i->buffer) == 0)
5618     return -1;
5619
5620   if (vam->exec_mode == 0 && unformat (i, "mode"))
5621     {
5622       vam->exec_mode = 1;
5623       return 0;
5624     }
5625   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5626     {
5627       vam->exec_mode = 0;
5628       return 0;
5629     }
5630
5631   /*
5632    * In order for the CLI command to work, it
5633    * must be a vector ending in \n, not a C-string ending
5634    * in \n\0.
5635    */
5636   u32 len = vec_len (vam->input->buffer);
5637   M2 (CLI_INBAND, mp, len);
5638   clib_memcpy (mp->cmd, vam->input->buffer, len);
5639   mp->length = htonl (len);
5640
5641   S (mp);
5642   W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
5643   return ret;
5644 }
5645
5646 static int
5647 api_create_loopback (vat_main_t * vam)
5648 {
5649   unformat_input_t *i = vam->input;
5650   vl_api_create_loopback_t *mp;
5651   vl_api_create_loopback_instance_t *mp_lbi;
5652   u8 mac_address[6];
5653   u8 mac_set = 0;
5654   u8 is_specified = 0;
5655   u32 user_instance = 0;
5656   int ret;
5657
5658   memset (mac_address, 0, sizeof (mac_address));
5659
5660   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5661     {
5662       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5663         mac_set = 1;
5664       if (unformat (i, "instance %d", &user_instance))
5665         is_specified = 1;
5666       else
5667         break;
5668     }
5669
5670   if (is_specified)
5671     {
5672       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5673       mp_lbi->is_specified = is_specified;
5674       if (is_specified)
5675         mp_lbi->user_instance = htonl (user_instance);
5676       if (mac_set)
5677         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5678       S (mp_lbi);
5679     }
5680   else
5681     {
5682       /* Construct the API message */
5683       M (CREATE_LOOPBACK, mp);
5684       if (mac_set)
5685         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5686       S (mp);
5687     }
5688
5689   W (ret);
5690   return ret;
5691 }
5692
5693 static int
5694 api_delete_loopback (vat_main_t * vam)
5695 {
5696   unformat_input_t *i = vam->input;
5697   vl_api_delete_loopback_t *mp;
5698   u32 sw_if_index = ~0;
5699   int ret;
5700
5701   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5702     {
5703       if (unformat (i, "sw_if_index %d", &sw_if_index))
5704         ;
5705       else
5706         break;
5707     }
5708
5709   if (sw_if_index == ~0)
5710     {
5711       errmsg ("missing sw_if_index");
5712       return -99;
5713     }
5714
5715   /* Construct the API message */
5716   M (DELETE_LOOPBACK, mp);
5717   mp->sw_if_index = ntohl (sw_if_index);
5718
5719   S (mp);
5720   W (ret);
5721   return ret;
5722 }
5723
5724 static int
5725 api_want_stats (vat_main_t * vam)
5726 {
5727   unformat_input_t *i = vam->input;
5728   vl_api_want_stats_t *mp;
5729   int enable = -1;
5730   int ret;
5731
5732   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5733     {
5734       if (unformat (i, "enable"))
5735         enable = 1;
5736       else if (unformat (i, "disable"))
5737         enable = 0;
5738       else
5739         break;
5740     }
5741
5742   if (enable == -1)
5743     {
5744       errmsg ("missing enable|disable");
5745       return -99;
5746     }
5747
5748   M (WANT_STATS, mp);
5749   mp->enable_disable = enable;
5750
5751   S (mp);
5752   W (ret);
5753   return ret;
5754 }
5755
5756 static int
5757 api_want_interface_events (vat_main_t * vam)
5758 {
5759   unformat_input_t *i = vam->input;
5760   vl_api_want_interface_events_t *mp;
5761   int enable = -1;
5762   int ret;
5763
5764   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5765     {
5766       if (unformat (i, "enable"))
5767         enable = 1;
5768       else if (unformat (i, "disable"))
5769         enable = 0;
5770       else
5771         break;
5772     }
5773
5774   if (enable == -1)
5775     {
5776       errmsg ("missing enable|disable");
5777       return -99;
5778     }
5779
5780   M (WANT_INTERFACE_EVENTS, mp);
5781   mp->enable_disable = enable;
5782
5783   vam->interface_event_display = enable;
5784
5785   S (mp);
5786   W (ret);
5787   return ret;
5788 }
5789
5790
5791 /* Note: non-static, called once to set up the initial intfc table */
5792 int
5793 api_sw_interface_dump (vat_main_t * vam)
5794 {
5795   vl_api_sw_interface_dump_t *mp;
5796   vl_api_control_ping_t *mp_ping;
5797   hash_pair_t *p;
5798   name_sort_t *nses = 0, *ns;
5799   sw_interface_subif_t *sub = NULL;
5800   int ret;
5801
5802   /* Toss the old name table */
5803   /* *INDENT-OFF* */
5804   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5805   ({
5806     vec_add2 (nses, ns, 1);
5807     ns->name = (u8 *)(p->key);
5808     ns->value = (u32) p->value[0];
5809   }));
5810   /* *INDENT-ON* */
5811
5812   hash_free (vam->sw_if_index_by_interface_name);
5813
5814   vec_foreach (ns, nses) vec_free (ns->name);
5815
5816   vec_free (nses);
5817
5818   vec_foreach (sub, vam->sw_if_subif_table)
5819   {
5820     vec_free (sub->interface_name);
5821   }
5822   vec_free (vam->sw_if_subif_table);
5823
5824   /* recreate the interface name hash table */
5825   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5826
5827   /* Get list of ethernets */
5828   M (SW_INTERFACE_DUMP, mp);
5829   mp->name_filter_valid = 1;
5830   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
5831   S (mp);
5832
5833   /* and local / loopback interfaces */
5834   M (SW_INTERFACE_DUMP, mp);
5835   mp->name_filter_valid = 1;
5836   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
5837   S (mp);
5838
5839   /* and packet-generator interfaces */
5840   M (SW_INTERFACE_DUMP, mp);
5841   mp->name_filter_valid = 1;
5842   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
5843   S (mp);
5844
5845   /* and vxlan-gpe tunnel interfaces */
5846   M (SW_INTERFACE_DUMP, mp);
5847   mp->name_filter_valid = 1;
5848   strncpy ((char *) mp->name_filter, "vxlan_gpe",
5849            sizeof (mp->name_filter) - 1);
5850   S (mp);
5851
5852   /* and vxlan tunnel interfaces */
5853   M (SW_INTERFACE_DUMP, mp);
5854   mp->name_filter_valid = 1;
5855   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
5856   S (mp);
5857
5858   /* and host (af_packet) interfaces */
5859   M (SW_INTERFACE_DUMP, mp);
5860   mp->name_filter_valid = 1;
5861   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
5862   S (mp);
5863
5864   /* and l2tpv3 tunnel interfaces */
5865   M (SW_INTERFACE_DUMP, mp);
5866   mp->name_filter_valid = 1;
5867   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
5868            sizeof (mp->name_filter) - 1);
5869   S (mp);
5870
5871   /* and GRE tunnel interfaces */
5872   M (SW_INTERFACE_DUMP, mp);
5873   mp->name_filter_valid = 1;
5874   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
5875   S (mp);
5876
5877   /* and LISP-GPE interfaces */
5878   M (SW_INTERFACE_DUMP, mp);
5879   mp->name_filter_valid = 1;
5880   strncpy ((char *) mp->name_filter, "lisp_gpe",
5881            sizeof (mp->name_filter) - 1);
5882   S (mp);
5883
5884   /* and IPSEC tunnel interfaces */
5885   M (SW_INTERFACE_DUMP, mp);
5886   mp->name_filter_valid = 1;
5887   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
5888   S (mp);
5889
5890   /* Use a control ping for synchronization */
5891   M (CONTROL_PING, mp_ping);
5892   S (mp_ping);
5893
5894   W (ret);
5895   return ret;
5896 }
5897
5898 static int
5899 api_sw_interface_set_flags (vat_main_t * vam)
5900 {
5901   unformat_input_t *i = vam->input;
5902   vl_api_sw_interface_set_flags_t *mp;
5903   u32 sw_if_index;
5904   u8 sw_if_index_set = 0;
5905   u8 admin_up = 0;
5906   int ret;
5907
5908   /* Parse args required to build the message */
5909   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5910     {
5911       if (unformat (i, "admin-up"))
5912         admin_up = 1;
5913       else if (unformat (i, "admin-down"))
5914         admin_up = 0;
5915       else
5916         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5917         sw_if_index_set = 1;
5918       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5919         sw_if_index_set = 1;
5920       else
5921         break;
5922     }
5923
5924   if (sw_if_index_set == 0)
5925     {
5926       errmsg ("missing interface name or sw_if_index");
5927       return -99;
5928     }
5929
5930   /* Construct the API message */
5931   M (SW_INTERFACE_SET_FLAGS, mp);
5932   mp->sw_if_index = ntohl (sw_if_index);
5933   mp->admin_up_down = admin_up;
5934
5935   /* send it... */
5936   S (mp);
5937
5938   /* Wait for a reply, return the good/bad news... */
5939   W (ret);
5940   return ret;
5941 }
5942
5943 static int
5944 api_sw_interface_clear_stats (vat_main_t * vam)
5945 {
5946   unformat_input_t *i = vam->input;
5947   vl_api_sw_interface_clear_stats_t *mp;
5948   u32 sw_if_index;
5949   u8 sw_if_index_set = 0;
5950   int ret;
5951
5952   /* Parse args required to build the message */
5953   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5954     {
5955       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5956         sw_if_index_set = 1;
5957       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5958         sw_if_index_set = 1;
5959       else
5960         break;
5961     }
5962
5963   /* Construct the API message */
5964   M (SW_INTERFACE_CLEAR_STATS, mp);
5965
5966   if (sw_if_index_set == 1)
5967     mp->sw_if_index = ntohl (sw_if_index);
5968   else
5969     mp->sw_if_index = ~0;
5970
5971   /* send it... */
5972   S (mp);
5973
5974   /* Wait for a reply, return the good/bad news... */
5975   W (ret);
5976   return ret;
5977 }
5978
5979 static int
5980 api_sw_interface_add_del_address (vat_main_t * vam)
5981 {
5982   unformat_input_t *i = vam->input;
5983   vl_api_sw_interface_add_del_address_t *mp;
5984   u32 sw_if_index;
5985   u8 sw_if_index_set = 0;
5986   u8 is_add = 1, del_all = 0;
5987   u32 address_length = 0;
5988   u8 v4_address_set = 0;
5989   u8 v6_address_set = 0;
5990   ip4_address_t v4address;
5991   ip6_address_t v6address;
5992   int ret;
5993
5994   /* Parse args required to build the message */
5995   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5996     {
5997       if (unformat (i, "del-all"))
5998         del_all = 1;
5999       else if (unformat (i, "del"))
6000         is_add = 0;
6001       else
6002         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6003         sw_if_index_set = 1;
6004       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6005         sw_if_index_set = 1;
6006       else if (unformat (i, "%U/%d",
6007                          unformat_ip4_address, &v4address, &address_length))
6008         v4_address_set = 1;
6009       else if (unformat (i, "%U/%d",
6010                          unformat_ip6_address, &v6address, &address_length))
6011         v6_address_set = 1;
6012       else
6013         break;
6014     }
6015
6016   if (sw_if_index_set == 0)
6017     {
6018       errmsg ("missing interface name or sw_if_index");
6019       return -99;
6020     }
6021   if (v4_address_set && v6_address_set)
6022     {
6023       errmsg ("both v4 and v6 addresses set");
6024       return -99;
6025     }
6026   if (!v4_address_set && !v6_address_set && !del_all)
6027     {
6028       errmsg ("no addresses set");
6029       return -99;
6030     }
6031
6032   /* Construct the API message */
6033   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6034
6035   mp->sw_if_index = ntohl (sw_if_index);
6036   mp->is_add = is_add;
6037   mp->del_all = del_all;
6038   if (v6_address_set)
6039     {
6040       mp->is_ipv6 = 1;
6041       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6042     }
6043   else
6044     {
6045       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6046     }
6047   mp->address_length = address_length;
6048
6049   /* send it... */
6050   S (mp);
6051
6052   /* Wait for a reply, return good/bad news  */
6053   W (ret);
6054   return ret;
6055 }
6056
6057 static int
6058 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6059 {
6060   unformat_input_t *i = vam->input;
6061   vl_api_sw_interface_set_mpls_enable_t *mp;
6062   u32 sw_if_index;
6063   u8 sw_if_index_set = 0;
6064   u8 enable = 1;
6065   int ret;
6066
6067   /* Parse args required to build the message */
6068   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6069     {
6070       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6071         sw_if_index_set = 1;
6072       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6073         sw_if_index_set = 1;
6074       else if (unformat (i, "disable"))
6075         enable = 0;
6076       else if (unformat (i, "dis"))
6077         enable = 0;
6078       else
6079         break;
6080     }
6081
6082   if (sw_if_index_set == 0)
6083     {
6084       errmsg ("missing interface name or sw_if_index");
6085       return -99;
6086     }
6087
6088   /* Construct the API message */
6089   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6090
6091   mp->sw_if_index = ntohl (sw_if_index);
6092   mp->enable = enable;
6093
6094   /* send it... */
6095   S (mp);
6096
6097   /* Wait for a reply... */
6098   W (ret);
6099   return ret;
6100 }
6101
6102 static int
6103 api_sw_interface_set_table (vat_main_t * vam)
6104 {
6105   unformat_input_t *i = vam->input;
6106   vl_api_sw_interface_set_table_t *mp;
6107   u32 sw_if_index, vrf_id = 0;
6108   u8 sw_if_index_set = 0;
6109   u8 is_ipv6 = 0;
6110   int ret;
6111
6112   /* Parse args required to build the message */
6113   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6114     {
6115       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6116         sw_if_index_set = 1;
6117       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6118         sw_if_index_set = 1;
6119       else if (unformat (i, "vrf %d", &vrf_id))
6120         ;
6121       else if (unformat (i, "ipv6"))
6122         is_ipv6 = 1;
6123       else
6124         break;
6125     }
6126
6127   if (sw_if_index_set == 0)
6128     {
6129       errmsg ("missing interface name or sw_if_index");
6130       return -99;
6131     }
6132
6133   /* Construct the API message */
6134   M (SW_INTERFACE_SET_TABLE, mp);
6135
6136   mp->sw_if_index = ntohl (sw_if_index);
6137   mp->is_ipv6 = is_ipv6;
6138   mp->vrf_id = ntohl (vrf_id);
6139
6140   /* send it... */
6141   S (mp);
6142
6143   /* Wait for a reply... */
6144   W (ret);
6145   return ret;
6146 }
6147
6148 static void vl_api_sw_interface_get_table_reply_t_handler
6149   (vl_api_sw_interface_get_table_reply_t * mp)
6150 {
6151   vat_main_t *vam = &vat_main;
6152
6153   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6154
6155   vam->retval = ntohl (mp->retval);
6156   vam->result_ready = 1;
6157
6158 }
6159
6160 static void vl_api_sw_interface_get_table_reply_t_handler_json
6161   (vl_api_sw_interface_get_table_reply_t * mp)
6162 {
6163   vat_main_t *vam = &vat_main;
6164   vat_json_node_t node;
6165
6166   vat_json_init_object (&node);
6167   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6168   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6169
6170   vat_json_print (vam->ofp, &node);
6171   vat_json_free (&node);
6172
6173   vam->retval = ntohl (mp->retval);
6174   vam->result_ready = 1;
6175 }
6176
6177 static int
6178 api_sw_interface_get_table (vat_main_t * vam)
6179 {
6180   unformat_input_t *i = vam->input;
6181   vl_api_sw_interface_get_table_t *mp;
6182   u32 sw_if_index;
6183   u8 sw_if_index_set = 0;
6184   u8 is_ipv6 = 0;
6185   int ret;
6186
6187   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6188     {
6189       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6190         sw_if_index_set = 1;
6191       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6192         sw_if_index_set = 1;
6193       else if (unformat (i, "ipv6"))
6194         is_ipv6 = 1;
6195       else
6196         break;
6197     }
6198
6199   if (sw_if_index_set == 0)
6200     {
6201       errmsg ("missing interface name or sw_if_index");
6202       return -99;
6203     }
6204
6205   M (SW_INTERFACE_GET_TABLE, mp);
6206   mp->sw_if_index = htonl (sw_if_index);
6207   mp->is_ipv6 = is_ipv6;
6208
6209   S (mp);
6210   W (ret);
6211   return ret;
6212 }
6213
6214 static int
6215 api_sw_interface_set_vpath (vat_main_t * vam)
6216 {
6217   unformat_input_t *i = vam->input;
6218   vl_api_sw_interface_set_vpath_t *mp;
6219   u32 sw_if_index = 0;
6220   u8 sw_if_index_set = 0;
6221   u8 is_enable = 0;
6222   int ret;
6223
6224   /* Parse args required to build the message */
6225   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6226     {
6227       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6228         sw_if_index_set = 1;
6229       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6230         sw_if_index_set = 1;
6231       else if (unformat (i, "enable"))
6232         is_enable = 1;
6233       else if (unformat (i, "disable"))
6234         is_enable = 0;
6235       else
6236         break;
6237     }
6238
6239   if (sw_if_index_set == 0)
6240     {
6241       errmsg ("missing interface name or sw_if_index");
6242       return -99;
6243     }
6244
6245   /* Construct the API message */
6246   M (SW_INTERFACE_SET_VPATH, mp);
6247
6248   mp->sw_if_index = ntohl (sw_if_index);
6249   mp->enable = is_enable;
6250
6251   /* send it... */
6252   S (mp);
6253
6254   /* Wait for a reply... */
6255   W (ret);
6256   return ret;
6257 }
6258
6259 static int
6260 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6261 {
6262   unformat_input_t *i = vam->input;
6263   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6264   u32 sw_if_index = 0;
6265   u8 sw_if_index_set = 0;
6266   u8 is_enable = 1;
6267   u8 is_ipv6 = 0;
6268   int ret;
6269
6270   /* Parse args required to build the message */
6271   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6272     {
6273       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6274         sw_if_index_set = 1;
6275       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6276         sw_if_index_set = 1;
6277       else if (unformat (i, "enable"))
6278         is_enable = 1;
6279       else if (unformat (i, "disable"))
6280         is_enable = 0;
6281       else if (unformat (i, "ip4"))
6282         is_ipv6 = 0;
6283       else if (unformat (i, "ip6"))
6284         is_ipv6 = 1;
6285       else
6286         break;
6287     }
6288
6289   if (sw_if_index_set == 0)
6290     {
6291       errmsg ("missing interface name or sw_if_index");
6292       return -99;
6293     }
6294
6295   /* Construct the API message */
6296   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6297
6298   mp->sw_if_index = ntohl (sw_if_index);
6299   mp->enable = is_enable;
6300   mp->is_ipv6 = is_ipv6;
6301
6302   /* send it... */
6303   S (mp);
6304
6305   /* Wait for a reply... */
6306   W (ret);
6307   return ret;
6308 }
6309
6310
6311 static int
6312 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6313 {
6314   unformat_input_t *i = vam->input;
6315   vl_api_sw_interface_set_l2_xconnect_t *mp;
6316   u32 rx_sw_if_index;
6317   u8 rx_sw_if_index_set = 0;
6318   u32 tx_sw_if_index;
6319   u8 tx_sw_if_index_set = 0;
6320   u8 enable = 1;
6321   int ret;
6322
6323   /* Parse args required to build the message */
6324   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6325     {
6326       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6327         rx_sw_if_index_set = 1;
6328       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6329         tx_sw_if_index_set = 1;
6330       else if (unformat (i, "rx"))
6331         {
6332           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6333             {
6334               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6335                             &rx_sw_if_index))
6336                 rx_sw_if_index_set = 1;
6337             }
6338           else
6339             break;
6340         }
6341       else if (unformat (i, "tx"))
6342         {
6343           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6344             {
6345               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6346                             &tx_sw_if_index))
6347                 tx_sw_if_index_set = 1;
6348             }
6349           else
6350             break;
6351         }
6352       else if (unformat (i, "enable"))
6353         enable = 1;
6354       else if (unformat (i, "disable"))
6355         enable = 0;
6356       else
6357         break;
6358     }
6359
6360   if (rx_sw_if_index_set == 0)
6361     {
6362       errmsg ("missing rx interface name or rx_sw_if_index");
6363       return -99;
6364     }
6365
6366   if (enable && (tx_sw_if_index_set == 0))
6367     {
6368       errmsg ("missing tx interface name or tx_sw_if_index");
6369       return -99;
6370     }
6371
6372   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6373
6374   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6375   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6376   mp->enable = enable;
6377
6378   S (mp);
6379   W (ret);
6380   return ret;
6381 }
6382
6383 static int
6384 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6385 {
6386   unformat_input_t *i = vam->input;
6387   vl_api_sw_interface_set_l2_bridge_t *mp;
6388   u32 rx_sw_if_index;
6389   u8 rx_sw_if_index_set = 0;
6390   u32 bd_id;
6391   u8 bd_id_set = 0;
6392   u8 bvi = 0;
6393   u32 shg = 0;
6394   u8 enable = 1;
6395   int ret;
6396
6397   /* Parse args required to build the message */
6398   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6399     {
6400       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6401         rx_sw_if_index_set = 1;
6402       else if (unformat (i, "bd_id %d", &bd_id))
6403         bd_id_set = 1;
6404       else
6405         if (unformat
6406             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6407         rx_sw_if_index_set = 1;
6408       else if (unformat (i, "shg %d", &shg))
6409         ;
6410       else if (unformat (i, "bvi"))
6411         bvi = 1;
6412       else if (unformat (i, "enable"))
6413         enable = 1;
6414       else if (unformat (i, "disable"))
6415         enable = 0;
6416       else
6417         break;
6418     }
6419
6420   if (rx_sw_if_index_set == 0)
6421     {
6422       errmsg ("missing rx interface name or sw_if_index");
6423       return -99;
6424     }
6425
6426   if (enable && (bd_id_set == 0))
6427     {
6428       errmsg ("missing bridge domain");
6429       return -99;
6430     }
6431
6432   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6433
6434   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6435   mp->bd_id = ntohl (bd_id);
6436   mp->shg = (u8) shg;
6437   mp->bvi = bvi;
6438   mp->enable = enable;
6439
6440   S (mp);
6441   W (ret);
6442   return ret;
6443 }
6444
6445 static int
6446 api_bridge_domain_dump (vat_main_t * vam)
6447 {
6448   unformat_input_t *i = vam->input;
6449   vl_api_bridge_domain_dump_t *mp;
6450   vl_api_control_ping_t *mp_ping;
6451   u32 bd_id = ~0;
6452   int ret;
6453
6454   /* Parse args required to build the message */
6455   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6456     {
6457       if (unformat (i, "bd_id %d", &bd_id))
6458         ;
6459       else
6460         break;
6461     }
6462
6463   M (BRIDGE_DOMAIN_DUMP, mp);
6464   mp->bd_id = ntohl (bd_id);
6465   S (mp);
6466
6467   /* Use a control ping for synchronization */
6468   M (CONTROL_PING, mp_ping);
6469   S (mp_ping);
6470
6471   W (ret);
6472   return ret;
6473 }
6474
6475 static int
6476 api_bridge_domain_add_del (vat_main_t * vam)
6477 {
6478   unformat_input_t *i = vam->input;
6479   vl_api_bridge_domain_add_del_t *mp;
6480   u32 bd_id = ~0;
6481   u8 is_add = 1;
6482   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6483   u8 *bd_tag = NULL;
6484   u32 mac_age = 0;
6485   int ret;
6486
6487   /* Parse args required to build the message */
6488   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6489     {
6490       if (unformat (i, "bd_id %d", &bd_id))
6491         ;
6492       else if (unformat (i, "flood %d", &flood))
6493         ;
6494       else if (unformat (i, "uu-flood %d", &uu_flood))
6495         ;
6496       else if (unformat (i, "forward %d", &forward))
6497         ;
6498       else if (unformat (i, "learn %d", &learn))
6499         ;
6500       else if (unformat (i, "arp-term %d", &arp_term))
6501         ;
6502       else if (unformat (i, "mac-age %d", &mac_age))
6503         ;
6504       else if (unformat (i, "bd-tag %s", &bd_tag))
6505         ;
6506       else if (unformat (i, "del"))
6507         {
6508           is_add = 0;
6509           flood = uu_flood = forward = learn = 0;
6510         }
6511       else
6512         break;
6513     }
6514
6515   if (bd_id == ~0)
6516     {
6517       errmsg ("missing bridge domain");
6518       ret = -99;
6519       goto done;
6520     }
6521
6522   if (mac_age > 255)
6523     {
6524       errmsg ("mac age must be less than 256 ");
6525       ret = -99;
6526       goto done;
6527     }
6528
6529   if ((bd_tag) && (strlen ((char *) bd_tag) > 63))
6530     {
6531       errmsg ("bd-tag cannot be longer than 63");
6532       ret = -99;
6533       goto done;
6534     }
6535
6536   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6537
6538   mp->bd_id = ntohl (bd_id);
6539   mp->flood = flood;
6540   mp->uu_flood = uu_flood;
6541   mp->forward = forward;
6542   mp->learn = learn;
6543   mp->arp_term = arp_term;
6544   mp->is_add = is_add;
6545   mp->mac_age = (u8) mac_age;
6546   if (bd_tag)
6547     strcpy ((char *) mp->bd_tag, (char *) bd_tag);
6548
6549   S (mp);
6550   W (ret);
6551
6552 done:
6553   vec_free (bd_tag);
6554   return ret;
6555 }
6556
6557 static int
6558 api_l2fib_flush_bd (vat_main_t * vam)
6559 {
6560   unformat_input_t *i = vam->input;
6561   vl_api_l2fib_flush_bd_t *mp;
6562   u32 bd_id = ~0;
6563   int ret;
6564
6565   /* Parse args required to build the message */
6566   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6567     {
6568       if (unformat (i, "bd_id %d", &bd_id));
6569       else
6570         break;
6571     }
6572
6573   if (bd_id == ~0)
6574     {
6575       errmsg ("missing bridge domain");
6576       return -99;
6577     }
6578
6579   M (L2FIB_FLUSH_BD, mp);
6580
6581   mp->bd_id = htonl (bd_id);
6582
6583   S (mp);
6584   W (ret);
6585   return ret;
6586 }
6587
6588 static int
6589 api_l2fib_flush_int (vat_main_t * vam)
6590 {
6591   unformat_input_t *i = vam->input;
6592   vl_api_l2fib_flush_int_t *mp;
6593   u32 sw_if_index = ~0;
6594   int ret;
6595
6596   /* Parse args required to build the message */
6597   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6598     {
6599       if (unformat (i, "sw_if_index %d", &sw_if_index));
6600       else
6601         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6602       else
6603         break;
6604     }
6605
6606   if (sw_if_index == ~0)
6607     {
6608       errmsg ("missing interface name or sw_if_index");
6609       return -99;
6610     }
6611
6612   M (L2FIB_FLUSH_INT, mp);
6613
6614   mp->sw_if_index = ntohl (sw_if_index);
6615
6616   S (mp);
6617   W (ret);
6618   return ret;
6619 }
6620
6621 static int
6622 api_l2fib_add_del (vat_main_t * vam)
6623 {
6624   unformat_input_t *i = vam->input;
6625   vl_api_l2fib_add_del_t *mp;
6626   f64 timeout;
6627   u64 mac = 0;
6628   u8 mac_set = 0;
6629   u32 bd_id;
6630   u8 bd_id_set = 0;
6631   u32 sw_if_index = ~0;
6632   u8 sw_if_index_set = 0;
6633   u8 is_add = 1;
6634   u8 static_mac = 0;
6635   u8 filter_mac = 0;
6636   u8 bvi_mac = 0;
6637   int count = 1;
6638   f64 before = 0;
6639   int j;
6640
6641   /* Parse args required to build the message */
6642   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6643     {
6644       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
6645         mac_set = 1;
6646       else if (unformat (i, "bd_id %d", &bd_id))
6647         bd_id_set = 1;
6648       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6649         sw_if_index_set = 1;
6650       else if (unformat (i, "sw_if"))
6651         {
6652           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6653             {
6654               if (unformat
6655                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6656                 sw_if_index_set = 1;
6657             }
6658           else
6659             break;
6660         }
6661       else if (unformat (i, "static"))
6662         static_mac = 1;
6663       else if (unformat (i, "filter"))
6664         {
6665           filter_mac = 1;
6666           static_mac = 1;
6667         }
6668       else if (unformat (i, "bvi"))
6669         {
6670           bvi_mac = 1;
6671           static_mac = 1;
6672         }
6673       else if (unformat (i, "del"))
6674         is_add = 0;
6675       else if (unformat (i, "count %d", &count))
6676         ;
6677       else
6678         break;
6679     }
6680
6681   if (mac_set == 0)
6682     {
6683       errmsg ("missing mac address");
6684       return -99;
6685     }
6686
6687   if (bd_id_set == 0)
6688     {
6689       errmsg ("missing bridge domain");
6690       return -99;
6691     }
6692
6693   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6694     {
6695       errmsg ("missing interface name or sw_if_index");
6696       return -99;
6697     }
6698
6699   if (count > 1)
6700     {
6701       /* Turn on async mode */
6702       vam->async_mode = 1;
6703       vam->async_errors = 0;
6704       before = vat_time_now (vam);
6705     }
6706
6707   for (j = 0; j < count; j++)
6708     {
6709       M (L2FIB_ADD_DEL, mp);
6710
6711       mp->mac = mac;
6712       mp->bd_id = ntohl (bd_id);
6713       mp->is_add = is_add;
6714
6715       if (is_add)
6716         {
6717           mp->sw_if_index = ntohl (sw_if_index);
6718           mp->static_mac = static_mac;
6719           mp->filter_mac = filter_mac;
6720           mp->bvi_mac = bvi_mac;
6721         }
6722       increment_mac_address (&mac);
6723       /* send it... */
6724       S (mp);
6725     }
6726
6727   if (count > 1)
6728     {
6729       vl_api_control_ping_t *mp_ping;
6730       f64 after;
6731
6732       /* Shut off async mode */
6733       vam->async_mode = 0;
6734
6735       M (CONTROL_PING, mp_ping);
6736       S (mp_ping);
6737
6738       timeout = vat_time_now (vam) + 1.0;
6739       while (vat_time_now (vam) < timeout)
6740         if (vam->result_ready == 1)
6741           goto out;
6742       vam->retval = -99;
6743
6744     out:
6745       if (vam->retval == -99)
6746         errmsg ("timeout");
6747
6748       if (vam->async_errors > 0)
6749         {
6750           errmsg ("%d asynchronous errors", vam->async_errors);
6751           vam->retval = -98;
6752         }
6753       vam->async_errors = 0;
6754       after = vat_time_now (vam);
6755
6756       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6757              count, after - before, count / (after - before));
6758     }
6759   else
6760     {
6761       int ret;
6762
6763       /* Wait for a reply... */
6764       W (ret);
6765       return ret;
6766     }
6767   /* Return the good/bad news */
6768   return (vam->retval);
6769 }
6770
6771 static int
6772 api_bridge_domain_set_mac_age (vat_main_t * vam)
6773 {
6774   unformat_input_t *i = vam->input;
6775   vl_api_bridge_domain_set_mac_age_t *mp;
6776   u32 bd_id = ~0;
6777   u32 mac_age = 0;
6778   int ret;
6779
6780   /* Parse args required to build the message */
6781   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6782     {
6783       if (unformat (i, "bd_id %d", &bd_id));
6784       else if (unformat (i, "mac-age %d", &mac_age));
6785       else
6786         break;
6787     }
6788
6789   if (bd_id == ~0)
6790     {
6791       errmsg ("missing bridge domain");
6792       return -99;
6793     }
6794
6795   if (mac_age > 255)
6796     {
6797       errmsg ("mac age must be less than 256 ");
6798       return -99;
6799     }
6800
6801   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6802
6803   mp->bd_id = htonl (bd_id);
6804   mp->mac_age = (u8) mac_age;
6805
6806   S (mp);
6807   W (ret);
6808   return ret;
6809 }
6810
6811 static int
6812 api_l2_flags (vat_main_t * vam)
6813 {
6814   unformat_input_t *i = vam->input;
6815   vl_api_l2_flags_t *mp;
6816   u32 sw_if_index;
6817   u32 flags = 0;
6818   u8 sw_if_index_set = 0;
6819   u8 is_set = 0;
6820   int ret;
6821
6822   /* Parse args required to build the message */
6823   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6824     {
6825       if (unformat (i, "sw_if_index %d", &sw_if_index))
6826         sw_if_index_set = 1;
6827       else if (unformat (i, "sw_if"))
6828         {
6829           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6830             {
6831               if (unformat
6832                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6833                 sw_if_index_set = 1;
6834             }
6835           else
6836             break;
6837         }
6838       else if (unformat (i, "learn"))
6839         flags |= L2_LEARN;
6840       else if (unformat (i, "forward"))
6841         flags |= L2_FWD;
6842       else if (unformat (i, "flood"))
6843         flags |= L2_FLOOD;
6844       else if (unformat (i, "uu-flood"))
6845         flags |= L2_UU_FLOOD;
6846       else if (unformat (i, "arp-term"))
6847         flags |= L2_ARP_TERM;
6848       else if (unformat (i, "off"))
6849         is_set = 0;
6850       else if (unformat (i, "disable"))
6851         is_set = 0;
6852       else
6853         break;
6854     }
6855
6856   if (sw_if_index_set == 0)
6857     {
6858       errmsg ("missing interface name or sw_if_index");
6859       return -99;
6860     }
6861
6862   M (L2_FLAGS, mp);
6863
6864   mp->sw_if_index = ntohl (sw_if_index);
6865   mp->feature_bitmap = ntohl (flags);
6866   mp->is_set = is_set;
6867
6868   S (mp);
6869   W (ret);
6870   return ret;
6871 }
6872
6873 static int
6874 api_bridge_flags (vat_main_t * vam)
6875 {
6876   unformat_input_t *i = vam->input;
6877   vl_api_bridge_flags_t *mp;
6878   u32 bd_id;
6879   u8 bd_id_set = 0;
6880   u8 is_set = 1;
6881   u32 flags = 0;
6882   int ret;
6883
6884   /* Parse args required to build the message */
6885   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6886     {
6887       if (unformat (i, "bd_id %d", &bd_id))
6888         bd_id_set = 1;
6889       else if (unformat (i, "learn"))
6890         flags |= L2_LEARN;
6891       else if (unformat (i, "forward"))
6892         flags |= L2_FWD;
6893       else if (unformat (i, "flood"))
6894         flags |= L2_FLOOD;
6895       else if (unformat (i, "uu-flood"))
6896         flags |= L2_UU_FLOOD;
6897       else if (unformat (i, "arp-term"))
6898         flags |= L2_ARP_TERM;
6899       else if (unformat (i, "off"))
6900         is_set = 0;
6901       else if (unformat (i, "disable"))
6902         is_set = 0;
6903       else
6904         break;
6905     }
6906
6907   if (bd_id_set == 0)
6908     {
6909       errmsg ("missing bridge domain");
6910       return -99;
6911     }
6912
6913   M (BRIDGE_FLAGS, mp);
6914
6915   mp->bd_id = ntohl (bd_id);
6916   mp->feature_bitmap = ntohl (flags);
6917   mp->is_set = is_set;
6918
6919   S (mp);
6920   W (ret);
6921   return ret;
6922 }
6923
6924 static int
6925 api_bd_ip_mac_add_del (vat_main_t * vam)
6926 {
6927   unformat_input_t *i = vam->input;
6928   vl_api_bd_ip_mac_add_del_t *mp;
6929   u32 bd_id;
6930   u8 is_ipv6 = 0;
6931   u8 is_add = 1;
6932   u8 bd_id_set = 0;
6933   u8 ip_set = 0;
6934   u8 mac_set = 0;
6935   ip4_address_t v4addr;
6936   ip6_address_t v6addr;
6937   u8 macaddr[6];
6938   int ret;
6939
6940
6941   /* Parse args required to build the message */
6942   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6943     {
6944       if (unformat (i, "bd_id %d", &bd_id))
6945         {
6946           bd_id_set++;
6947         }
6948       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
6949         {
6950           ip_set++;
6951         }
6952       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
6953         {
6954           ip_set++;
6955           is_ipv6++;
6956         }
6957       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
6958         {
6959           mac_set++;
6960         }
6961       else if (unformat (i, "del"))
6962         is_add = 0;
6963       else
6964         break;
6965     }
6966
6967   if (bd_id_set == 0)
6968     {
6969       errmsg ("missing bridge domain");
6970       return -99;
6971     }
6972   else if (ip_set == 0)
6973     {
6974       errmsg ("missing IP address");
6975       return -99;
6976     }
6977   else if (mac_set == 0)
6978     {
6979       errmsg ("missing MAC address");
6980       return -99;
6981     }
6982
6983   M (BD_IP_MAC_ADD_DEL, mp);
6984
6985   mp->bd_id = ntohl (bd_id);
6986   mp->is_ipv6 = is_ipv6;
6987   mp->is_add = is_add;
6988   if (is_ipv6)
6989     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
6990   else
6991     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
6992   clib_memcpy (mp->mac_address, macaddr, 6);
6993   S (mp);
6994   W (ret);
6995   return ret;
6996 }
6997
6998 static int
6999 api_tap_connect (vat_main_t * vam)
7000 {
7001   unformat_input_t *i = vam->input;
7002   vl_api_tap_connect_t *mp;
7003   u8 mac_address[6];
7004   u8 random_mac = 1;
7005   u8 name_set = 0;
7006   u8 *tap_name;
7007   u8 *tag = 0;
7008   ip4_address_t ip4_address;
7009   u32 ip4_mask_width;
7010   int ip4_address_set = 0;
7011   ip6_address_t ip6_address;
7012   u32 ip6_mask_width;
7013   int ip6_address_set = 0;
7014   int ret;
7015
7016   memset (mac_address, 0, sizeof (mac_address));
7017
7018   /* Parse args required to build the message */
7019   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7020     {
7021       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7022         {
7023           random_mac = 0;
7024         }
7025       else if (unformat (i, "random-mac"))
7026         random_mac = 1;
7027       else if (unformat (i, "tapname %s", &tap_name))
7028         name_set = 1;
7029       else if (unformat (i, "tag %s", &tag))
7030         ;
7031       else if (unformat (i, "address %U/%d",
7032                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7033         ip4_address_set = 1;
7034       else if (unformat (i, "address %U/%d",
7035                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7036         ip6_address_set = 1;
7037       else
7038         break;
7039     }
7040
7041   if (name_set == 0)
7042     {
7043       errmsg ("missing tap name");
7044       return -99;
7045     }
7046   if (vec_len (tap_name) > 63)
7047     {
7048       errmsg ("tap name too long");
7049       return -99;
7050     }
7051   vec_add1 (tap_name, 0);
7052
7053   if (vec_len (tag) > 63)
7054     {
7055       errmsg ("tag too long");
7056       return -99;
7057     }
7058
7059   /* Construct the API message */
7060   M (TAP_CONNECT, mp);
7061
7062   mp->use_random_mac = random_mac;
7063   clib_memcpy (mp->mac_address, mac_address, 6);
7064   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7065   if (tag)
7066     clib_memcpy (mp->tag, tag, vec_len (tag));
7067
7068   if (ip4_address_set)
7069     {
7070       mp->ip4_address_set = 1;
7071       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7072       mp->ip4_mask_width = ip4_mask_width;
7073     }
7074   if (ip6_address_set)
7075     {
7076       mp->ip6_address_set = 1;
7077       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7078       mp->ip6_mask_width = ip6_mask_width;
7079     }
7080
7081   vec_free (tap_name);
7082   vec_free (tag);
7083
7084   /* send it... */
7085   S (mp);
7086
7087   /* Wait for a reply... */
7088   W (ret);
7089   return ret;
7090 }
7091
7092 static int
7093 api_tap_modify (vat_main_t * vam)
7094 {
7095   unformat_input_t *i = vam->input;
7096   vl_api_tap_modify_t *mp;
7097   u8 mac_address[6];
7098   u8 random_mac = 1;
7099   u8 name_set = 0;
7100   u8 *tap_name;
7101   u32 sw_if_index = ~0;
7102   u8 sw_if_index_set = 0;
7103   int ret;
7104
7105   memset (mac_address, 0, sizeof (mac_address));
7106
7107   /* Parse args required to build the message */
7108   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7109     {
7110       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7111         sw_if_index_set = 1;
7112       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7113         sw_if_index_set = 1;
7114       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7115         {
7116           random_mac = 0;
7117         }
7118       else if (unformat (i, "random-mac"))
7119         random_mac = 1;
7120       else if (unformat (i, "tapname %s", &tap_name))
7121         name_set = 1;
7122       else
7123         break;
7124     }
7125
7126   if (sw_if_index_set == 0)
7127     {
7128       errmsg ("missing vpp interface name");
7129       return -99;
7130     }
7131   if (name_set == 0)
7132     {
7133       errmsg ("missing tap name");
7134       return -99;
7135     }
7136   if (vec_len (tap_name) > 63)
7137     {
7138       errmsg ("tap name too long");
7139     }
7140   vec_add1 (tap_name, 0);
7141
7142   /* Construct the API message */
7143   M (TAP_MODIFY, mp);
7144
7145   mp->use_random_mac = random_mac;
7146   mp->sw_if_index = ntohl (sw_if_index);
7147   clib_memcpy (mp->mac_address, mac_address, 6);
7148   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7149   vec_free (tap_name);
7150
7151   /* send it... */
7152   S (mp);
7153
7154   /* Wait for a reply... */
7155   W (ret);
7156   return ret;
7157 }
7158
7159 static int
7160 api_tap_delete (vat_main_t * vam)
7161 {
7162   unformat_input_t *i = vam->input;
7163   vl_api_tap_delete_t *mp;
7164   u32 sw_if_index = ~0;
7165   u8 sw_if_index_set = 0;
7166   int ret;
7167
7168   /* Parse args required to build the message */
7169   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7170     {
7171       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7172         sw_if_index_set = 1;
7173       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7174         sw_if_index_set = 1;
7175       else
7176         break;
7177     }
7178
7179   if (sw_if_index_set == 0)
7180     {
7181       errmsg ("missing vpp interface name");
7182       return -99;
7183     }
7184
7185   /* Construct the API message */
7186   M (TAP_DELETE, mp);
7187
7188   mp->sw_if_index = ntohl (sw_if_index);
7189
7190   /* send it... */
7191   S (mp);
7192
7193   /* Wait for a reply... */
7194   W (ret);
7195   return ret;
7196 }
7197
7198 static int
7199 api_ip_table_add_del (vat_main_t * vam)
7200 {
7201   unformat_input_t *i = vam->input;
7202   vl_api_ip_table_add_del_t *mp;
7203   u32 table_id = ~0;
7204   u8 is_ipv6 = 0;
7205   u8 is_add = 1;
7206   int ret = 0;
7207
7208   /* Parse args required to build the message */
7209   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7210     {
7211       if (unformat (i, "ipv6"))
7212         is_ipv6 = 1;
7213       else if (unformat (i, "del"))
7214         is_add = 0;
7215       else if (unformat (i, "add"))
7216         is_add = 1;
7217       else if (unformat (i, "table %d", &table_id))
7218         ;
7219       else
7220         {
7221           clib_warning ("parse error '%U'", format_unformat_error, i);
7222           return -99;
7223         }
7224     }
7225
7226   if (~0 == table_id)
7227     {
7228       errmsg ("missing table-ID");
7229       return -99;
7230     }
7231
7232   /* Construct the API message */
7233   M (IP_TABLE_ADD_DEL, mp);
7234
7235   mp->table_id = ntohl (table_id);
7236   mp->is_ipv6 = is_ipv6;
7237   mp->is_add = is_add;
7238
7239   /* send it... */
7240   S (mp);
7241
7242   /* Wait for a reply... */
7243   W (ret);
7244
7245   return ret;
7246 }
7247
7248 static int
7249 api_ip_add_del_route (vat_main_t * vam)
7250 {
7251   unformat_input_t *i = vam->input;
7252   vl_api_ip_add_del_route_t *mp;
7253   u32 sw_if_index = ~0, vrf_id = 0;
7254   u8 is_ipv6 = 0;
7255   u8 is_local = 0, is_drop = 0;
7256   u8 is_unreach = 0, is_prohibit = 0;
7257   u8 create_vrf_if_needed = 0;
7258   u8 is_add = 1;
7259   u32 next_hop_weight = 1;
7260   u8 not_last = 0;
7261   u8 is_multipath = 0;
7262   u8 address_set = 0;
7263   u8 address_length_set = 0;
7264   u32 next_hop_table_id = 0;
7265   u32 resolve_attempts = 0;
7266   u32 dst_address_length = 0;
7267   u8 next_hop_set = 0;
7268   ip4_address_t v4_dst_address, v4_next_hop_address;
7269   ip6_address_t v6_dst_address, v6_next_hop_address;
7270   int count = 1;
7271   int j;
7272   f64 before = 0;
7273   u32 random_add_del = 0;
7274   u32 *random_vector = 0;
7275   uword *random_hash;
7276   u32 random_seed = 0xdeaddabe;
7277   u32 classify_table_index = ~0;
7278   u8 is_classify = 0;
7279   u8 resolve_host = 0, resolve_attached = 0;
7280   mpls_label_t *next_hop_out_label_stack = NULL;
7281   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7282   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7283
7284   /* Parse args required to build the message */
7285   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7286     {
7287       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7288         ;
7289       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7290         ;
7291       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
7292         {
7293           address_set = 1;
7294           is_ipv6 = 0;
7295         }
7296       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
7297         {
7298           address_set = 1;
7299           is_ipv6 = 1;
7300         }
7301       else if (unformat (i, "/%d", &dst_address_length))
7302         {
7303           address_length_set = 1;
7304         }
7305
7306       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
7307                                          &v4_next_hop_address))
7308         {
7309           next_hop_set = 1;
7310         }
7311       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
7312                                          &v6_next_hop_address))
7313         {
7314           next_hop_set = 1;
7315         }
7316       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
7317         ;
7318       else if (unformat (i, "weight %d", &next_hop_weight))
7319         ;
7320       else if (unformat (i, "drop"))
7321         {
7322           is_drop = 1;
7323         }
7324       else if (unformat (i, "null-send-unreach"))
7325         {
7326           is_unreach = 1;
7327         }
7328       else if (unformat (i, "null-send-prohibit"))
7329         {
7330           is_prohibit = 1;
7331         }
7332       else if (unformat (i, "local"))
7333         {
7334           is_local = 1;
7335         }
7336       else if (unformat (i, "classify %d", &classify_table_index))
7337         {
7338           is_classify = 1;
7339         }
7340       else if (unformat (i, "del"))
7341         is_add = 0;
7342       else if (unformat (i, "add"))
7343         is_add = 1;
7344       else if (unformat (i, "not-last"))
7345         not_last = 1;
7346       else if (unformat (i, "resolve-via-host"))
7347         resolve_host = 1;
7348       else if (unformat (i, "resolve-via-attached"))
7349         resolve_attached = 1;
7350       else if (unformat (i, "multipath"))
7351         is_multipath = 1;
7352       else if (unformat (i, "vrf %d", &vrf_id))
7353         ;
7354       else if (unformat (i, "create-vrf"))
7355         create_vrf_if_needed = 1;
7356       else if (unformat (i, "count %d", &count))
7357         ;
7358       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
7359         ;
7360       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7361         ;
7362       else if (unformat (i, "out-label %d", &next_hop_out_label))
7363         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7364       else if (unformat (i, "via-label %d", &next_hop_via_label))
7365         ;
7366       else if (unformat (i, "random"))
7367         random_add_del = 1;
7368       else if (unformat (i, "seed %d", &random_seed))
7369         ;
7370       else
7371         {
7372           clib_warning ("parse error '%U'", format_unformat_error, i);
7373           return -99;
7374         }
7375     }
7376
7377   if (!next_hop_set && !is_drop && !is_local &&
7378       !is_classify && !is_unreach && !is_prohibit &&
7379       MPLS_LABEL_INVALID == next_hop_via_label)
7380     {
7381       errmsg
7382         ("next hop / local / drop / unreach / prohibit / classify not set");
7383       return -99;
7384     }
7385
7386   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
7387     {
7388       errmsg ("next hop and next-hop via label set");
7389       return -99;
7390     }
7391   if (address_set == 0)
7392     {
7393       errmsg ("missing addresses");
7394       return -99;
7395     }
7396
7397   if (address_length_set == 0)
7398     {
7399       errmsg ("missing address length");
7400       return -99;
7401     }
7402
7403   /* Generate a pile of unique, random routes */
7404   if (random_add_del)
7405     {
7406       u32 this_random_address;
7407       random_hash = hash_create (count, sizeof (uword));
7408
7409       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
7410       for (j = 0; j <= count; j++)
7411         {
7412           do
7413             {
7414               this_random_address = random_u32 (&random_seed);
7415               this_random_address =
7416                 clib_host_to_net_u32 (this_random_address);
7417             }
7418           while (hash_get (random_hash, this_random_address));
7419           vec_add1 (random_vector, this_random_address);
7420           hash_set (random_hash, this_random_address, 1);
7421         }
7422       hash_free (random_hash);
7423       v4_dst_address.as_u32 = random_vector[0];
7424     }
7425
7426   if (count > 1)
7427     {
7428       /* Turn on async mode */
7429       vam->async_mode = 1;
7430       vam->async_errors = 0;
7431       before = vat_time_now (vam);
7432     }
7433
7434   for (j = 0; j < count; j++)
7435     {
7436       /* Construct the API message */
7437       M2 (IP_ADD_DEL_ROUTE, mp,
7438           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7439
7440       mp->next_hop_sw_if_index = ntohl (sw_if_index);
7441       mp->table_id = ntohl (vrf_id);
7442       mp->create_vrf_if_needed = create_vrf_if_needed;
7443
7444       mp->is_add = is_add;
7445       mp->is_drop = is_drop;
7446       mp->is_unreach = is_unreach;
7447       mp->is_prohibit = is_prohibit;
7448       mp->is_ipv6 = is_ipv6;
7449       mp->is_local = is_local;
7450       mp->is_classify = is_classify;
7451       mp->is_multipath = is_multipath;
7452       mp->is_resolve_host = resolve_host;
7453       mp->is_resolve_attached = resolve_attached;
7454       mp->not_last = not_last;
7455       mp->next_hop_weight = next_hop_weight;
7456       mp->dst_address_length = dst_address_length;
7457       mp->next_hop_table_id = ntohl (next_hop_table_id);
7458       mp->classify_table_index = ntohl (classify_table_index);
7459       mp->next_hop_via_label = ntohl (next_hop_via_label);
7460       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7461       if (0 != mp->next_hop_n_out_labels)
7462         {
7463           memcpy (mp->next_hop_out_label_stack,
7464                   next_hop_out_label_stack,
7465                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7466           vec_free (next_hop_out_label_stack);
7467         }
7468
7469       if (is_ipv6)
7470         {
7471           clib_memcpy (mp->dst_address, &v6_dst_address,
7472                        sizeof (v6_dst_address));
7473           if (next_hop_set)
7474             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
7475                          sizeof (v6_next_hop_address));
7476           increment_v6_address (&v6_dst_address);
7477         }
7478       else
7479         {
7480           clib_memcpy (mp->dst_address, &v4_dst_address,
7481                        sizeof (v4_dst_address));
7482           if (next_hop_set)
7483             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
7484                          sizeof (v4_next_hop_address));
7485           if (random_add_del)
7486             v4_dst_address.as_u32 = random_vector[j + 1];
7487           else
7488             increment_v4_address (&v4_dst_address);
7489         }
7490       /* send it... */
7491       S (mp);
7492       /* If we receive SIGTERM, stop now... */
7493       if (vam->do_exit)
7494         break;
7495     }
7496
7497   /* When testing multiple add/del ops, use a control-ping to sync */
7498   if (count > 1)
7499     {
7500       vl_api_control_ping_t *mp_ping;
7501       f64 after;
7502       f64 timeout;
7503
7504       /* Shut off async mode */
7505       vam->async_mode = 0;
7506
7507       M (CONTROL_PING, mp_ping);
7508       S (mp_ping);
7509
7510       timeout = vat_time_now (vam) + 1.0;
7511       while (vat_time_now (vam) < timeout)
7512         if (vam->result_ready == 1)
7513           goto out;
7514       vam->retval = -99;
7515
7516     out:
7517       if (vam->retval == -99)
7518         errmsg ("timeout");
7519
7520       if (vam->async_errors > 0)
7521         {
7522           errmsg ("%d asynchronous errors", vam->async_errors);
7523           vam->retval = -98;
7524         }
7525       vam->async_errors = 0;
7526       after = vat_time_now (vam);
7527
7528       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7529       if (j > 0)
7530         count = j;
7531
7532       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7533              count, after - before, count / (after - before));
7534     }
7535   else
7536     {
7537       int ret;
7538
7539       /* Wait for a reply... */
7540       W (ret);
7541       return ret;
7542     }
7543
7544   /* Return the good/bad news */
7545   return (vam->retval);
7546 }
7547
7548 static int
7549 api_ip_mroute_add_del (vat_main_t * vam)
7550 {
7551   unformat_input_t *i = vam->input;
7552   vl_api_ip_mroute_add_del_t *mp;
7553   u32 sw_if_index = ~0, vrf_id = 0;
7554   u8 is_ipv6 = 0;
7555   u8 is_local = 0;
7556   u8 create_vrf_if_needed = 0;
7557   u8 is_add = 1;
7558   u8 address_set = 0;
7559   u32 grp_address_length = 0;
7560   ip4_address_t v4_grp_address, v4_src_address;
7561   ip6_address_t v6_grp_address, v6_src_address;
7562   mfib_itf_flags_t iflags = 0;
7563   mfib_entry_flags_t eflags = 0;
7564   int ret;
7565
7566   /* Parse args required to build the message */
7567   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7568     {
7569       if (unformat (i, "sw_if_index %d", &sw_if_index))
7570         ;
7571       else if (unformat (i, "%U %U",
7572                          unformat_ip4_address, &v4_src_address,
7573                          unformat_ip4_address, &v4_grp_address))
7574         {
7575           grp_address_length = 64;
7576           address_set = 1;
7577           is_ipv6 = 0;
7578         }
7579       else if (unformat (i, "%U %U",
7580                          unformat_ip6_address, &v6_src_address,
7581                          unformat_ip6_address, &v6_grp_address))
7582         {
7583           grp_address_length = 256;
7584           address_set = 1;
7585           is_ipv6 = 1;
7586         }
7587       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
7588         {
7589           memset (&v4_src_address, 0, sizeof (v4_src_address));
7590           grp_address_length = 32;
7591           address_set = 1;
7592           is_ipv6 = 0;
7593         }
7594       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
7595         {
7596           memset (&v6_src_address, 0, sizeof (v6_src_address));
7597           grp_address_length = 128;
7598           address_set = 1;
7599           is_ipv6 = 1;
7600         }
7601       else if (unformat (i, "/%d", &grp_address_length))
7602         ;
7603       else if (unformat (i, "local"))
7604         {
7605           is_local = 1;
7606         }
7607       else if (unformat (i, "del"))
7608         is_add = 0;
7609       else if (unformat (i, "add"))
7610         is_add = 1;
7611       else if (unformat (i, "vrf %d", &vrf_id))
7612         ;
7613       else if (unformat (i, "create-vrf"))
7614         create_vrf_if_needed = 1;
7615       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
7616         ;
7617       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
7618         ;
7619       else
7620         {
7621           clib_warning ("parse error '%U'", format_unformat_error, i);
7622           return -99;
7623         }
7624     }
7625
7626   if (address_set == 0)
7627     {
7628       errmsg ("missing addresses\n");
7629       return -99;
7630     }
7631
7632   /* Construct the API message */
7633   M (IP_MROUTE_ADD_DEL, mp);
7634
7635   mp->next_hop_sw_if_index = ntohl (sw_if_index);
7636   mp->table_id = ntohl (vrf_id);
7637   mp->create_vrf_if_needed = create_vrf_if_needed;
7638
7639   mp->is_add = is_add;
7640   mp->is_ipv6 = is_ipv6;
7641   mp->is_local = is_local;
7642   mp->itf_flags = ntohl (iflags);
7643   mp->entry_flags = ntohl (eflags);
7644   mp->grp_address_length = grp_address_length;
7645   mp->grp_address_length = ntohs (mp->grp_address_length);
7646
7647   if (is_ipv6)
7648     {
7649       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
7650       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
7651     }
7652   else
7653     {
7654       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
7655       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
7656
7657     }
7658
7659   /* send it... */
7660   S (mp);
7661   /* Wait for a reply... */
7662   W (ret);
7663   return ret;
7664 }
7665
7666 static int
7667 api_mpls_table_add_del (vat_main_t * vam)
7668 {
7669   unformat_input_t *i = vam->input;
7670   vl_api_mpls_table_add_del_t *mp;
7671   u32 table_id = ~0;
7672   u8 is_add = 1;
7673   int ret = 0;
7674
7675   /* Parse args required to build the message */
7676   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7677     {
7678       if (unformat (i, "table %d", &table_id))
7679         ;
7680       else if (unformat (i, "del"))
7681         is_add = 0;
7682       else if (unformat (i, "add"))
7683         is_add = 1;
7684       else
7685         {
7686           clib_warning ("parse error '%U'", format_unformat_error, i);
7687           return -99;
7688         }
7689     }
7690
7691   if (~0 == table_id)
7692     {
7693       errmsg ("missing table-ID");
7694       return -99;
7695     }
7696
7697   /* Construct the API message */
7698   M (MPLS_TABLE_ADD_DEL, mp);
7699
7700   mp->mt_table_id = ntohl (table_id);
7701   mp->mt_is_add = is_add;
7702
7703   /* send it... */
7704   S (mp);
7705
7706   /* Wait for a reply... */
7707   W (ret);
7708
7709   return ret;
7710 }
7711
7712 static int
7713 api_mpls_route_add_del (vat_main_t * vam)
7714 {
7715   unformat_input_t *i = vam->input;
7716   vl_api_mpls_route_add_del_t *mp;
7717   u32 sw_if_index = ~0, table_id = 0;
7718   u8 create_table_if_needed = 0;
7719   u8 is_add = 1;
7720   u32 next_hop_weight = 1;
7721   u8 is_multipath = 0;
7722   u32 next_hop_table_id = 0;
7723   u8 next_hop_set = 0;
7724   ip4_address_t v4_next_hop_address = {
7725     .as_u32 = 0,
7726   };
7727   ip6_address_t v6_next_hop_address = { {0} };
7728   int count = 1;
7729   int j;
7730   f64 before = 0;
7731   u32 classify_table_index = ~0;
7732   u8 is_classify = 0;
7733   u8 resolve_host = 0, resolve_attached = 0;
7734   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7735   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7736   mpls_label_t *next_hop_out_label_stack = NULL;
7737   mpls_label_t local_label = MPLS_LABEL_INVALID;
7738   u8 is_eos = 0;
7739   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
7740
7741   /* Parse args required to build the message */
7742   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7743     {
7744       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7745         ;
7746       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7747         ;
7748       else if (unformat (i, "%d", &local_label))
7749         ;
7750       else if (unformat (i, "eos"))
7751         is_eos = 1;
7752       else if (unformat (i, "non-eos"))
7753         is_eos = 0;
7754       else if (unformat (i, "via %U", unformat_ip4_address,
7755                          &v4_next_hop_address))
7756         {
7757           next_hop_set = 1;
7758           next_hop_proto = DPO_PROTO_IP4;
7759         }
7760       else if (unformat (i, "via %U", unformat_ip6_address,
7761                          &v6_next_hop_address))
7762         {
7763           next_hop_set = 1;
7764           next_hop_proto = DPO_PROTO_IP6;
7765         }
7766       else if (unformat (i, "weight %d", &next_hop_weight))
7767         ;
7768       else if (unformat (i, "create-table"))
7769         create_table_if_needed = 1;
7770       else if (unformat (i, "classify %d", &classify_table_index))
7771         {
7772           is_classify = 1;
7773         }
7774       else if (unformat (i, "del"))
7775         is_add = 0;
7776       else if (unformat (i, "add"))
7777         is_add = 1;
7778       else if (unformat (i, "resolve-via-host"))
7779         resolve_host = 1;
7780       else if (unformat (i, "resolve-via-attached"))
7781         resolve_attached = 1;
7782       else if (unformat (i, "multipath"))
7783         is_multipath = 1;
7784       else if (unformat (i, "count %d", &count))
7785         ;
7786       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
7787         {
7788           next_hop_set = 1;
7789           next_hop_proto = DPO_PROTO_IP4;
7790         }
7791       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
7792         {
7793           next_hop_set = 1;
7794           next_hop_proto = DPO_PROTO_IP6;
7795         }
7796       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7797         ;
7798       else if (unformat (i, "via-label %d", &next_hop_via_label))
7799         ;
7800       else if (unformat (i, "out-label %d", &next_hop_out_label))
7801         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7802       else
7803         {
7804           clib_warning ("parse error '%U'", format_unformat_error, i);
7805           return -99;
7806         }
7807     }
7808
7809   if (!next_hop_set && !is_classify)
7810     {
7811       errmsg ("next hop / classify not set");
7812       return -99;
7813     }
7814
7815   if (MPLS_LABEL_INVALID == local_label)
7816     {
7817       errmsg ("missing label");
7818       return -99;
7819     }
7820
7821   if (count > 1)
7822     {
7823       /* Turn on async mode */
7824       vam->async_mode = 1;
7825       vam->async_errors = 0;
7826       before = vat_time_now (vam);
7827     }
7828
7829   for (j = 0; j < count; j++)
7830     {
7831       /* Construct the API message */
7832       M2 (MPLS_ROUTE_ADD_DEL, mp,
7833           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7834
7835       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
7836       mp->mr_table_id = ntohl (table_id);
7837       mp->mr_create_table_if_needed = create_table_if_needed;
7838
7839       mp->mr_is_add = is_add;
7840       mp->mr_next_hop_proto = next_hop_proto;
7841       mp->mr_is_classify = is_classify;
7842       mp->mr_is_multipath = is_multipath;
7843       mp->mr_is_resolve_host = resolve_host;
7844       mp->mr_is_resolve_attached = resolve_attached;
7845       mp->mr_next_hop_weight = next_hop_weight;
7846       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
7847       mp->mr_classify_table_index = ntohl (classify_table_index);
7848       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
7849       mp->mr_label = ntohl (local_label);
7850       mp->mr_eos = is_eos;
7851
7852       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7853       if (0 != mp->mr_next_hop_n_out_labels)
7854         {
7855           memcpy (mp->mr_next_hop_out_label_stack,
7856                   next_hop_out_label_stack,
7857                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7858           vec_free (next_hop_out_label_stack);
7859         }
7860
7861       if (next_hop_set)
7862         {
7863           if (DPO_PROTO_IP4 == next_hop_proto)
7864             {
7865               clib_memcpy (mp->mr_next_hop,
7866                            &v4_next_hop_address,
7867                            sizeof (v4_next_hop_address));
7868             }
7869           else if (DPO_PROTO_IP6 == next_hop_proto)
7870
7871             {
7872               clib_memcpy (mp->mr_next_hop,
7873                            &v6_next_hop_address,
7874                            sizeof (v6_next_hop_address));
7875             }
7876         }
7877       local_label++;
7878
7879       /* send it... */
7880       S (mp);
7881       /* If we receive SIGTERM, stop now... */
7882       if (vam->do_exit)
7883         break;
7884     }
7885
7886   /* When testing multiple add/del ops, use a control-ping to sync */
7887   if (count > 1)
7888     {
7889       vl_api_control_ping_t *mp_ping;
7890       f64 after;
7891       f64 timeout;
7892
7893       /* Shut off async mode */
7894       vam->async_mode = 0;
7895
7896       M (CONTROL_PING, mp_ping);
7897       S (mp_ping);
7898
7899       timeout = vat_time_now (vam) + 1.0;
7900       while (vat_time_now (vam) < timeout)
7901         if (vam->result_ready == 1)
7902           goto out;
7903       vam->retval = -99;
7904
7905     out:
7906       if (vam->retval == -99)
7907         errmsg ("timeout");
7908
7909       if (vam->async_errors > 0)
7910         {
7911           errmsg ("%d asynchronous errors", vam->async_errors);
7912           vam->retval = -98;
7913         }
7914       vam->async_errors = 0;
7915       after = vat_time_now (vam);
7916
7917       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7918       if (j > 0)
7919         count = j;
7920
7921       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7922              count, after - before, count / (after - before));
7923     }
7924   else
7925     {
7926       int ret;
7927
7928       /* Wait for a reply... */
7929       W (ret);
7930       return ret;
7931     }
7932
7933   /* Return the good/bad news */
7934   return (vam->retval);
7935 }
7936
7937 static int
7938 api_mpls_ip_bind_unbind (vat_main_t * vam)
7939 {
7940   unformat_input_t *i = vam->input;
7941   vl_api_mpls_ip_bind_unbind_t *mp;
7942   u32 ip_table_id = 0;
7943   u8 create_table_if_needed = 0;
7944   u8 is_bind = 1;
7945   u8 is_ip4 = 1;
7946   ip4_address_t v4_address;
7947   ip6_address_t v6_address;
7948   u32 address_length;
7949   u8 address_set = 0;
7950   mpls_label_t local_label = MPLS_LABEL_INVALID;
7951   int ret;
7952
7953   /* Parse args required to build the message */
7954   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7955     {
7956       if (unformat (i, "%U/%d", unformat_ip4_address,
7957                     &v4_address, &address_length))
7958         {
7959           is_ip4 = 1;
7960           address_set = 1;
7961         }
7962       else if (unformat (i, "%U/%d", unformat_ip6_address,
7963                          &v6_address, &address_length))
7964         {
7965           is_ip4 = 0;
7966           address_set = 1;
7967         }
7968       else if (unformat (i, "%d", &local_label))
7969         ;
7970       else if (unformat (i, "create-table"))
7971         create_table_if_needed = 1;
7972       else if (unformat (i, "table-id %d", &ip_table_id))
7973         ;
7974       else if (unformat (i, "unbind"))
7975         is_bind = 0;
7976       else if (unformat (i, "bind"))
7977         is_bind = 1;
7978       else
7979         {
7980           clib_warning ("parse error '%U'", format_unformat_error, i);
7981           return -99;
7982         }
7983     }
7984
7985   if (!address_set)
7986     {
7987       errmsg ("IP addres not set");
7988       return -99;
7989     }
7990
7991   if (MPLS_LABEL_INVALID == local_label)
7992     {
7993       errmsg ("missing label");
7994       return -99;
7995     }
7996
7997   /* Construct the API message */
7998   M (MPLS_IP_BIND_UNBIND, mp);
7999
8000   mp->mb_create_table_if_needed = create_table_if_needed;
8001   mp->mb_is_bind = is_bind;
8002   mp->mb_is_ip4 = is_ip4;
8003   mp->mb_ip_table_id = ntohl (ip_table_id);
8004   mp->mb_mpls_table_id = 0;
8005   mp->mb_label = ntohl (local_label);
8006   mp->mb_address_length = address_length;
8007
8008   if (is_ip4)
8009     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8010   else
8011     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8012
8013   /* send it... */
8014   S (mp);
8015
8016   /* Wait for a reply... */
8017   W (ret);
8018   return ret;
8019 }
8020
8021 static int
8022 api_proxy_arp_add_del (vat_main_t * vam)
8023 {
8024   unformat_input_t *i = vam->input;
8025   vl_api_proxy_arp_add_del_t *mp;
8026   u32 vrf_id = 0;
8027   u8 is_add = 1;
8028   ip4_address_t lo, hi;
8029   u8 range_set = 0;
8030   int ret;
8031
8032   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8033     {
8034       if (unformat (i, "vrf %d", &vrf_id))
8035         ;
8036       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
8037                          unformat_ip4_address, &hi))
8038         range_set = 1;
8039       else if (unformat (i, "del"))
8040         is_add = 0;
8041       else
8042         {
8043           clib_warning ("parse error '%U'", format_unformat_error, i);
8044           return -99;
8045         }
8046     }
8047
8048   if (range_set == 0)
8049     {
8050       errmsg ("address range not set");
8051       return -99;
8052     }
8053
8054   M (PROXY_ARP_ADD_DEL, mp);
8055
8056   mp->vrf_id = ntohl (vrf_id);
8057   mp->is_add = is_add;
8058   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
8059   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
8060
8061   S (mp);
8062   W (ret);
8063   return ret;
8064 }
8065
8066 static int
8067 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8068 {
8069   unformat_input_t *i = vam->input;
8070   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8071   u32 sw_if_index;
8072   u8 enable = 1;
8073   u8 sw_if_index_set = 0;
8074   int ret;
8075
8076   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8077     {
8078       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8079         sw_if_index_set = 1;
8080       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8081         sw_if_index_set = 1;
8082       else if (unformat (i, "enable"))
8083         enable = 1;
8084       else if (unformat (i, "disable"))
8085         enable = 0;
8086       else
8087         {
8088           clib_warning ("parse error '%U'", format_unformat_error, i);
8089           return -99;
8090         }
8091     }
8092
8093   if (sw_if_index_set == 0)
8094     {
8095       errmsg ("missing interface name or sw_if_index");
8096       return -99;
8097     }
8098
8099   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8100
8101   mp->sw_if_index = ntohl (sw_if_index);
8102   mp->enable_disable = enable;
8103
8104   S (mp);
8105   W (ret);
8106   return ret;
8107 }
8108
8109 static int
8110 api_mpls_tunnel_add_del (vat_main_t * vam)
8111 {
8112   unformat_input_t *i = vam->input;
8113   vl_api_mpls_tunnel_add_del_t *mp;
8114
8115   u8 is_add = 1;
8116   u8 l2_only = 0;
8117   u32 sw_if_index = ~0;
8118   u32 next_hop_sw_if_index = ~0;
8119   u32 next_hop_proto_is_ip4 = 1;
8120
8121   u32 next_hop_table_id = 0;
8122   ip4_address_t v4_next_hop_address = {
8123     .as_u32 = 0,
8124   };
8125   ip6_address_t v6_next_hop_address = { {0} };
8126   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
8127   int ret;
8128
8129   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8130     {
8131       if (unformat (i, "add"))
8132         is_add = 1;
8133       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8134         is_add = 0;
8135       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
8136         ;
8137       else if (unformat (i, "via %U",
8138                          unformat_ip4_address, &v4_next_hop_address))
8139         {
8140           next_hop_proto_is_ip4 = 1;
8141         }
8142       else if (unformat (i, "via %U",
8143                          unformat_ip6_address, &v6_next_hop_address))
8144         {
8145           next_hop_proto_is_ip4 = 0;
8146         }
8147       else if (unformat (i, "l2-only"))
8148         l2_only = 1;
8149       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8150         ;
8151       else if (unformat (i, "out-label %d", &next_hop_out_label))
8152         vec_add1 (labels, ntohl (next_hop_out_label));
8153       else
8154         {
8155           clib_warning ("parse error '%U'", format_unformat_error, i);
8156           return -99;
8157         }
8158     }
8159
8160   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
8161
8162   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
8163   mp->mt_sw_if_index = ntohl (sw_if_index);
8164   mp->mt_is_add = is_add;
8165   mp->mt_l2_only = l2_only;
8166   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
8167   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
8168
8169   mp->mt_next_hop_n_out_labels = vec_len (labels);
8170
8171   if (0 != mp->mt_next_hop_n_out_labels)
8172     {
8173       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
8174                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
8175       vec_free (labels);
8176     }
8177
8178   if (next_hop_proto_is_ip4)
8179     {
8180       clib_memcpy (mp->mt_next_hop,
8181                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8182     }
8183   else
8184     {
8185       clib_memcpy (mp->mt_next_hop,
8186                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8187     }
8188
8189   S (mp);
8190   W (ret);
8191   return ret;
8192 }
8193
8194 static int
8195 api_sw_interface_set_unnumbered (vat_main_t * vam)
8196 {
8197   unformat_input_t *i = vam->input;
8198   vl_api_sw_interface_set_unnumbered_t *mp;
8199   u32 sw_if_index;
8200   u32 unnum_sw_index = ~0;
8201   u8 is_add = 1;
8202   u8 sw_if_index_set = 0;
8203   int ret;
8204
8205   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8206     {
8207       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8208         sw_if_index_set = 1;
8209       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8210         sw_if_index_set = 1;
8211       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8212         ;
8213       else if (unformat (i, "del"))
8214         is_add = 0;
8215       else
8216         {
8217           clib_warning ("parse error '%U'", format_unformat_error, i);
8218           return -99;
8219         }
8220     }
8221
8222   if (sw_if_index_set == 0)
8223     {
8224       errmsg ("missing interface name or sw_if_index");
8225       return -99;
8226     }
8227
8228   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8229
8230   mp->sw_if_index = ntohl (sw_if_index);
8231   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8232   mp->is_add = is_add;
8233
8234   S (mp);
8235   W (ret);
8236   return ret;
8237 }
8238
8239 static int
8240 api_ip_neighbor_add_del (vat_main_t * vam)
8241 {
8242   unformat_input_t *i = vam->input;
8243   vl_api_ip_neighbor_add_del_t *mp;
8244   u32 sw_if_index;
8245   u8 sw_if_index_set = 0;
8246   u8 is_add = 1;
8247   u8 is_static = 0;
8248   u8 is_no_fib_entry = 0;
8249   u8 mac_address[6];
8250   u8 mac_set = 0;
8251   u8 v4_address_set = 0;
8252   u8 v6_address_set = 0;
8253   ip4_address_t v4address;
8254   ip6_address_t v6address;
8255   int ret;
8256
8257   memset (mac_address, 0, sizeof (mac_address));
8258
8259   /* Parse args required to build the message */
8260   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8261     {
8262       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8263         {
8264           mac_set = 1;
8265         }
8266       else if (unformat (i, "del"))
8267         is_add = 0;
8268       else
8269         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8270         sw_if_index_set = 1;
8271       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8272         sw_if_index_set = 1;
8273       else if (unformat (i, "is_static"))
8274         is_static = 1;
8275       else if (unformat (i, "no-fib-entry"))
8276         is_no_fib_entry = 1;
8277       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
8278         v4_address_set = 1;
8279       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
8280         v6_address_set = 1;
8281       else
8282         {
8283           clib_warning ("parse error '%U'", format_unformat_error, i);
8284           return -99;
8285         }
8286     }
8287
8288   if (sw_if_index_set == 0)
8289     {
8290       errmsg ("missing interface name or sw_if_index");
8291       return -99;
8292     }
8293   if (v4_address_set && v6_address_set)
8294     {
8295       errmsg ("both v4 and v6 addresses set");
8296       return -99;
8297     }
8298   if (!v4_address_set && !v6_address_set)
8299     {
8300       errmsg ("no address set");
8301       return -99;
8302     }
8303
8304   /* Construct the API message */
8305   M (IP_NEIGHBOR_ADD_DEL, mp);
8306
8307   mp->sw_if_index = ntohl (sw_if_index);
8308   mp->is_add = is_add;
8309   mp->is_static = is_static;
8310   mp->is_no_adj_fib = is_no_fib_entry;
8311   if (mac_set)
8312     clib_memcpy (mp->mac_address, mac_address, 6);
8313   if (v6_address_set)
8314     {
8315       mp->is_ipv6 = 1;
8316       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
8317     }
8318   else
8319     {
8320       /* mp->is_ipv6 = 0; via memset in M macro above */
8321       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
8322     }
8323
8324   /* send it... */
8325   S (mp);
8326
8327   /* Wait for a reply, return good/bad news  */
8328   W (ret);
8329   return ret;
8330 }
8331
8332 static int
8333 api_reset_vrf (vat_main_t * vam)
8334 {
8335   unformat_input_t *i = vam->input;
8336   vl_api_reset_vrf_t *mp;
8337   u32 vrf_id = 0;
8338   u8 is_ipv6 = 0;
8339   u8 vrf_id_set = 0;
8340   int ret;
8341
8342   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8343     {
8344       if (unformat (i, "vrf %d", &vrf_id))
8345         vrf_id_set = 1;
8346       else if (unformat (i, "ipv6"))
8347         is_ipv6 = 1;
8348       else
8349         {
8350           clib_warning ("parse error '%U'", format_unformat_error, i);
8351           return -99;
8352         }
8353     }
8354
8355   if (vrf_id_set == 0)
8356     {
8357       errmsg ("missing vrf id");
8358       return -99;
8359     }
8360
8361   M (RESET_VRF, mp);
8362
8363   mp->vrf_id = ntohl (vrf_id);
8364   mp->is_ipv6 = is_ipv6;
8365
8366   S (mp);
8367   W (ret);
8368   return ret;
8369 }
8370
8371 static int
8372 api_create_vlan_subif (vat_main_t * vam)
8373 {
8374   unformat_input_t *i = vam->input;
8375   vl_api_create_vlan_subif_t *mp;
8376   u32 sw_if_index;
8377   u8 sw_if_index_set = 0;
8378   u32 vlan_id;
8379   u8 vlan_id_set = 0;
8380   int ret;
8381
8382   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8383     {
8384       if (unformat (i, "sw_if_index %d", &sw_if_index))
8385         sw_if_index_set = 1;
8386       else
8387         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8388         sw_if_index_set = 1;
8389       else if (unformat (i, "vlan %d", &vlan_id))
8390         vlan_id_set = 1;
8391       else
8392         {
8393           clib_warning ("parse error '%U'", format_unformat_error, i);
8394           return -99;
8395         }
8396     }
8397
8398   if (sw_if_index_set == 0)
8399     {
8400       errmsg ("missing interface name or sw_if_index");
8401       return -99;
8402     }
8403
8404   if (vlan_id_set == 0)
8405     {
8406       errmsg ("missing vlan_id");
8407       return -99;
8408     }
8409   M (CREATE_VLAN_SUBIF, mp);
8410
8411   mp->sw_if_index = ntohl (sw_if_index);
8412   mp->vlan_id = ntohl (vlan_id);
8413
8414   S (mp);
8415   W (ret);
8416   return ret;
8417 }
8418
8419 #define foreach_create_subif_bit                \
8420 _(no_tags)                                      \
8421 _(one_tag)                                      \
8422 _(two_tags)                                     \
8423 _(dot1ad)                                       \
8424 _(exact_match)                                  \
8425 _(default_sub)                                  \
8426 _(outer_vlan_id_any)                            \
8427 _(inner_vlan_id_any)
8428
8429 static int
8430 api_create_subif (vat_main_t * vam)
8431 {
8432   unformat_input_t *i = vam->input;
8433   vl_api_create_subif_t *mp;
8434   u32 sw_if_index;
8435   u8 sw_if_index_set = 0;
8436   u32 sub_id;
8437   u8 sub_id_set = 0;
8438   u32 no_tags = 0;
8439   u32 one_tag = 0;
8440   u32 two_tags = 0;
8441   u32 dot1ad = 0;
8442   u32 exact_match = 0;
8443   u32 default_sub = 0;
8444   u32 outer_vlan_id_any = 0;
8445   u32 inner_vlan_id_any = 0;
8446   u32 tmp;
8447   u16 outer_vlan_id = 0;
8448   u16 inner_vlan_id = 0;
8449   int ret;
8450
8451   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8452     {
8453       if (unformat (i, "sw_if_index %d", &sw_if_index))
8454         sw_if_index_set = 1;
8455       else
8456         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8457         sw_if_index_set = 1;
8458       else if (unformat (i, "sub_id %d", &sub_id))
8459         sub_id_set = 1;
8460       else if (unformat (i, "outer_vlan_id %d", &tmp))
8461         outer_vlan_id = tmp;
8462       else if (unformat (i, "inner_vlan_id %d", &tmp))
8463         inner_vlan_id = tmp;
8464
8465 #define _(a) else if (unformat (i, #a)) a = 1 ;
8466       foreach_create_subif_bit
8467 #undef _
8468         else
8469         {
8470           clib_warning ("parse error '%U'", format_unformat_error, i);
8471           return -99;
8472         }
8473     }
8474
8475   if (sw_if_index_set == 0)
8476     {
8477       errmsg ("missing interface name or sw_if_index");
8478       return -99;
8479     }
8480
8481   if (sub_id_set == 0)
8482     {
8483       errmsg ("missing sub_id");
8484       return -99;
8485     }
8486   M (CREATE_SUBIF, mp);
8487
8488   mp->sw_if_index = ntohl (sw_if_index);
8489   mp->sub_id = ntohl (sub_id);
8490
8491 #define _(a) mp->a = a;
8492   foreach_create_subif_bit;
8493 #undef _
8494
8495   mp->outer_vlan_id = ntohs (outer_vlan_id);
8496   mp->inner_vlan_id = ntohs (inner_vlan_id);
8497
8498   S (mp);
8499   W (ret);
8500   return ret;
8501 }
8502
8503 static int
8504 api_oam_add_del (vat_main_t * vam)
8505 {
8506   unformat_input_t *i = vam->input;
8507   vl_api_oam_add_del_t *mp;
8508   u32 vrf_id = 0;
8509   u8 is_add = 1;
8510   ip4_address_t src, dst;
8511   u8 src_set = 0;
8512   u8 dst_set = 0;
8513   int ret;
8514
8515   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8516     {
8517       if (unformat (i, "vrf %d", &vrf_id))
8518         ;
8519       else if (unformat (i, "src %U", unformat_ip4_address, &src))
8520         src_set = 1;
8521       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
8522         dst_set = 1;
8523       else if (unformat (i, "del"))
8524         is_add = 0;
8525       else
8526         {
8527           clib_warning ("parse error '%U'", format_unformat_error, i);
8528           return -99;
8529         }
8530     }
8531
8532   if (src_set == 0)
8533     {
8534       errmsg ("missing src addr");
8535       return -99;
8536     }
8537
8538   if (dst_set == 0)
8539     {
8540       errmsg ("missing dst addr");
8541       return -99;
8542     }
8543
8544   M (OAM_ADD_DEL, mp);
8545
8546   mp->vrf_id = ntohl (vrf_id);
8547   mp->is_add = is_add;
8548   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
8549   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
8550
8551   S (mp);
8552   W (ret);
8553   return ret;
8554 }
8555
8556 static int
8557 api_reset_fib (vat_main_t * vam)
8558 {
8559   unformat_input_t *i = vam->input;
8560   vl_api_reset_fib_t *mp;
8561   u32 vrf_id = 0;
8562   u8 is_ipv6 = 0;
8563   u8 vrf_id_set = 0;
8564
8565   int ret;
8566   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8567     {
8568       if (unformat (i, "vrf %d", &vrf_id))
8569         vrf_id_set = 1;
8570       else if (unformat (i, "ipv6"))
8571         is_ipv6 = 1;
8572       else
8573         {
8574           clib_warning ("parse error '%U'", format_unformat_error, i);
8575           return -99;
8576         }
8577     }
8578
8579   if (vrf_id_set == 0)
8580     {
8581       errmsg ("missing vrf id");
8582       return -99;
8583     }
8584
8585   M (RESET_FIB, mp);
8586
8587   mp->vrf_id = ntohl (vrf_id);
8588   mp->is_ipv6 = is_ipv6;
8589
8590   S (mp);
8591   W (ret);
8592   return ret;
8593 }
8594
8595 static int
8596 api_dhcp_proxy_config (vat_main_t * vam)
8597 {
8598   unformat_input_t *i = vam->input;
8599   vl_api_dhcp_proxy_config_t *mp;
8600   u32 rx_vrf_id = 0;
8601   u32 server_vrf_id = 0;
8602   u8 is_add = 1;
8603   u8 v4_address_set = 0;
8604   u8 v6_address_set = 0;
8605   ip4_address_t v4address;
8606   ip6_address_t v6address;
8607   u8 v4_src_address_set = 0;
8608   u8 v6_src_address_set = 0;
8609   ip4_address_t v4srcaddress;
8610   ip6_address_t v6srcaddress;
8611   int ret;
8612
8613   /* Parse args required to build the message */
8614   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8615     {
8616       if (unformat (i, "del"))
8617         is_add = 0;
8618       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
8619         ;
8620       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
8621         ;
8622       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
8623         v4_address_set = 1;
8624       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
8625         v6_address_set = 1;
8626       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
8627         v4_src_address_set = 1;
8628       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
8629         v6_src_address_set = 1;
8630       else
8631         break;
8632     }
8633
8634   if (v4_address_set && v6_address_set)
8635     {
8636       errmsg ("both v4 and v6 server addresses set");
8637       return -99;
8638     }
8639   if (!v4_address_set && !v6_address_set)
8640     {
8641       errmsg ("no server addresses set");
8642       return -99;
8643     }
8644
8645   if (v4_src_address_set && v6_src_address_set)
8646     {
8647       errmsg ("both v4 and v6  src addresses set");
8648       return -99;
8649     }
8650   if (!v4_src_address_set && !v6_src_address_set)
8651     {
8652       errmsg ("no src addresses set");
8653       return -99;
8654     }
8655
8656   if (!(v4_src_address_set && v4_address_set) &&
8657       !(v6_src_address_set && v6_address_set))
8658     {
8659       errmsg ("no matching server and src addresses set");
8660       return -99;
8661     }
8662
8663   /* Construct the API message */
8664   M (DHCP_PROXY_CONFIG, mp);
8665
8666   mp->is_add = is_add;
8667   mp->rx_vrf_id = ntohl (rx_vrf_id);
8668   mp->server_vrf_id = ntohl (server_vrf_id);
8669   if (v6_address_set)
8670     {
8671       mp->is_ipv6 = 1;
8672       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
8673       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
8674     }
8675   else
8676     {
8677       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
8678       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
8679     }
8680
8681   /* send it... */
8682   S (mp);
8683
8684   /* Wait for a reply, return good/bad news  */
8685   W (ret);
8686   return ret;
8687 }
8688
8689 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
8690 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
8691
8692 static void
8693 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
8694 {
8695   vat_main_t *vam = &vat_main;
8696   u32 i, count = mp->count;
8697   vl_api_dhcp_server_t *s;
8698
8699   if (mp->is_ipv6)
8700     print (vam->ofp,
8701            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8702            ntohl (mp->rx_vrf_id),
8703            format_ip6_address, mp->dhcp_src_address,
8704            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8705   else
8706     print (vam->ofp,
8707            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8708            ntohl (mp->rx_vrf_id),
8709            format_ip4_address, mp->dhcp_src_address,
8710            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8711
8712   for (i = 0; i < count; i++)
8713     {
8714       s = &mp->servers[i];
8715
8716       if (mp->is_ipv6)
8717         print (vam->ofp,
8718                " Server Table-ID %d, Server Address %U",
8719                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
8720       else
8721         print (vam->ofp,
8722                " Server Table-ID %d, Server Address %U",
8723                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
8724     }
8725 }
8726
8727 static void vl_api_dhcp_proxy_details_t_handler_json
8728   (vl_api_dhcp_proxy_details_t * mp)
8729 {
8730   vat_main_t *vam = &vat_main;
8731   vat_json_node_t *node = NULL;
8732   u32 i, count = mp->count;
8733   struct in_addr ip4;
8734   struct in6_addr ip6;
8735   vl_api_dhcp_server_t *s;
8736
8737   if (VAT_JSON_ARRAY != vam->json_tree.type)
8738     {
8739       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8740       vat_json_init_array (&vam->json_tree);
8741     }
8742   node = vat_json_array_add (&vam->json_tree);
8743
8744   vat_json_init_object (node);
8745   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
8746   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
8747   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
8748
8749   if (mp->is_ipv6)
8750     {
8751       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
8752       vat_json_object_add_ip6 (node, "src_address", ip6);
8753     }
8754   else
8755     {
8756       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
8757       vat_json_object_add_ip4 (node, "src_address", ip4);
8758     }
8759
8760   for (i = 0; i < count; i++)
8761     {
8762       s = &mp->servers[i];
8763
8764       vat_json_object_add_uint (node, "server-table-id",
8765                                 ntohl (s->server_vrf_id));
8766
8767       if (mp->is_ipv6)
8768         {
8769           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
8770           vat_json_object_add_ip4 (node, "src_address", ip4);
8771         }
8772       else
8773         {
8774           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
8775           vat_json_object_add_ip6 (node, "server_address", ip6);
8776         }
8777     }
8778 }
8779
8780 static int
8781 api_dhcp_proxy_dump (vat_main_t * vam)
8782 {
8783   unformat_input_t *i = vam->input;
8784   vl_api_control_ping_t *mp_ping;
8785   vl_api_dhcp_proxy_dump_t *mp;
8786   u8 is_ipv6 = 0;
8787   int ret;
8788
8789   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8790     {
8791       if (unformat (i, "ipv6"))
8792         is_ipv6 = 1;
8793       else
8794         {
8795           clib_warning ("parse error '%U'", format_unformat_error, i);
8796           return -99;
8797         }
8798     }
8799
8800   M (DHCP_PROXY_DUMP, mp);
8801
8802   mp->is_ip6 = is_ipv6;
8803   S (mp);
8804
8805   /* Use a control ping for synchronization */
8806   M (CONTROL_PING, mp_ping);
8807   S (mp_ping);
8808
8809   W (ret);
8810   return ret;
8811 }
8812
8813 static int
8814 api_dhcp_proxy_set_vss (vat_main_t * vam)
8815 {
8816   unformat_input_t *i = vam->input;
8817   vl_api_dhcp_proxy_set_vss_t *mp;
8818   u8 is_ipv6 = 0;
8819   u8 is_add = 1;
8820   u32 tbl_id;
8821   u8 tbl_id_set = 0;
8822   u32 oui;
8823   u8 oui_set = 0;
8824   u32 fib_id;
8825   u8 fib_id_set = 0;
8826   int ret;
8827
8828   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8829     {
8830       if (unformat (i, "tbl_id %d", &tbl_id))
8831         tbl_id_set = 1;
8832       if (unformat (i, "fib_id %d", &fib_id))
8833         fib_id_set = 1;
8834       if (unformat (i, "oui %d", &oui))
8835         oui_set = 1;
8836       else if (unformat (i, "ipv6"))
8837         is_ipv6 = 1;
8838       else if (unformat (i, "del"))
8839         is_add = 0;
8840       else
8841         {
8842           clib_warning ("parse error '%U'", format_unformat_error, i);
8843           return -99;
8844         }
8845     }
8846
8847   if (tbl_id_set == 0)
8848     {
8849       errmsg ("missing tbl id");
8850       return -99;
8851     }
8852
8853   if (fib_id_set == 0)
8854     {
8855       errmsg ("missing fib id");
8856       return -99;
8857     }
8858   if (oui_set == 0)
8859     {
8860       errmsg ("missing oui");
8861       return -99;
8862     }
8863
8864   M (DHCP_PROXY_SET_VSS, mp);
8865   mp->tbl_id = ntohl (tbl_id);
8866   mp->fib_id = ntohl (fib_id);
8867   mp->oui = ntohl (oui);
8868   mp->is_ipv6 = is_ipv6;
8869   mp->is_add = is_add;
8870
8871   S (mp);
8872   W (ret);
8873   return ret;
8874 }
8875
8876 static int
8877 api_dhcp_client_config (vat_main_t * vam)
8878 {
8879   unformat_input_t *i = vam->input;
8880   vl_api_dhcp_client_config_t *mp;
8881   u32 sw_if_index;
8882   u8 sw_if_index_set = 0;
8883   u8 is_add = 1;
8884   u8 *hostname = 0;
8885   u8 disable_event = 0;
8886   int ret;
8887
8888   /* Parse args required to build the message */
8889   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8890     {
8891       if (unformat (i, "del"))
8892         is_add = 0;
8893       else
8894         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8895         sw_if_index_set = 1;
8896       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8897         sw_if_index_set = 1;
8898       else if (unformat (i, "hostname %s", &hostname))
8899         ;
8900       else if (unformat (i, "disable_event"))
8901         disable_event = 1;
8902       else
8903         break;
8904     }
8905
8906   if (sw_if_index_set == 0)
8907     {
8908       errmsg ("missing interface name or sw_if_index");
8909       return -99;
8910     }
8911
8912   if (vec_len (hostname) > 63)
8913     {
8914       errmsg ("hostname too long");
8915     }
8916   vec_add1 (hostname, 0);
8917
8918   /* Construct the API message */
8919   M (DHCP_CLIENT_CONFIG, mp);
8920
8921   mp->sw_if_index = htonl (sw_if_index);
8922   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
8923   vec_free (hostname);
8924   mp->is_add = is_add;
8925   mp->want_dhcp_event = disable_event ? 0 : 1;
8926   mp->pid = htonl (getpid ());
8927
8928   /* send it... */
8929   S (mp);
8930
8931   /* Wait for a reply, return good/bad news  */
8932   W (ret);
8933   return ret;
8934 }
8935
8936 static int
8937 api_set_ip_flow_hash (vat_main_t * vam)
8938 {
8939   unformat_input_t *i = vam->input;
8940   vl_api_set_ip_flow_hash_t *mp;
8941   u32 vrf_id = 0;
8942   u8 is_ipv6 = 0;
8943   u8 vrf_id_set = 0;
8944   u8 src = 0;
8945   u8 dst = 0;
8946   u8 sport = 0;
8947   u8 dport = 0;
8948   u8 proto = 0;
8949   u8 reverse = 0;
8950   int ret;
8951
8952   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8953     {
8954       if (unformat (i, "vrf %d", &vrf_id))
8955         vrf_id_set = 1;
8956       else if (unformat (i, "ipv6"))
8957         is_ipv6 = 1;
8958       else if (unformat (i, "src"))
8959         src = 1;
8960       else if (unformat (i, "dst"))
8961         dst = 1;
8962       else if (unformat (i, "sport"))
8963         sport = 1;
8964       else if (unformat (i, "dport"))
8965         dport = 1;
8966       else if (unformat (i, "proto"))
8967         proto = 1;
8968       else if (unformat (i, "reverse"))
8969         reverse = 1;
8970
8971       else
8972         {
8973           clib_warning ("parse error '%U'", format_unformat_error, i);
8974           return -99;
8975         }
8976     }
8977
8978   if (vrf_id_set == 0)
8979     {
8980       errmsg ("missing vrf id");
8981       return -99;
8982     }
8983
8984   M (SET_IP_FLOW_HASH, mp);
8985   mp->src = src;
8986   mp->dst = dst;
8987   mp->sport = sport;
8988   mp->dport = dport;
8989   mp->proto = proto;
8990   mp->reverse = reverse;
8991   mp->vrf_id = ntohl (vrf_id);
8992   mp->is_ipv6 = is_ipv6;
8993
8994   S (mp);
8995   W (ret);
8996   return ret;
8997 }
8998
8999 static int
9000 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9001 {
9002   unformat_input_t *i = vam->input;
9003   vl_api_sw_interface_ip6_enable_disable_t *mp;
9004   u32 sw_if_index;
9005   u8 sw_if_index_set = 0;
9006   u8 enable = 0;
9007   int ret;
9008
9009   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9010     {
9011       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9012         sw_if_index_set = 1;
9013       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9014         sw_if_index_set = 1;
9015       else if (unformat (i, "enable"))
9016         enable = 1;
9017       else if (unformat (i, "disable"))
9018         enable = 0;
9019       else
9020         {
9021           clib_warning ("parse error '%U'", format_unformat_error, i);
9022           return -99;
9023         }
9024     }
9025
9026   if (sw_if_index_set == 0)
9027     {
9028       errmsg ("missing interface name or sw_if_index");
9029       return -99;
9030     }
9031
9032   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9033
9034   mp->sw_if_index = ntohl (sw_if_index);
9035   mp->enable = enable;
9036
9037   S (mp);
9038   W (ret);
9039   return ret;
9040 }
9041
9042 static int
9043 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
9044 {
9045   unformat_input_t *i = vam->input;
9046   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
9047   u32 sw_if_index;
9048   u8 sw_if_index_set = 0;
9049   u8 v6_address_set = 0;
9050   ip6_address_t v6address;
9051   int ret;
9052
9053   /* Parse args required to build the message */
9054   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9055     {
9056       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9057         sw_if_index_set = 1;
9058       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9059         sw_if_index_set = 1;
9060       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9061         v6_address_set = 1;
9062       else
9063         break;
9064     }
9065
9066   if (sw_if_index_set == 0)
9067     {
9068       errmsg ("missing interface name or sw_if_index");
9069       return -99;
9070     }
9071   if (!v6_address_set)
9072     {
9073       errmsg ("no address set");
9074       return -99;
9075     }
9076
9077   /* Construct the API message */
9078   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
9079
9080   mp->sw_if_index = ntohl (sw_if_index);
9081   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9082
9083   /* send it... */
9084   S (mp);
9085
9086   /* Wait for a reply, return good/bad news  */
9087   W (ret);
9088   return ret;
9089 }
9090
9091 static int
9092 api_ip6nd_proxy_add_del (vat_main_t * vam)
9093 {
9094   unformat_input_t *i = vam->input;
9095   vl_api_ip6nd_proxy_add_del_t *mp;
9096   u32 sw_if_index = ~0;
9097   u8 v6_address_set = 0;
9098   ip6_address_t v6address;
9099   u8 is_del = 0;
9100   int ret;
9101
9102   /* Parse args required to build the message */
9103   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9104     {
9105       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9106         ;
9107       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9108         ;
9109       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9110         v6_address_set = 1;
9111       if (unformat (i, "del"))
9112         is_del = 1;
9113       else
9114         {
9115           clib_warning ("parse error '%U'", format_unformat_error, i);
9116           return -99;
9117         }
9118     }
9119
9120   if (sw_if_index == ~0)
9121     {
9122       errmsg ("missing interface name or sw_if_index");
9123       return -99;
9124     }
9125   if (!v6_address_set)
9126     {
9127       errmsg ("no address set");
9128       return -99;
9129     }
9130
9131   /* Construct the API message */
9132   M (IP6ND_PROXY_ADD_DEL, mp);
9133
9134   mp->is_del = is_del;
9135   mp->sw_if_index = ntohl (sw_if_index);
9136   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9137
9138   /* send it... */
9139   S (mp);
9140
9141   /* Wait for a reply, return good/bad news  */
9142   W (ret);
9143   return ret;
9144 }
9145
9146 static int
9147 api_ip6nd_proxy_dump (vat_main_t * vam)
9148 {
9149   vl_api_ip6nd_proxy_dump_t *mp;
9150   vl_api_control_ping_t *mp_ping;
9151   int ret;
9152
9153   M (IP6ND_PROXY_DUMP, mp);
9154
9155   S (mp);
9156
9157   /* Use a control ping for synchronization */
9158   M (CONTROL_PING, mp_ping);
9159   S (mp_ping);
9160
9161   W (ret);
9162   return ret;
9163 }
9164
9165 static void vl_api_ip6nd_proxy_details_t_handler
9166   (vl_api_ip6nd_proxy_details_t * mp)
9167 {
9168   vat_main_t *vam = &vat_main;
9169
9170   print (vam->ofp, "host %U sw_if_index %d",
9171          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
9172 }
9173
9174 static void vl_api_ip6nd_proxy_details_t_handler_json
9175   (vl_api_ip6nd_proxy_details_t * mp)
9176 {
9177   vat_main_t *vam = &vat_main;
9178   struct in6_addr ip6;
9179   vat_json_node_t *node = NULL;
9180
9181   if (VAT_JSON_ARRAY != vam->json_tree.type)
9182     {
9183       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9184       vat_json_init_array (&vam->json_tree);
9185     }
9186   node = vat_json_array_add (&vam->json_tree);
9187
9188   vat_json_init_object (node);
9189   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9190
9191   clib_memcpy (&ip6, mp->address, sizeof (ip6));
9192   vat_json_object_add_ip6 (node, "host", ip6);
9193 }
9194
9195 static int
9196 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9197 {
9198   unformat_input_t *i = vam->input;
9199   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9200   u32 sw_if_index;
9201   u8 sw_if_index_set = 0;
9202   u32 address_length = 0;
9203   u8 v6_address_set = 0;
9204   ip6_address_t v6address;
9205   u8 use_default = 0;
9206   u8 no_advertise = 0;
9207   u8 off_link = 0;
9208   u8 no_autoconfig = 0;
9209   u8 no_onlink = 0;
9210   u8 is_no = 0;
9211   u32 val_lifetime = 0;
9212   u32 pref_lifetime = 0;
9213   int ret;
9214
9215   /* Parse args required to build the message */
9216   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9217     {
9218       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9219         sw_if_index_set = 1;
9220       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9221         sw_if_index_set = 1;
9222       else if (unformat (i, "%U/%d",
9223                          unformat_ip6_address, &v6address, &address_length))
9224         v6_address_set = 1;
9225       else if (unformat (i, "val_life %d", &val_lifetime))
9226         ;
9227       else if (unformat (i, "pref_life %d", &pref_lifetime))
9228         ;
9229       else if (unformat (i, "def"))
9230         use_default = 1;
9231       else if (unformat (i, "noadv"))
9232         no_advertise = 1;
9233       else if (unformat (i, "offl"))
9234         off_link = 1;
9235       else if (unformat (i, "noauto"))
9236         no_autoconfig = 1;
9237       else if (unformat (i, "nolink"))
9238         no_onlink = 1;
9239       else if (unformat (i, "isno"))
9240         is_no = 1;
9241       else
9242         {
9243           clib_warning ("parse error '%U'", format_unformat_error, i);
9244           return -99;
9245         }
9246     }
9247
9248   if (sw_if_index_set == 0)
9249     {
9250       errmsg ("missing interface name or sw_if_index");
9251       return -99;
9252     }
9253   if (!v6_address_set)
9254     {
9255       errmsg ("no address set");
9256       return -99;
9257     }
9258
9259   /* Construct the API message */
9260   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9261
9262   mp->sw_if_index = ntohl (sw_if_index);
9263   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9264   mp->address_length = address_length;
9265   mp->use_default = use_default;
9266   mp->no_advertise = no_advertise;
9267   mp->off_link = off_link;
9268   mp->no_autoconfig = no_autoconfig;
9269   mp->no_onlink = no_onlink;
9270   mp->is_no = is_no;
9271   mp->val_lifetime = ntohl (val_lifetime);
9272   mp->pref_lifetime = ntohl (pref_lifetime);
9273
9274   /* send it... */
9275   S (mp);
9276
9277   /* Wait for a reply, return good/bad news  */
9278   W (ret);
9279   return ret;
9280 }
9281
9282 static int
9283 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9284 {
9285   unformat_input_t *i = vam->input;
9286   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9287   u32 sw_if_index;
9288   u8 sw_if_index_set = 0;
9289   u8 suppress = 0;
9290   u8 managed = 0;
9291   u8 other = 0;
9292   u8 ll_option = 0;
9293   u8 send_unicast = 0;
9294   u8 cease = 0;
9295   u8 is_no = 0;
9296   u8 default_router = 0;
9297   u32 max_interval = 0;
9298   u32 min_interval = 0;
9299   u32 lifetime = 0;
9300   u32 initial_count = 0;
9301   u32 initial_interval = 0;
9302   int ret;
9303
9304
9305   /* Parse args required to build the message */
9306   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9307     {
9308       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9309         sw_if_index_set = 1;
9310       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9311         sw_if_index_set = 1;
9312       else if (unformat (i, "maxint %d", &max_interval))
9313         ;
9314       else if (unformat (i, "minint %d", &min_interval))
9315         ;
9316       else if (unformat (i, "life %d", &lifetime))
9317         ;
9318       else if (unformat (i, "count %d", &initial_count))
9319         ;
9320       else if (unformat (i, "interval %d", &initial_interval))
9321         ;
9322       else if (unformat (i, "suppress") || unformat (i, "surpress"))
9323         suppress = 1;
9324       else if (unformat (i, "managed"))
9325         managed = 1;
9326       else if (unformat (i, "other"))
9327         other = 1;
9328       else if (unformat (i, "ll"))
9329         ll_option = 1;
9330       else if (unformat (i, "send"))
9331         send_unicast = 1;
9332       else if (unformat (i, "cease"))
9333         cease = 1;
9334       else if (unformat (i, "isno"))
9335         is_no = 1;
9336       else if (unformat (i, "def"))
9337         default_router = 1;
9338       else
9339         {
9340           clib_warning ("parse error '%U'", format_unformat_error, i);
9341           return -99;
9342         }
9343     }
9344
9345   if (sw_if_index_set == 0)
9346     {
9347       errmsg ("missing interface name or sw_if_index");
9348       return -99;
9349     }
9350
9351   /* Construct the API message */
9352   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
9353
9354   mp->sw_if_index = ntohl (sw_if_index);
9355   mp->max_interval = ntohl (max_interval);
9356   mp->min_interval = ntohl (min_interval);
9357   mp->lifetime = ntohl (lifetime);
9358   mp->initial_count = ntohl (initial_count);
9359   mp->initial_interval = ntohl (initial_interval);
9360   mp->suppress = suppress;
9361   mp->managed = managed;
9362   mp->other = other;
9363   mp->ll_option = ll_option;
9364   mp->send_unicast = send_unicast;
9365   mp->cease = cease;
9366   mp->is_no = is_no;
9367   mp->default_router = default_router;
9368
9369   /* send it... */
9370   S (mp);
9371
9372   /* Wait for a reply, return good/bad news  */
9373   W (ret);
9374   return ret;
9375 }
9376
9377 static int
9378 api_set_arp_neighbor_limit (vat_main_t * vam)
9379 {
9380   unformat_input_t *i = vam->input;
9381   vl_api_set_arp_neighbor_limit_t *mp;
9382   u32 arp_nbr_limit;
9383   u8 limit_set = 0;
9384   u8 is_ipv6 = 0;
9385   int ret;
9386
9387   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9388     {
9389       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
9390         limit_set = 1;
9391       else if (unformat (i, "ipv6"))
9392         is_ipv6 = 1;
9393       else
9394         {
9395           clib_warning ("parse error '%U'", format_unformat_error, i);
9396           return -99;
9397         }
9398     }
9399
9400   if (limit_set == 0)
9401     {
9402       errmsg ("missing limit value");
9403       return -99;
9404     }
9405
9406   M (SET_ARP_NEIGHBOR_LIMIT, mp);
9407
9408   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
9409   mp->is_ipv6 = is_ipv6;
9410
9411   S (mp);
9412   W (ret);
9413   return ret;
9414 }
9415
9416 static int
9417 api_l2_patch_add_del (vat_main_t * vam)
9418 {
9419   unformat_input_t *i = vam->input;
9420   vl_api_l2_patch_add_del_t *mp;
9421   u32 rx_sw_if_index;
9422   u8 rx_sw_if_index_set = 0;
9423   u32 tx_sw_if_index;
9424   u8 tx_sw_if_index_set = 0;
9425   u8 is_add = 1;
9426   int ret;
9427
9428   /* Parse args required to build the message */
9429   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9430     {
9431       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9432         rx_sw_if_index_set = 1;
9433       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9434         tx_sw_if_index_set = 1;
9435       else if (unformat (i, "rx"))
9436         {
9437           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9438             {
9439               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9440                             &rx_sw_if_index))
9441                 rx_sw_if_index_set = 1;
9442             }
9443           else
9444             break;
9445         }
9446       else if (unformat (i, "tx"))
9447         {
9448           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9449             {
9450               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9451                             &tx_sw_if_index))
9452                 tx_sw_if_index_set = 1;
9453             }
9454           else
9455             break;
9456         }
9457       else if (unformat (i, "del"))
9458         is_add = 0;
9459       else
9460         break;
9461     }
9462
9463   if (rx_sw_if_index_set == 0)
9464     {
9465       errmsg ("missing rx interface name or rx_sw_if_index");
9466       return -99;
9467     }
9468
9469   if (tx_sw_if_index_set == 0)
9470     {
9471       errmsg ("missing tx interface name or tx_sw_if_index");
9472       return -99;
9473     }
9474
9475   M (L2_PATCH_ADD_DEL, mp);
9476
9477   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9478   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9479   mp->is_add = is_add;
9480
9481   S (mp);
9482   W (ret);
9483   return ret;
9484 }
9485
9486 u8 is_del;
9487 u8 localsid_addr[16];
9488 u8 end_psp;
9489 u8 behavior;
9490 u32 sw_if_index;
9491 u32 vlan_index;
9492 u32 fib_table;
9493 u8 nh_addr[16];
9494
9495 static int
9496 api_sr_localsid_add_del (vat_main_t * vam)
9497 {
9498   unformat_input_t *i = vam->input;
9499   vl_api_sr_localsid_add_del_t *mp;
9500
9501   u8 is_del;
9502   ip6_address_t localsid;
9503   u8 end_psp = 0;
9504   u8 behavior = ~0;
9505   u32 sw_if_index;
9506   u32 fib_table = ~(u32) 0;
9507   ip6_address_t next_hop;
9508
9509   bool nexthop_set = 0;
9510
9511   int ret;
9512
9513   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9514     {
9515       if (unformat (i, "del"))
9516         is_del = 1;
9517       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9518       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
9519         nexthop_set = 1;
9520       else if (unformat (i, "behavior %u", &behavior));
9521       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9522       else if (unformat (i, "fib-table %u", &fib_table));
9523       else if (unformat (i, "end.psp %u", &behavior));
9524       else
9525         break;
9526     }
9527
9528   M (SR_LOCALSID_ADD_DEL, mp);
9529
9530   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
9531   if (nexthop_set)
9532     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
9533   mp->behavior = behavior;
9534   mp->sw_if_index = ntohl (sw_if_index);
9535   mp->fib_table = ntohl (fib_table);
9536   mp->end_psp = end_psp;
9537   mp->is_del = is_del;
9538
9539   S (mp);
9540   W (ret);
9541   return ret;
9542 }
9543
9544 static int
9545 api_ioam_enable (vat_main_t * vam)
9546 {
9547   unformat_input_t *input = vam->input;
9548   vl_api_ioam_enable_t *mp;
9549   u32 id = 0;
9550   int has_trace_option = 0;
9551   int has_pot_option = 0;
9552   int has_seqno_option = 0;
9553   int has_analyse_option = 0;
9554   int ret;
9555
9556   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9557     {
9558       if (unformat (input, "trace"))
9559         has_trace_option = 1;
9560       else if (unformat (input, "pot"))
9561         has_pot_option = 1;
9562       else if (unformat (input, "seqno"))
9563         has_seqno_option = 1;
9564       else if (unformat (input, "analyse"))
9565         has_analyse_option = 1;
9566       else
9567         break;
9568     }
9569   M (IOAM_ENABLE, mp);
9570   mp->id = htons (id);
9571   mp->seqno = has_seqno_option;
9572   mp->analyse = has_analyse_option;
9573   mp->pot_enable = has_pot_option;
9574   mp->trace_enable = has_trace_option;
9575
9576   S (mp);
9577   W (ret);
9578   return ret;
9579 }
9580
9581
9582 static int
9583 api_ioam_disable (vat_main_t * vam)
9584 {
9585   vl_api_ioam_disable_t *mp;
9586   int ret;
9587
9588   M (IOAM_DISABLE, mp);
9589   S (mp);
9590   W (ret);
9591   return ret;
9592 }
9593
9594 #define foreach_tcp_proto_field                 \
9595 _(src_port)                                     \
9596 _(dst_port)
9597
9598 #define foreach_udp_proto_field                 \
9599 _(src_port)                                     \
9600 _(dst_port)
9601
9602 #define foreach_ip4_proto_field                 \
9603 _(src_address)                                  \
9604 _(dst_address)                                  \
9605 _(tos)                                          \
9606 _(length)                                       \
9607 _(fragment_id)                                  \
9608 _(ttl)                                          \
9609 _(protocol)                                     \
9610 _(checksum)
9611
9612 typedef struct
9613 {
9614   u16 src_port, dst_port;
9615 } tcpudp_header_t;
9616
9617 #if VPP_API_TEST_BUILTIN == 0
9618 uword
9619 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9620 {
9621   u8 **maskp = va_arg (*args, u8 **);
9622   u8 *mask = 0;
9623   u8 found_something = 0;
9624   tcp_header_t *tcp;
9625
9626 #define _(a) u8 a=0;
9627   foreach_tcp_proto_field;
9628 #undef _
9629
9630   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9631     {
9632       if (0);
9633 #define _(a) else if (unformat (input, #a)) a=1;
9634       foreach_tcp_proto_field
9635 #undef _
9636         else
9637         break;
9638     }
9639
9640 #define _(a) found_something += a;
9641   foreach_tcp_proto_field;
9642 #undef _
9643
9644   if (found_something == 0)
9645     return 0;
9646
9647   vec_validate (mask, sizeof (*tcp) - 1);
9648
9649   tcp = (tcp_header_t *) mask;
9650
9651 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
9652   foreach_tcp_proto_field;
9653 #undef _
9654
9655   *maskp = mask;
9656   return 1;
9657 }
9658
9659 uword
9660 unformat_udp_mask (unformat_input_t * input, va_list * args)
9661 {
9662   u8 **maskp = va_arg (*args, u8 **);
9663   u8 *mask = 0;
9664   u8 found_something = 0;
9665   udp_header_t *udp;
9666
9667 #define _(a) u8 a=0;
9668   foreach_udp_proto_field;
9669 #undef _
9670
9671   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9672     {
9673       if (0);
9674 #define _(a) else if (unformat (input, #a)) a=1;
9675       foreach_udp_proto_field
9676 #undef _
9677         else
9678         break;
9679     }
9680
9681 #define _(a) found_something += a;
9682   foreach_udp_proto_field;
9683 #undef _
9684
9685   if (found_something == 0)
9686     return 0;
9687
9688   vec_validate (mask, sizeof (*udp) - 1);
9689
9690   udp = (udp_header_t *) mask;
9691
9692 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
9693   foreach_udp_proto_field;
9694 #undef _
9695
9696   *maskp = mask;
9697   return 1;
9698 }
9699
9700 uword
9701 unformat_l4_mask (unformat_input_t * input, va_list * args)
9702 {
9703   u8 **maskp = va_arg (*args, u8 **);
9704   u16 src_port = 0, dst_port = 0;
9705   tcpudp_header_t *tcpudp;
9706
9707   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9708     {
9709       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9710         return 1;
9711       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9712         return 1;
9713       else if (unformat (input, "src_port"))
9714         src_port = 0xFFFF;
9715       else if (unformat (input, "dst_port"))
9716         dst_port = 0xFFFF;
9717       else
9718         return 0;
9719     }
9720
9721   if (!src_port && !dst_port)
9722     return 0;
9723
9724   u8 *mask = 0;
9725   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9726
9727   tcpudp = (tcpudp_header_t *) mask;
9728   tcpudp->src_port = src_port;
9729   tcpudp->dst_port = dst_port;
9730
9731   *maskp = mask;
9732
9733   return 1;
9734 }
9735
9736 uword
9737 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9738 {
9739   u8 **maskp = va_arg (*args, u8 **);
9740   u8 *mask = 0;
9741   u8 found_something = 0;
9742   ip4_header_t *ip;
9743
9744 #define _(a) u8 a=0;
9745   foreach_ip4_proto_field;
9746 #undef _
9747   u8 version = 0;
9748   u8 hdr_length = 0;
9749
9750
9751   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9752     {
9753       if (unformat (input, "version"))
9754         version = 1;
9755       else if (unformat (input, "hdr_length"))
9756         hdr_length = 1;
9757       else if (unformat (input, "src"))
9758         src_address = 1;
9759       else if (unformat (input, "dst"))
9760         dst_address = 1;
9761       else if (unformat (input, "proto"))
9762         protocol = 1;
9763
9764 #define _(a) else if (unformat (input, #a)) a=1;
9765       foreach_ip4_proto_field
9766 #undef _
9767         else
9768         break;
9769     }
9770
9771 #define _(a) found_something += a;
9772   foreach_ip4_proto_field;
9773 #undef _
9774
9775   if (found_something == 0)
9776     return 0;
9777
9778   vec_validate (mask, sizeof (*ip) - 1);
9779
9780   ip = (ip4_header_t *) mask;
9781
9782 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9783   foreach_ip4_proto_field;
9784 #undef _
9785
9786   ip->ip_version_and_header_length = 0;
9787
9788   if (version)
9789     ip->ip_version_and_header_length |= 0xF0;
9790
9791   if (hdr_length)
9792     ip->ip_version_and_header_length |= 0x0F;
9793
9794   *maskp = mask;
9795   return 1;
9796 }
9797
9798 #define foreach_ip6_proto_field                 \
9799 _(src_address)                                  \
9800 _(dst_address)                                  \
9801 _(payload_length)                               \
9802 _(hop_limit)                                    \
9803 _(protocol)
9804
9805 uword
9806 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9807 {
9808   u8 **maskp = va_arg (*args, u8 **);
9809   u8 *mask = 0;
9810   u8 found_something = 0;
9811   ip6_header_t *ip;
9812   u32 ip_version_traffic_class_and_flow_label;
9813
9814 #define _(a) u8 a=0;
9815   foreach_ip6_proto_field;
9816 #undef _
9817   u8 version = 0;
9818   u8 traffic_class = 0;
9819   u8 flow_label = 0;
9820
9821   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9822     {
9823       if (unformat (input, "version"))
9824         version = 1;
9825       else if (unformat (input, "traffic-class"))
9826         traffic_class = 1;
9827       else if (unformat (input, "flow-label"))
9828         flow_label = 1;
9829       else if (unformat (input, "src"))
9830         src_address = 1;
9831       else if (unformat (input, "dst"))
9832         dst_address = 1;
9833       else if (unformat (input, "proto"))
9834         protocol = 1;
9835
9836 #define _(a) else if (unformat (input, #a)) a=1;
9837       foreach_ip6_proto_field
9838 #undef _
9839         else
9840         break;
9841     }
9842
9843 #define _(a) found_something += a;
9844   foreach_ip6_proto_field;
9845 #undef _
9846
9847   if (found_something == 0)
9848     return 0;
9849
9850   vec_validate (mask, sizeof (*ip) - 1);
9851
9852   ip = (ip6_header_t *) mask;
9853
9854 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9855   foreach_ip6_proto_field;
9856 #undef _
9857
9858   ip_version_traffic_class_and_flow_label = 0;
9859
9860   if (version)
9861     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9862
9863   if (traffic_class)
9864     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9865
9866   if (flow_label)
9867     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9868
9869   ip->ip_version_traffic_class_and_flow_label =
9870     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9871
9872   *maskp = mask;
9873   return 1;
9874 }
9875
9876 uword
9877 unformat_l3_mask (unformat_input_t * input, va_list * args)
9878 {
9879   u8 **maskp = va_arg (*args, u8 **);
9880
9881   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9882     {
9883       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9884         return 1;
9885       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9886         return 1;
9887       else
9888         break;
9889     }
9890   return 0;
9891 }
9892
9893 uword
9894 unformat_l2_mask (unformat_input_t * input, va_list * args)
9895 {
9896   u8 **maskp = va_arg (*args, u8 **);
9897   u8 *mask = 0;
9898   u8 src = 0;
9899   u8 dst = 0;
9900   u8 proto = 0;
9901   u8 tag1 = 0;
9902   u8 tag2 = 0;
9903   u8 ignore_tag1 = 0;
9904   u8 ignore_tag2 = 0;
9905   u8 cos1 = 0;
9906   u8 cos2 = 0;
9907   u8 dot1q = 0;
9908   u8 dot1ad = 0;
9909   int len = 14;
9910
9911   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9912     {
9913       if (unformat (input, "src"))
9914         src = 1;
9915       else if (unformat (input, "dst"))
9916         dst = 1;
9917       else if (unformat (input, "proto"))
9918         proto = 1;
9919       else if (unformat (input, "tag1"))
9920         tag1 = 1;
9921       else if (unformat (input, "tag2"))
9922         tag2 = 1;
9923       else if (unformat (input, "ignore-tag1"))
9924         ignore_tag1 = 1;
9925       else if (unformat (input, "ignore-tag2"))
9926         ignore_tag2 = 1;
9927       else if (unformat (input, "cos1"))
9928         cos1 = 1;
9929       else if (unformat (input, "cos2"))
9930         cos2 = 1;
9931       else if (unformat (input, "dot1q"))
9932         dot1q = 1;
9933       else if (unformat (input, "dot1ad"))
9934         dot1ad = 1;
9935       else
9936         break;
9937     }
9938   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9939        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9940     return 0;
9941
9942   if (tag1 || ignore_tag1 || cos1 || dot1q)
9943     len = 18;
9944   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9945     len = 22;
9946
9947   vec_validate (mask, len - 1);
9948
9949   if (dst)
9950     memset (mask, 0xff, 6);
9951
9952   if (src)
9953     memset (mask + 6, 0xff, 6);
9954
9955   if (tag2 || dot1ad)
9956     {
9957       /* inner vlan tag */
9958       if (tag2)
9959         {
9960           mask[19] = 0xff;
9961           mask[18] = 0x0f;
9962         }
9963       if (cos2)
9964         mask[18] |= 0xe0;
9965       if (proto)
9966         mask[21] = mask[20] = 0xff;
9967       if (tag1)
9968         {
9969           mask[15] = 0xff;
9970           mask[14] = 0x0f;
9971         }
9972       if (cos1)
9973         mask[14] |= 0xe0;
9974       *maskp = mask;
9975       return 1;
9976     }
9977   if (tag1 | dot1q)
9978     {
9979       if (tag1)
9980         {
9981           mask[15] = 0xff;
9982           mask[14] = 0x0f;
9983         }
9984       if (cos1)
9985         mask[14] |= 0xe0;
9986       if (proto)
9987         mask[16] = mask[17] = 0xff;
9988
9989       *maskp = mask;
9990       return 1;
9991     }
9992   if (cos2)
9993     mask[18] |= 0xe0;
9994   if (cos1)
9995     mask[14] |= 0xe0;
9996   if (proto)
9997     mask[12] = mask[13] = 0xff;
9998
9999   *maskp = mask;
10000   return 1;
10001 }
10002
10003 uword
10004 unformat_classify_mask (unformat_input_t * input, va_list * args)
10005 {
10006   u8 **maskp = va_arg (*args, u8 **);
10007   u32 *skipp = va_arg (*args, u32 *);
10008   u32 *matchp = va_arg (*args, u32 *);
10009   u32 match;
10010   u8 *mask = 0;
10011   u8 *l2 = 0;
10012   u8 *l3 = 0;
10013   u8 *l4 = 0;
10014   int i;
10015
10016   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10017     {
10018       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10019         ;
10020       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10021         ;
10022       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10023         ;
10024       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10025         ;
10026       else
10027         break;
10028     }
10029
10030   if (l4 && !l3)
10031     {
10032       vec_free (mask);
10033       vec_free (l2);
10034       vec_free (l4);
10035       return 0;
10036     }
10037
10038   if (mask || l2 || l3 || l4)
10039     {
10040       if (l2 || l3 || l4)
10041         {
10042           /* "With a free Ethernet header in every package" */
10043           if (l2 == 0)
10044             vec_validate (l2, 13);
10045           mask = l2;
10046           if (vec_len (l3))
10047             {
10048               vec_append (mask, l3);
10049               vec_free (l3);
10050             }
10051           if (vec_len (l4))
10052             {
10053               vec_append (mask, l4);
10054               vec_free (l4);
10055             }
10056         }
10057
10058       /* Scan forward looking for the first significant mask octet */
10059       for (i = 0; i < vec_len (mask); i++)
10060         if (mask[i])
10061           break;
10062
10063       /* compute (skip, match) params */
10064       *skipp = i / sizeof (u32x4);
10065       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10066
10067       /* Pad mask to an even multiple of the vector size */
10068       while (vec_len (mask) % sizeof (u32x4))
10069         vec_add1 (mask, 0);
10070
10071       match = vec_len (mask) / sizeof (u32x4);
10072
10073       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10074         {
10075           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10076           if (*tmp || *(tmp + 1))
10077             break;
10078           match--;
10079         }
10080       if (match == 0)
10081         clib_warning ("BUG: match 0");
10082
10083       _vec_len (mask) = match * sizeof (u32x4);
10084
10085       *matchp = match;
10086       *maskp = mask;
10087
10088       return 1;
10089     }
10090
10091   return 0;
10092 }
10093 #endif /* VPP_API_TEST_BUILTIN */
10094
10095 #define foreach_l2_next                         \
10096 _(drop, DROP)                                   \
10097 _(ethernet, ETHERNET_INPUT)                     \
10098 _(ip4, IP4_INPUT)                               \
10099 _(ip6, IP6_INPUT)
10100
10101 uword
10102 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10103 {
10104   u32 *miss_next_indexp = va_arg (*args, u32 *);
10105   u32 next_index = 0;
10106   u32 tmp;
10107
10108 #define _(n,N) \
10109   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10110   foreach_l2_next;
10111 #undef _
10112
10113   if (unformat (input, "%d", &tmp))
10114     {
10115       next_index = tmp;
10116       goto out;
10117     }
10118
10119   return 0;
10120
10121 out:
10122   *miss_next_indexp = next_index;
10123   return 1;
10124 }
10125
10126 #define foreach_ip_next                         \
10127 _(drop, DROP)                                   \
10128 _(local, LOCAL)                                 \
10129 _(rewrite, REWRITE)
10130
10131 uword
10132 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10133 {
10134   u32 *miss_next_indexp = va_arg (*args, u32 *);
10135   u32 next_index = 0;
10136   u32 tmp;
10137
10138 #define _(n,N) \
10139   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10140   foreach_ip_next;
10141 #undef _
10142
10143   if (unformat (input, "%d", &tmp))
10144     {
10145       next_index = tmp;
10146       goto out;
10147     }
10148
10149   return 0;
10150
10151 out:
10152   *miss_next_indexp = next_index;
10153   return 1;
10154 }
10155
10156 #define foreach_acl_next                        \
10157 _(deny, DENY)
10158
10159 uword
10160 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10161 {
10162   u32 *miss_next_indexp = va_arg (*args, u32 *);
10163   u32 next_index = 0;
10164   u32 tmp;
10165
10166 #define _(n,N) \
10167   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10168   foreach_acl_next;
10169 #undef _
10170
10171   if (unformat (input, "permit"))
10172     {
10173       next_index = ~0;
10174       goto out;
10175     }
10176   else if (unformat (input, "%d", &tmp))
10177     {
10178       next_index = tmp;
10179       goto out;
10180     }
10181
10182   return 0;
10183
10184 out:
10185   *miss_next_indexp = next_index;
10186   return 1;
10187 }
10188
10189 uword
10190 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10191 {
10192   u32 *r = va_arg (*args, u32 *);
10193
10194   if (unformat (input, "conform-color"))
10195     *r = POLICE_CONFORM;
10196   else if (unformat (input, "exceed-color"))
10197     *r = POLICE_EXCEED;
10198   else
10199     return 0;
10200
10201   return 1;
10202 }
10203
10204 static int
10205 api_classify_add_del_table (vat_main_t * vam)
10206 {
10207   unformat_input_t *i = vam->input;
10208   vl_api_classify_add_del_table_t *mp;
10209
10210   u32 nbuckets = 2;
10211   u32 skip = ~0;
10212   u32 match = ~0;
10213   int is_add = 1;
10214   int del_chain = 0;
10215   u32 table_index = ~0;
10216   u32 next_table_index = ~0;
10217   u32 miss_next_index = ~0;
10218   u32 memory_size = 32 << 20;
10219   u8 *mask = 0;
10220   u32 current_data_flag = 0;
10221   int current_data_offset = 0;
10222   int ret;
10223
10224   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10225     {
10226       if (unformat (i, "del"))
10227         is_add = 0;
10228       else if (unformat (i, "del-chain"))
10229         {
10230           is_add = 0;
10231           del_chain = 1;
10232         }
10233       else if (unformat (i, "buckets %d", &nbuckets))
10234         ;
10235       else if (unformat (i, "memory_size %d", &memory_size))
10236         ;
10237       else if (unformat (i, "skip %d", &skip))
10238         ;
10239       else if (unformat (i, "match %d", &match))
10240         ;
10241       else if (unformat (i, "table %d", &table_index))
10242         ;
10243       else if (unformat (i, "mask %U", unformat_classify_mask,
10244                          &mask, &skip, &match))
10245         ;
10246       else if (unformat (i, "next-table %d", &next_table_index))
10247         ;
10248       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10249                          &miss_next_index))
10250         ;
10251       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10252                          &miss_next_index))
10253         ;
10254       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10255                          &miss_next_index))
10256         ;
10257       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10258         ;
10259       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10260         ;
10261       else
10262         break;
10263     }
10264
10265   if (is_add && mask == 0)
10266     {
10267       errmsg ("Mask required");
10268       return -99;
10269     }
10270
10271   if (is_add && skip == ~0)
10272     {
10273       errmsg ("skip count required");
10274       return -99;
10275     }
10276
10277   if (is_add && match == ~0)
10278     {
10279       errmsg ("match count required");
10280       return -99;
10281     }
10282
10283   if (!is_add && table_index == ~0)
10284     {
10285       errmsg ("table index required for delete");
10286       return -99;
10287     }
10288
10289   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10290
10291   mp->is_add = is_add;
10292   mp->del_chain = del_chain;
10293   mp->table_index = ntohl (table_index);
10294   mp->nbuckets = ntohl (nbuckets);
10295   mp->memory_size = ntohl (memory_size);
10296   mp->skip_n_vectors = ntohl (skip);
10297   mp->match_n_vectors = ntohl (match);
10298   mp->next_table_index = ntohl (next_table_index);
10299   mp->miss_next_index = ntohl (miss_next_index);
10300   mp->current_data_flag = ntohl (current_data_flag);
10301   mp->current_data_offset = ntohl (current_data_offset);
10302   clib_memcpy (mp->mask, mask, vec_len (mask));
10303
10304   vec_free (mask);
10305
10306   S (mp);
10307   W (ret);
10308   return ret;
10309 }
10310
10311 #if VPP_API_TEST_BUILTIN == 0
10312 uword
10313 unformat_l4_match (unformat_input_t * input, va_list * args)
10314 {
10315   u8 **matchp = va_arg (*args, u8 **);
10316
10317   u8 *proto_header = 0;
10318   int src_port = 0;
10319   int dst_port = 0;
10320
10321   tcpudp_header_t h;
10322
10323   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10324     {
10325       if (unformat (input, "src_port %d", &src_port))
10326         ;
10327       else if (unformat (input, "dst_port %d", &dst_port))
10328         ;
10329       else
10330         return 0;
10331     }
10332
10333   h.src_port = clib_host_to_net_u16 (src_port);
10334   h.dst_port = clib_host_to_net_u16 (dst_port);
10335   vec_validate (proto_header, sizeof (h) - 1);
10336   memcpy (proto_header, &h, sizeof (h));
10337
10338   *matchp = proto_header;
10339
10340   return 1;
10341 }
10342
10343 uword
10344 unformat_ip4_match (unformat_input_t * input, va_list * args)
10345 {
10346   u8 **matchp = va_arg (*args, u8 **);
10347   u8 *match = 0;
10348   ip4_header_t *ip;
10349   int version = 0;
10350   u32 version_val;
10351   int hdr_length = 0;
10352   u32 hdr_length_val;
10353   int src = 0, dst = 0;
10354   ip4_address_t src_val, dst_val;
10355   int proto = 0;
10356   u32 proto_val;
10357   int tos = 0;
10358   u32 tos_val;
10359   int length = 0;
10360   u32 length_val;
10361   int fragment_id = 0;
10362   u32 fragment_id_val;
10363   int ttl = 0;
10364   int ttl_val;
10365   int checksum = 0;
10366   u32 checksum_val;
10367
10368   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10369     {
10370       if (unformat (input, "version %d", &version_val))
10371         version = 1;
10372       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10373         hdr_length = 1;
10374       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10375         src = 1;
10376       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10377         dst = 1;
10378       else if (unformat (input, "proto %d", &proto_val))
10379         proto = 1;
10380       else if (unformat (input, "tos %d", &tos_val))
10381         tos = 1;
10382       else if (unformat (input, "length %d", &length_val))
10383         length = 1;
10384       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10385         fragment_id = 1;
10386       else if (unformat (input, "ttl %d", &ttl_val))
10387         ttl = 1;
10388       else if (unformat (input, "checksum %d", &checksum_val))
10389         checksum = 1;
10390       else
10391         break;
10392     }
10393
10394   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10395       + ttl + checksum == 0)
10396     return 0;
10397
10398   /*
10399    * Aligned because we use the real comparison functions
10400    */
10401   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10402
10403   ip = (ip4_header_t *) match;
10404
10405   /* These are realistically matched in practice */
10406   if (src)
10407     ip->src_address.as_u32 = src_val.as_u32;
10408
10409   if (dst)
10410     ip->dst_address.as_u32 = dst_val.as_u32;
10411
10412   if (proto)
10413     ip->protocol = proto_val;
10414
10415
10416   /* These are not, but they're included for completeness */
10417   if (version)
10418     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10419
10420   if (hdr_length)
10421     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10422
10423   if (tos)
10424     ip->tos = tos_val;
10425
10426   if (length)
10427     ip->length = clib_host_to_net_u16 (length_val);
10428
10429   if (ttl)
10430     ip->ttl = ttl_val;
10431
10432   if (checksum)
10433     ip->checksum = clib_host_to_net_u16 (checksum_val);
10434
10435   *matchp = match;
10436   return 1;
10437 }
10438
10439 uword
10440 unformat_ip6_match (unformat_input_t * input, va_list * args)
10441 {
10442   u8 **matchp = va_arg (*args, u8 **);
10443   u8 *match = 0;
10444   ip6_header_t *ip;
10445   int version = 0;
10446   u32 version_val;
10447   u8 traffic_class = 0;
10448   u32 traffic_class_val = 0;
10449   u8 flow_label = 0;
10450   u8 flow_label_val;
10451   int src = 0, dst = 0;
10452   ip6_address_t src_val, dst_val;
10453   int proto = 0;
10454   u32 proto_val;
10455   int payload_length = 0;
10456   u32 payload_length_val;
10457   int hop_limit = 0;
10458   int hop_limit_val;
10459   u32 ip_version_traffic_class_and_flow_label;
10460
10461   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10462     {
10463       if (unformat (input, "version %d", &version_val))
10464         version = 1;
10465       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10466         traffic_class = 1;
10467       else if (unformat (input, "flow_label %d", &flow_label_val))
10468         flow_label = 1;
10469       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10470         src = 1;
10471       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10472         dst = 1;
10473       else if (unformat (input, "proto %d", &proto_val))
10474         proto = 1;
10475       else if (unformat (input, "payload_length %d", &payload_length_val))
10476         payload_length = 1;
10477       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10478         hop_limit = 1;
10479       else
10480         break;
10481     }
10482
10483   if (version + traffic_class + flow_label + src + dst + proto +
10484       payload_length + hop_limit == 0)
10485     return 0;
10486
10487   /*
10488    * Aligned because we use the real comparison functions
10489    */
10490   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10491
10492   ip = (ip6_header_t *) match;
10493
10494   if (src)
10495     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10496
10497   if (dst)
10498     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10499
10500   if (proto)
10501     ip->protocol = proto_val;
10502
10503   ip_version_traffic_class_and_flow_label = 0;
10504
10505   if (version)
10506     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10507
10508   if (traffic_class)
10509     ip_version_traffic_class_and_flow_label |=
10510       (traffic_class_val & 0xFF) << 20;
10511
10512   if (flow_label)
10513     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10514
10515   ip->ip_version_traffic_class_and_flow_label =
10516     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10517
10518   if (payload_length)
10519     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10520
10521   if (hop_limit)
10522     ip->hop_limit = hop_limit_val;
10523
10524   *matchp = match;
10525   return 1;
10526 }
10527
10528 uword
10529 unformat_l3_match (unformat_input_t * input, va_list * args)
10530 {
10531   u8 **matchp = va_arg (*args, u8 **);
10532
10533   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10534     {
10535       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10536         return 1;
10537       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10538         return 1;
10539       else
10540         break;
10541     }
10542   return 0;
10543 }
10544
10545 uword
10546 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10547 {
10548   u8 *tagp = va_arg (*args, u8 *);
10549   u32 tag;
10550
10551   if (unformat (input, "%d", &tag))
10552     {
10553       tagp[0] = (tag >> 8) & 0x0F;
10554       tagp[1] = tag & 0xFF;
10555       return 1;
10556     }
10557
10558   return 0;
10559 }
10560
10561 uword
10562 unformat_l2_match (unformat_input_t * input, va_list * args)
10563 {
10564   u8 **matchp = va_arg (*args, u8 **);
10565   u8 *match = 0;
10566   u8 src = 0;
10567   u8 src_val[6];
10568   u8 dst = 0;
10569   u8 dst_val[6];
10570   u8 proto = 0;
10571   u16 proto_val;
10572   u8 tag1 = 0;
10573   u8 tag1_val[2];
10574   u8 tag2 = 0;
10575   u8 tag2_val[2];
10576   int len = 14;
10577   u8 ignore_tag1 = 0;
10578   u8 ignore_tag2 = 0;
10579   u8 cos1 = 0;
10580   u8 cos2 = 0;
10581   u32 cos1_val = 0;
10582   u32 cos2_val = 0;
10583
10584   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10585     {
10586       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10587         src = 1;
10588       else
10589         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10590         dst = 1;
10591       else if (unformat (input, "proto %U",
10592                          unformat_ethernet_type_host_byte_order, &proto_val))
10593         proto = 1;
10594       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10595         tag1 = 1;
10596       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10597         tag2 = 1;
10598       else if (unformat (input, "ignore-tag1"))
10599         ignore_tag1 = 1;
10600       else if (unformat (input, "ignore-tag2"))
10601         ignore_tag2 = 1;
10602       else if (unformat (input, "cos1 %d", &cos1_val))
10603         cos1 = 1;
10604       else if (unformat (input, "cos2 %d", &cos2_val))
10605         cos2 = 1;
10606       else
10607         break;
10608     }
10609   if ((src + dst + proto + tag1 + tag2 +
10610        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10611     return 0;
10612
10613   if (tag1 || ignore_tag1 || cos1)
10614     len = 18;
10615   if (tag2 || ignore_tag2 || cos2)
10616     len = 22;
10617
10618   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10619
10620   if (dst)
10621     clib_memcpy (match, dst_val, 6);
10622
10623   if (src)
10624     clib_memcpy (match + 6, src_val, 6);
10625
10626   if (tag2)
10627     {
10628       /* inner vlan tag */
10629       match[19] = tag2_val[1];
10630       match[18] = tag2_val[0];
10631       if (cos2)
10632         match[18] |= (cos2_val & 0x7) << 5;
10633       if (proto)
10634         {
10635           match[21] = proto_val & 0xff;
10636           match[20] = proto_val >> 8;
10637         }
10638       if (tag1)
10639         {
10640           match[15] = tag1_val[1];
10641           match[14] = tag1_val[0];
10642         }
10643       if (cos1)
10644         match[14] |= (cos1_val & 0x7) << 5;
10645       *matchp = match;
10646       return 1;
10647     }
10648   if (tag1)
10649     {
10650       match[15] = tag1_val[1];
10651       match[14] = tag1_val[0];
10652       if (proto)
10653         {
10654           match[17] = proto_val & 0xff;
10655           match[16] = proto_val >> 8;
10656         }
10657       if (cos1)
10658         match[14] |= (cos1_val & 0x7) << 5;
10659
10660       *matchp = match;
10661       return 1;
10662     }
10663   if (cos2)
10664     match[18] |= (cos2_val & 0x7) << 5;
10665   if (cos1)
10666     match[14] |= (cos1_val & 0x7) << 5;
10667   if (proto)
10668     {
10669       match[13] = proto_val & 0xff;
10670       match[12] = proto_val >> 8;
10671     }
10672
10673   *matchp = match;
10674   return 1;
10675 }
10676 #endif
10677
10678 uword
10679 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10680 {
10681   u8 **matchp = va_arg (*args, u8 **);
10682   u32 skip_n_vectors = va_arg (*args, u32);
10683   u32 match_n_vectors = va_arg (*args, u32);
10684
10685   u8 *match = 0;
10686   u8 *l2 = 0;
10687   u8 *l3 = 0;
10688   u8 *l4 = 0;
10689
10690   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10691     {
10692       if (unformat (input, "hex %U", unformat_hex_string, &match))
10693         ;
10694       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10695         ;
10696       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10697         ;
10698       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10699         ;
10700       else
10701         break;
10702     }
10703
10704   if (l4 && !l3)
10705     {
10706       vec_free (match);
10707       vec_free (l2);
10708       vec_free (l4);
10709       return 0;
10710     }
10711
10712   if (match || l2 || l3 || l4)
10713     {
10714       if (l2 || l3 || l4)
10715         {
10716           /* "Win a free Ethernet header in every packet" */
10717           if (l2 == 0)
10718             vec_validate_aligned (l2, 13, sizeof (u32x4));
10719           match = l2;
10720           if (vec_len (l3))
10721             {
10722               vec_append_aligned (match, l3, sizeof (u32x4));
10723               vec_free (l3);
10724             }
10725           if (vec_len (l4))
10726             {
10727               vec_append_aligned (match, l4, sizeof (u32x4));
10728               vec_free (l4);
10729             }
10730         }
10731
10732       /* Make sure the vector is big enough even if key is all 0's */
10733       vec_validate_aligned
10734         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10735          sizeof (u32x4));
10736
10737       /* Set size, include skipped vectors */
10738       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10739
10740       *matchp = match;
10741
10742       return 1;
10743     }
10744
10745   return 0;
10746 }
10747
10748 static int
10749 api_classify_add_del_session (vat_main_t * vam)
10750 {
10751   unformat_input_t *i = vam->input;
10752   vl_api_classify_add_del_session_t *mp;
10753   int is_add = 1;
10754   u32 table_index = ~0;
10755   u32 hit_next_index = ~0;
10756   u32 opaque_index = ~0;
10757   u8 *match = 0;
10758   i32 advance = 0;
10759   u32 skip_n_vectors = 0;
10760   u32 match_n_vectors = 0;
10761   u32 action = 0;
10762   u32 metadata = 0;
10763   int ret;
10764
10765   /*
10766    * Warning: you have to supply skip_n and match_n
10767    * because the API client cant simply look at the classify
10768    * table object.
10769    */
10770
10771   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10772     {
10773       if (unformat (i, "del"))
10774         is_add = 0;
10775       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10776                          &hit_next_index))
10777         ;
10778       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10779                          &hit_next_index))
10780         ;
10781       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10782                          &hit_next_index))
10783         ;
10784       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10785         ;
10786       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10787         ;
10788       else if (unformat (i, "opaque-index %d", &opaque_index))
10789         ;
10790       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10791         ;
10792       else if (unformat (i, "match_n %d", &match_n_vectors))
10793         ;
10794       else if (unformat (i, "match %U", api_unformat_classify_match,
10795                          &match, skip_n_vectors, match_n_vectors))
10796         ;
10797       else if (unformat (i, "advance %d", &advance))
10798         ;
10799       else if (unformat (i, "table-index %d", &table_index))
10800         ;
10801       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10802         action = 1;
10803       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10804         action = 2;
10805       else if (unformat (i, "action %d", &action))
10806         ;
10807       else if (unformat (i, "metadata %d", &metadata))
10808         ;
10809       else
10810         break;
10811     }
10812
10813   if (table_index == ~0)
10814     {
10815       errmsg ("Table index required");
10816       return -99;
10817     }
10818
10819   if (is_add && match == 0)
10820     {
10821       errmsg ("Match value required");
10822       return -99;
10823     }
10824
10825   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10826
10827   mp->is_add = is_add;
10828   mp->table_index = ntohl (table_index);
10829   mp->hit_next_index = ntohl (hit_next_index);
10830   mp->opaque_index = ntohl (opaque_index);
10831   mp->advance = ntohl (advance);
10832   mp->action = action;
10833   mp->metadata = ntohl (metadata);
10834   clib_memcpy (mp->match, match, vec_len (match));
10835   vec_free (match);
10836
10837   S (mp);
10838   W (ret);
10839   return ret;
10840 }
10841
10842 static int
10843 api_classify_set_interface_ip_table (vat_main_t * vam)
10844 {
10845   unformat_input_t *i = vam->input;
10846   vl_api_classify_set_interface_ip_table_t *mp;
10847   u32 sw_if_index;
10848   int sw_if_index_set;
10849   u32 table_index = ~0;
10850   u8 is_ipv6 = 0;
10851   int ret;
10852
10853   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10854     {
10855       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10856         sw_if_index_set = 1;
10857       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10858         sw_if_index_set = 1;
10859       else if (unformat (i, "table %d", &table_index))
10860         ;
10861       else
10862         {
10863           clib_warning ("parse error '%U'", format_unformat_error, i);
10864           return -99;
10865         }
10866     }
10867
10868   if (sw_if_index_set == 0)
10869     {
10870       errmsg ("missing interface name or sw_if_index");
10871       return -99;
10872     }
10873
10874
10875   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10876
10877   mp->sw_if_index = ntohl (sw_if_index);
10878   mp->table_index = ntohl (table_index);
10879   mp->is_ipv6 = is_ipv6;
10880
10881   S (mp);
10882   W (ret);
10883   return ret;
10884 }
10885
10886 static int
10887 api_classify_set_interface_l2_tables (vat_main_t * vam)
10888 {
10889   unformat_input_t *i = vam->input;
10890   vl_api_classify_set_interface_l2_tables_t *mp;
10891   u32 sw_if_index;
10892   int sw_if_index_set;
10893   u32 ip4_table_index = ~0;
10894   u32 ip6_table_index = ~0;
10895   u32 other_table_index = ~0;
10896   u32 is_input = 1;
10897   int ret;
10898
10899   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10900     {
10901       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10902         sw_if_index_set = 1;
10903       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10904         sw_if_index_set = 1;
10905       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10906         ;
10907       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10908         ;
10909       else if (unformat (i, "other-table %d", &other_table_index))
10910         ;
10911       else if (unformat (i, "is-input %d", &is_input))
10912         ;
10913       else
10914         {
10915           clib_warning ("parse error '%U'", format_unformat_error, i);
10916           return -99;
10917         }
10918     }
10919
10920   if (sw_if_index_set == 0)
10921     {
10922       errmsg ("missing interface name or sw_if_index");
10923       return -99;
10924     }
10925
10926
10927   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10928
10929   mp->sw_if_index = ntohl (sw_if_index);
10930   mp->ip4_table_index = ntohl (ip4_table_index);
10931   mp->ip6_table_index = ntohl (ip6_table_index);
10932   mp->other_table_index = ntohl (other_table_index);
10933   mp->is_input = (u8) is_input;
10934
10935   S (mp);
10936   W (ret);
10937   return ret;
10938 }
10939
10940 static int
10941 api_set_ipfix_exporter (vat_main_t * vam)
10942 {
10943   unformat_input_t *i = vam->input;
10944   vl_api_set_ipfix_exporter_t *mp;
10945   ip4_address_t collector_address;
10946   u8 collector_address_set = 0;
10947   u32 collector_port = ~0;
10948   ip4_address_t src_address;
10949   u8 src_address_set = 0;
10950   u32 vrf_id = ~0;
10951   u32 path_mtu = ~0;
10952   u32 template_interval = ~0;
10953   u8 udp_checksum = 0;
10954   int ret;
10955
10956   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10957     {
10958       if (unformat (i, "collector_address %U", unformat_ip4_address,
10959                     &collector_address))
10960         collector_address_set = 1;
10961       else if (unformat (i, "collector_port %d", &collector_port))
10962         ;
10963       else if (unformat (i, "src_address %U", unformat_ip4_address,
10964                          &src_address))
10965         src_address_set = 1;
10966       else if (unformat (i, "vrf_id %d", &vrf_id))
10967         ;
10968       else if (unformat (i, "path_mtu %d", &path_mtu))
10969         ;
10970       else if (unformat (i, "template_interval %d", &template_interval))
10971         ;
10972       else if (unformat (i, "udp_checksum"))
10973         udp_checksum = 1;
10974       else
10975         break;
10976     }
10977
10978   if (collector_address_set == 0)
10979     {
10980       errmsg ("collector_address required");
10981       return -99;
10982     }
10983
10984   if (src_address_set == 0)
10985     {
10986       errmsg ("src_address required");
10987       return -99;
10988     }
10989
10990   M (SET_IPFIX_EXPORTER, mp);
10991
10992   memcpy (mp->collector_address, collector_address.data,
10993           sizeof (collector_address.data));
10994   mp->collector_port = htons ((u16) collector_port);
10995   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
10996   mp->vrf_id = htonl (vrf_id);
10997   mp->path_mtu = htonl (path_mtu);
10998   mp->template_interval = htonl (template_interval);
10999   mp->udp_checksum = udp_checksum;
11000
11001   S (mp);
11002   W (ret);
11003   return ret;
11004 }
11005
11006 static int
11007 api_set_ipfix_classify_stream (vat_main_t * vam)
11008 {
11009   unformat_input_t *i = vam->input;
11010   vl_api_set_ipfix_classify_stream_t *mp;
11011   u32 domain_id = 0;
11012   u32 src_port = UDP_DST_PORT_ipfix;
11013   int ret;
11014
11015   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11016     {
11017       if (unformat (i, "domain %d", &domain_id))
11018         ;
11019       else if (unformat (i, "src_port %d", &src_port))
11020         ;
11021       else
11022         {
11023           errmsg ("unknown input `%U'", format_unformat_error, i);
11024           return -99;
11025         }
11026     }
11027
11028   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11029
11030   mp->domain_id = htonl (domain_id);
11031   mp->src_port = htons ((u16) src_port);
11032
11033   S (mp);
11034   W (ret);
11035   return ret;
11036 }
11037
11038 static int
11039 api_ipfix_classify_table_add_del (vat_main_t * vam)
11040 {
11041   unformat_input_t *i = vam->input;
11042   vl_api_ipfix_classify_table_add_del_t *mp;
11043   int is_add = -1;
11044   u32 classify_table_index = ~0;
11045   u8 ip_version = 0;
11046   u8 transport_protocol = 255;
11047   int ret;
11048
11049   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11050     {
11051       if (unformat (i, "add"))
11052         is_add = 1;
11053       else if (unformat (i, "del"))
11054         is_add = 0;
11055       else if (unformat (i, "table %d", &classify_table_index))
11056         ;
11057       else if (unformat (i, "ip4"))
11058         ip_version = 4;
11059       else if (unformat (i, "ip6"))
11060         ip_version = 6;
11061       else if (unformat (i, "tcp"))
11062         transport_protocol = 6;
11063       else if (unformat (i, "udp"))
11064         transport_protocol = 17;
11065       else
11066         {
11067           errmsg ("unknown input `%U'", format_unformat_error, i);
11068           return -99;
11069         }
11070     }
11071
11072   if (is_add == -1)
11073     {
11074       errmsg ("expecting: add|del");
11075       return -99;
11076     }
11077   if (classify_table_index == ~0)
11078     {
11079       errmsg ("classifier table not specified");
11080       return -99;
11081     }
11082   if (ip_version == 0)
11083     {
11084       errmsg ("IP version not specified");
11085       return -99;
11086     }
11087
11088   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11089
11090   mp->is_add = is_add;
11091   mp->table_id = htonl (classify_table_index);
11092   mp->ip_version = ip_version;
11093   mp->transport_protocol = transport_protocol;
11094
11095   S (mp);
11096   W (ret);
11097   return ret;
11098 }
11099
11100 static int
11101 api_get_node_index (vat_main_t * vam)
11102 {
11103   unformat_input_t *i = vam->input;
11104   vl_api_get_node_index_t *mp;
11105   u8 *name = 0;
11106   int ret;
11107
11108   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11109     {
11110       if (unformat (i, "node %s", &name))
11111         ;
11112       else
11113         break;
11114     }
11115   if (name == 0)
11116     {
11117       errmsg ("node name required");
11118       return -99;
11119     }
11120   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11121     {
11122       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11123       return -99;
11124     }
11125
11126   M (GET_NODE_INDEX, mp);
11127   clib_memcpy (mp->node_name, name, vec_len (name));
11128   vec_free (name);
11129
11130   S (mp);
11131   W (ret);
11132   return ret;
11133 }
11134
11135 static int
11136 api_get_next_index (vat_main_t * vam)
11137 {
11138   unformat_input_t *i = vam->input;
11139   vl_api_get_next_index_t *mp;
11140   u8 *node_name = 0, *next_node_name = 0;
11141   int ret;
11142
11143   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11144     {
11145       if (unformat (i, "node-name %s", &node_name))
11146         ;
11147       else if (unformat (i, "next-node-name %s", &next_node_name))
11148         break;
11149     }
11150
11151   if (node_name == 0)
11152     {
11153       errmsg ("node name required");
11154       return -99;
11155     }
11156   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11157     {
11158       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11159       return -99;
11160     }
11161
11162   if (next_node_name == 0)
11163     {
11164       errmsg ("next node name required");
11165       return -99;
11166     }
11167   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11168     {
11169       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11170       return -99;
11171     }
11172
11173   M (GET_NEXT_INDEX, mp);
11174   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11175   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11176   vec_free (node_name);
11177   vec_free (next_node_name);
11178
11179   S (mp);
11180   W (ret);
11181   return ret;
11182 }
11183
11184 static int
11185 api_add_node_next (vat_main_t * vam)
11186 {
11187   unformat_input_t *i = vam->input;
11188   vl_api_add_node_next_t *mp;
11189   u8 *name = 0;
11190   u8 *next = 0;
11191   int ret;
11192
11193   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11194     {
11195       if (unformat (i, "node %s", &name))
11196         ;
11197       else if (unformat (i, "next %s", &next))
11198         ;
11199       else
11200         break;
11201     }
11202   if (name == 0)
11203     {
11204       errmsg ("node name required");
11205       return -99;
11206     }
11207   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11208     {
11209       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11210       return -99;
11211     }
11212   if (next == 0)
11213     {
11214       errmsg ("next node required");
11215       return -99;
11216     }
11217   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11218     {
11219       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11220       return -99;
11221     }
11222
11223   M (ADD_NODE_NEXT, mp);
11224   clib_memcpy (mp->node_name, name, vec_len (name));
11225   clib_memcpy (mp->next_name, next, vec_len (next));
11226   vec_free (name);
11227   vec_free (next);
11228
11229   S (mp);
11230   W (ret);
11231   return ret;
11232 }
11233
11234 static int
11235 api_l2tpv3_create_tunnel (vat_main_t * vam)
11236 {
11237   unformat_input_t *i = vam->input;
11238   ip6_address_t client_address, our_address;
11239   int client_address_set = 0;
11240   int our_address_set = 0;
11241   u32 local_session_id = 0;
11242   u32 remote_session_id = 0;
11243   u64 local_cookie = 0;
11244   u64 remote_cookie = 0;
11245   u8 l2_sublayer_present = 0;
11246   vl_api_l2tpv3_create_tunnel_t *mp;
11247   int ret;
11248
11249   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11250     {
11251       if (unformat (i, "client_address %U", unformat_ip6_address,
11252                     &client_address))
11253         client_address_set = 1;
11254       else if (unformat (i, "our_address %U", unformat_ip6_address,
11255                          &our_address))
11256         our_address_set = 1;
11257       else if (unformat (i, "local_session_id %d", &local_session_id))
11258         ;
11259       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11260         ;
11261       else if (unformat (i, "local_cookie %lld", &local_cookie))
11262         ;
11263       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11264         ;
11265       else if (unformat (i, "l2-sublayer-present"))
11266         l2_sublayer_present = 1;
11267       else
11268         break;
11269     }
11270
11271   if (client_address_set == 0)
11272     {
11273       errmsg ("client_address required");
11274       return -99;
11275     }
11276
11277   if (our_address_set == 0)
11278     {
11279       errmsg ("our_address required");
11280       return -99;
11281     }
11282
11283   M (L2TPV3_CREATE_TUNNEL, mp);
11284
11285   clib_memcpy (mp->client_address, client_address.as_u8,
11286                sizeof (mp->client_address));
11287
11288   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
11289
11290   mp->local_session_id = ntohl (local_session_id);
11291   mp->remote_session_id = ntohl (remote_session_id);
11292   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11293   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11294   mp->l2_sublayer_present = l2_sublayer_present;
11295   mp->is_ipv6 = 1;
11296
11297   S (mp);
11298   W (ret);
11299   return ret;
11300 }
11301
11302 static int
11303 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11304 {
11305   unformat_input_t *i = vam->input;
11306   u32 sw_if_index;
11307   u8 sw_if_index_set = 0;
11308   u64 new_local_cookie = 0;
11309   u64 new_remote_cookie = 0;
11310   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11311   int ret;
11312
11313   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11314     {
11315       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11316         sw_if_index_set = 1;
11317       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11318         sw_if_index_set = 1;
11319       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11320         ;
11321       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11322         ;
11323       else
11324         break;
11325     }
11326
11327   if (sw_if_index_set == 0)
11328     {
11329       errmsg ("missing interface name or sw_if_index");
11330       return -99;
11331     }
11332
11333   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11334
11335   mp->sw_if_index = ntohl (sw_if_index);
11336   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11337   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11338
11339   S (mp);
11340   W (ret);
11341   return ret;
11342 }
11343
11344 static int
11345 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11346 {
11347   unformat_input_t *i = vam->input;
11348   vl_api_l2tpv3_interface_enable_disable_t *mp;
11349   u32 sw_if_index;
11350   u8 sw_if_index_set = 0;
11351   u8 enable_disable = 1;
11352   int ret;
11353
11354   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11355     {
11356       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11357         sw_if_index_set = 1;
11358       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11359         sw_if_index_set = 1;
11360       else if (unformat (i, "enable"))
11361         enable_disable = 1;
11362       else if (unformat (i, "disable"))
11363         enable_disable = 0;
11364       else
11365         break;
11366     }
11367
11368   if (sw_if_index_set == 0)
11369     {
11370       errmsg ("missing interface name or sw_if_index");
11371       return -99;
11372     }
11373
11374   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11375
11376   mp->sw_if_index = ntohl (sw_if_index);
11377   mp->enable_disable = enable_disable;
11378
11379   S (mp);
11380   W (ret);
11381   return ret;
11382 }
11383
11384 static int
11385 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11386 {
11387   unformat_input_t *i = vam->input;
11388   vl_api_l2tpv3_set_lookup_key_t *mp;
11389   u8 key = ~0;
11390   int ret;
11391
11392   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11393     {
11394       if (unformat (i, "lookup_v6_src"))
11395         key = L2T_LOOKUP_SRC_ADDRESS;
11396       else if (unformat (i, "lookup_v6_dst"))
11397         key = L2T_LOOKUP_DST_ADDRESS;
11398       else if (unformat (i, "lookup_session_id"))
11399         key = L2T_LOOKUP_SESSION_ID;
11400       else
11401         break;
11402     }
11403
11404   if (key == (u8) ~ 0)
11405     {
11406       errmsg ("l2tp session lookup key unset");
11407       return -99;
11408     }
11409
11410   M (L2TPV3_SET_LOOKUP_KEY, mp);
11411
11412   mp->key = key;
11413
11414   S (mp);
11415   W (ret);
11416   return ret;
11417 }
11418
11419 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11420   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11421 {
11422   vat_main_t *vam = &vat_main;
11423
11424   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11425          format_ip6_address, mp->our_address,
11426          format_ip6_address, mp->client_address,
11427          clib_net_to_host_u32 (mp->sw_if_index));
11428
11429   print (vam->ofp,
11430          "   local cookies %016llx %016llx remote cookie %016llx",
11431          clib_net_to_host_u64 (mp->local_cookie[0]),
11432          clib_net_to_host_u64 (mp->local_cookie[1]),
11433          clib_net_to_host_u64 (mp->remote_cookie));
11434
11435   print (vam->ofp, "   local session-id %d remote session-id %d",
11436          clib_net_to_host_u32 (mp->local_session_id),
11437          clib_net_to_host_u32 (mp->remote_session_id));
11438
11439   print (vam->ofp, "   l2 specific sublayer %s\n",
11440          mp->l2_sublayer_present ? "preset" : "absent");
11441
11442 }
11443
11444 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11445   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11446 {
11447   vat_main_t *vam = &vat_main;
11448   vat_json_node_t *node = NULL;
11449   struct in6_addr addr;
11450
11451   if (VAT_JSON_ARRAY != vam->json_tree.type)
11452     {
11453       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11454       vat_json_init_array (&vam->json_tree);
11455     }
11456   node = vat_json_array_add (&vam->json_tree);
11457
11458   vat_json_init_object (node);
11459
11460   clib_memcpy (&addr, mp->our_address, sizeof (addr));
11461   vat_json_object_add_ip6 (node, "our_address", addr);
11462   clib_memcpy (&addr, mp->client_address, sizeof (addr));
11463   vat_json_object_add_ip6 (node, "client_address", addr);
11464
11465   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11466   vat_json_init_array (lc);
11467   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11468   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11469   vat_json_object_add_uint (node, "remote_cookie",
11470                             clib_net_to_host_u64 (mp->remote_cookie));
11471
11472   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11473   vat_json_object_add_uint (node, "local_session_id",
11474                             clib_net_to_host_u32 (mp->local_session_id));
11475   vat_json_object_add_uint (node, "remote_session_id",
11476                             clib_net_to_host_u32 (mp->remote_session_id));
11477   vat_json_object_add_string_copy (node, "l2_sublayer",
11478                                    mp->l2_sublayer_present ? (u8 *) "present"
11479                                    : (u8 *) "absent");
11480 }
11481
11482 static int
11483 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11484 {
11485   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11486   vl_api_control_ping_t *mp_ping;
11487   int ret;
11488
11489   /* Get list of l2tpv3-tunnel interfaces */
11490   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11491   S (mp);
11492
11493   /* Use a control ping for synchronization */
11494   M (CONTROL_PING, mp_ping);
11495   S (mp_ping);
11496
11497   W (ret);
11498   return ret;
11499 }
11500
11501
11502 static void vl_api_sw_interface_tap_details_t_handler
11503   (vl_api_sw_interface_tap_details_t * mp)
11504 {
11505   vat_main_t *vam = &vat_main;
11506
11507   print (vam->ofp, "%-16s %d",
11508          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
11509 }
11510
11511 static void vl_api_sw_interface_tap_details_t_handler_json
11512   (vl_api_sw_interface_tap_details_t * mp)
11513 {
11514   vat_main_t *vam = &vat_main;
11515   vat_json_node_t *node = NULL;
11516
11517   if (VAT_JSON_ARRAY != vam->json_tree.type)
11518     {
11519       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11520       vat_json_init_array (&vam->json_tree);
11521     }
11522   node = vat_json_array_add (&vam->json_tree);
11523
11524   vat_json_init_object (node);
11525   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11526   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11527 }
11528
11529 static int
11530 api_sw_interface_tap_dump (vat_main_t * vam)
11531 {
11532   vl_api_sw_interface_tap_dump_t *mp;
11533   vl_api_control_ping_t *mp_ping;
11534   int ret;
11535
11536   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
11537   /* Get list of tap interfaces */
11538   M (SW_INTERFACE_TAP_DUMP, mp);
11539   S (mp);
11540
11541   /* Use a control ping for synchronization */
11542   M (CONTROL_PING, mp_ping);
11543   S (mp_ping);
11544
11545   W (ret);
11546   return ret;
11547 }
11548
11549 static uword unformat_vxlan_decap_next
11550   (unformat_input_t * input, va_list * args)
11551 {
11552   u32 *result = va_arg (*args, u32 *);
11553   u32 tmp;
11554
11555   if (unformat (input, "l2"))
11556     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11557   else if (unformat (input, "%d", &tmp))
11558     *result = tmp;
11559   else
11560     return 0;
11561   return 1;
11562 }
11563
11564 static int
11565 api_vxlan_add_del_tunnel (vat_main_t * vam)
11566 {
11567   unformat_input_t *line_input = vam->input;
11568   vl_api_vxlan_add_del_tunnel_t *mp;
11569   ip46_address_t src, dst;
11570   u8 is_add = 1;
11571   u8 ipv4_set = 0, ipv6_set = 0;
11572   u8 src_set = 0;
11573   u8 dst_set = 0;
11574   u8 grp_set = 0;
11575   u32 mcast_sw_if_index = ~0;
11576   u32 encap_vrf_id = 0;
11577   u32 decap_next_index = ~0;
11578   u32 vni = 0;
11579   int ret;
11580
11581   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11582   memset (&src, 0, sizeof src);
11583   memset (&dst, 0, sizeof dst);
11584
11585   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11586     {
11587       if (unformat (line_input, "del"))
11588         is_add = 0;
11589       else
11590         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11591         {
11592           ipv4_set = 1;
11593           src_set = 1;
11594         }
11595       else
11596         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11597         {
11598           ipv4_set = 1;
11599           dst_set = 1;
11600         }
11601       else
11602         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11603         {
11604           ipv6_set = 1;
11605           src_set = 1;
11606         }
11607       else
11608         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11609         {
11610           ipv6_set = 1;
11611           dst_set = 1;
11612         }
11613       else if (unformat (line_input, "group %U %U",
11614                          unformat_ip4_address, &dst.ip4,
11615                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11616         {
11617           grp_set = dst_set = 1;
11618           ipv4_set = 1;
11619         }
11620       else if (unformat (line_input, "group %U",
11621                          unformat_ip4_address, &dst.ip4))
11622         {
11623           grp_set = dst_set = 1;
11624           ipv4_set = 1;
11625         }
11626       else if (unformat (line_input, "group %U %U",
11627                          unformat_ip6_address, &dst.ip6,
11628                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11629         {
11630           grp_set = dst_set = 1;
11631           ipv6_set = 1;
11632         }
11633       else if (unformat (line_input, "group %U",
11634                          unformat_ip6_address, &dst.ip6))
11635         {
11636           grp_set = dst_set = 1;
11637           ipv6_set = 1;
11638         }
11639       else
11640         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11641         ;
11642       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11643         ;
11644       else if (unformat (line_input, "decap-next %U",
11645                          unformat_vxlan_decap_next, &decap_next_index))
11646         ;
11647       else if (unformat (line_input, "vni %d", &vni))
11648         ;
11649       else
11650         {
11651           errmsg ("parse error '%U'", format_unformat_error, line_input);
11652           return -99;
11653         }
11654     }
11655
11656   if (src_set == 0)
11657     {
11658       errmsg ("tunnel src address not specified");
11659       return -99;
11660     }
11661   if (dst_set == 0)
11662     {
11663       errmsg ("tunnel dst address not specified");
11664       return -99;
11665     }
11666
11667   if (grp_set && !ip46_address_is_multicast (&dst))
11668     {
11669       errmsg ("tunnel group address not multicast");
11670       return -99;
11671     }
11672   if (grp_set && mcast_sw_if_index == ~0)
11673     {
11674       errmsg ("tunnel nonexistent multicast device");
11675       return -99;
11676     }
11677   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11678     {
11679       errmsg ("tunnel dst address must be unicast");
11680       return -99;
11681     }
11682
11683
11684   if (ipv4_set && ipv6_set)
11685     {
11686       errmsg ("both IPv4 and IPv6 addresses specified");
11687       return -99;
11688     }
11689
11690   if ((vni == 0) || (vni >> 24))
11691     {
11692       errmsg ("vni not specified or out of range");
11693       return -99;
11694     }
11695
11696   M (VXLAN_ADD_DEL_TUNNEL, mp);
11697
11698   if (ipv6_set)
11699     {
11700       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
11701       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
11702     }
11703   else
11704     {
11705       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
11706       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
11707     }
11708   mp->encap_vrf_id = ntohl (encap_vrf_id);
11709   mp->decap_next_index = ntohl (decap_next_index);
11710   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11711   mp->vni = ntohl (vni);
11712   mp->is_add = is_add;
11713   mp->is_ipv6 = ipv6_set;
11714
11715   S (mp);
11716   W (ret);
11717   return ret;
11718 }
11719
11720 static void vl_api_vxlan_tunnel_details_t_handler
11721   (vl_api_vxlan_tunnel_details_t * mp)
11722 {
11723   vat_main_t *vam = &vat_main;
11724   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
11725   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
11726
11727   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
11728          ntohl (mp->sw_if_index),
11729          format_ip46_address, &src, IP46_TYPE_ANY,
11730          format_ip46_address, &dst, IP46_TYPE_ANY,
11731          ntohl (mp->encap_vrf_id),
11732          ntohl (mp->decap_next_index), ntohl (mp->vni),
11733          ntohl (mp->mcast_sw_if_index));
11734 }
11735
11736 static void vl_api_vxlan_tunnel_details_t_handler_json
11737   (vl_api_vxlan_tunnel_details_t * mp)
11738 {
11739   vat_main_t *vam = &vat_main;
11740   vat_json_node_t *node = NULL;
11741
11742   if (VAT_JSON_ARRAY != vam->json_tree.type)
11743     {
11744       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11745       vat_json_init_array (&vam->json_tree);
11746     }
11747   node = vat_json_array_add (&vam->json_tree);
11748
11749   vat_json_init_object (node);
11750   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11751   if (mp->is_ipv6)
11752     {
11753       struct in6_addr ip6;
11754
11755       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
11756       vat_json_object_add_ip6 (node, "src_address", ip6);
11757       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
11758       vat_json_object_add_ip6 (node, "dst_address", ip6);
11759     }
11760   else
11761     {
11762       struct in_addr ip4;
11763
11764       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
11765       vat_json_object_add_ip4 (node, "src_address", ip4);
11766       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
11767       vat_json_object_add_ip4 (node, "dst_address", ip4);
11768     }
11769   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11770   vat_json_object_add_uint (node, "decap_next_index",
11771                             ntohl (mp->decap_next_index));
11772   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11773   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11774   vat_json_object_add_uint (node, "mcast_sw_if_index",
11775                             ntohl (mp->mcast_sw_if_index));
11776 }
11777
11778 static int
11779 api_vxlan_tunnel_dump (vat_main_t * vam)
11780 {
11781   unformat_input_t *i = vam->input;
11782   vl_api_vxlan_tunnel_dump_t *mp;
11783   vl_api_control_ping_t *mp_ping;
11784   u32 sw_if_index;
11785   u8 sw_if_index_set = 0;
11786   int ret;
11787
11788   /* Parse args required to build the message */
11789   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11790     {
11791       if (unformat (i, "sw_if_index %d", &sw_if_index))
11792         sw_if_index_set = 1;
11793       else
11794         break;
11795     }
11796
11797   if (sw_if_index_set == 0)
11798     {
11799       sw_if_index = ~0;
11800     }
11801
11802   if (!vam->json_output)
11803     {
11804       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
11805              "sw_if_index", "src_address", "dst_address",
11806              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11807     }
11808
11809   /* Get list of vxlan-tunnel interfaces */
11810   M (VXLAN_TUNNEL_DUMP, mp);
11811
11812   mp->sw_if_index = htonl (sw_if_index);
11813
11814   S (mp);
11815
11816   /* Use a control ping for synchronization */
11817   M (CONTROL_PING, mp_ping);
11818   S (mp_ping);
11819
11820   W (ret);
11821   return ret;
11822 }
11823
11824 static int
11825 api_gre_add_del_tunnel (vat_main_t * vam)
11826 {
11827   unformat_input_t *line_input = vam->input;
11828   vl_api_gre_add_del_tunnel_t *mp;
11829   ip4_address_t src4, dst4;
11830   ip6_address_t src6, dst6;
11831   u8 is_add = 1;
11832   u8 ipv4_set = 0;
11833   u8 ipv6_set = 0;
11834   u8 teb = 0;
11835   u8 src_set = 0;
11836   u8 dst_set = 0;
11837   u32 outer_fib_id = 0;
11838   int ret;
11839
11840   memset (&src4, 0, sizeof src4);
11841   memset (&dst4, 0, sizeof dst4);
11842   memset (&src6, 0, sizeof src6);
11843   memset (&dst6, 0, sizeof dst6);
11844
11845   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11846     {
11847       if (unformat (line_input, "del"))
11848         is_add = 0;
11849       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
11850         {
11851           src_set = 1;
11852           ipv4_set = 1;
11853         }
11854       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
11855         {
11856           dst_set = 1;
11857           ipv4_set = 1;
11858         }
11859       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
11860         {
11861           src_set = 1;
11862           ipv6_set = 1;
11863         }
11864       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
11865         {
11866           dst_set = 1;
11867           ipv6_set = 1;
11868         }
11869       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
11870         ;
11871       else if (unformat (line_input, "teb"))
11872         teb = 1;
11873       else
11874         {
11875           errmsg ("parse error '%U'", format_unformat_error, line_input);
11876           return -99;
11877         }
11878     }
11879
11880   if (src_set == 0)
11881     {
11882       errmsg ("tunnel src address not specified");
11883       return -99;
11884     }
11885   if (dst_set == 0)
11886     {
11887       errmsg ("tunnel dst address not specified");
11888       return -99;
11889     }
11890   if (ipv4_set && ipv6_set)
11891     {
11892       errmsg ("both IPv4 and IPv6 addresses specified");
11893       return -99;
11894     }
11895
11896
11897   M (GRE_ADD_DEL_TUNNEL, mp);
11898
11899   if (ipv4_set)
11900     {
11901       clib_memcpy (&mp->src_address, &src4, 4);
11902       clib_memcpy (&mp->dst_address, &dst4, 4);
11903     }
11904   else
11905     {
11906       clib_memcpy (&mp->src_address, &src6, 16);
11907       clib_memcpy (&mp->dst_address, &dst6, 16);
11908     }
11909   mp->outer_fib_id = ntohl (outer_fib_id);
11910   mp->is_add = is_add;
11911   mp->teb = teb;
11912   mp->is_ipv6 = ipv6_set;
11913
11914   S (mp);
11915   W (ret);
11916   return ret;
11917 }
11918
11919 static void vl_api_gre_tunnel_details_t_handler
11920   (vl_api_gre_tunnel_details_t * mp)
11921 {
11922   vat_main_t *vam = &vat_main;
11923   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
11924   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
11925
11926   print (vam->ofp, "%11d%24U%24U%6d%14d",
11927          ntohl (mp->sw_if_index),
11928          format_ip46_address, &src, IP46_TYPE_ANY,
11929          format_ip46_address, &dst, IP46_TYPE_ANY,
11930          mp->teb, ntohl (mp->outer_fib_id));
11931 }
11932
11933 static void vl_api_gre_tunnel_details_t_handler_json
11934   (vl_api_gre_tunnel_details_t * mp)
11935 {
11936   vat_main_t *vam = &vat_main;
11937   vat_json_node_t *node = NULL;
11938   struct in_addr ip4;
11939   struct in6_addr ip6;
11940
11941   if (VAT_JSON_ARRAY != vam->json_tree.type)
11942     {
11943       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11944       vat_json_init_array (&vam->json_tree);
11945     }
11946   node = vat_json_array_add (&vam->json_tree);
11947
11948   vat_json_init_object (node);
11949   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11950   if (!mp->is_ipv6)
11951     {
11952       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
11953       vat_json_object_add_ip4 (node, "src_address", ip4);
11954       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
11955       vat_json_object_add_ip4 (node, "dst_address", ip4);
11956     }
11957   else
11958     {
11959       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
11960       vat_json_object_add_ip6 (node, "src_address", ip6);
11961       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
11962       vat_json_object_add_ip6 (node, "dst_address", ip6);
11963     }
11964   vat_json_object_add_uint (node, "teb", mp->teb);
11965   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
11966   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
11967 }
11968
11969 static int
11970 api_gre_tunnel_dump (vat_main_t * vam)
11971 {
11972   unformat_input_t *i = vam->input;
11973   vl_api_gre_tunnel_dump_t *mp;
11974   vl_api_control_ping_t *mp_ping;
11975   u32 sw_if_index;
11976   u8 sw_if_index_set = 0;
11977   int ret;
11978
11979   /* Parse args required to build the message */
11980   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11981     {
11982       if (unformat (i, "sw_if_index %d", &sw_if_index))
11983         sw_if_index_set = 1;
11984       else
11985         break;
11986     }
11987
11988   if (sw_if_index_set == 0)
11989     {
11990       sw_if_index = ~0;
11991     }
11992
11993   if (!vam->json_output)
11994     {
11995       print (vam->ofp, "%11s%24s%24s%6s%14s",
11996              "sw_if_index", "src_address", "dst_address", "teb",
11997              "outer_fib_id");
11998     }
11999
12000   /* Get list of gre-tunnel interfaces */
12001   M (GRE_TUNNEL_DUMP, mp);
12002
12003   mp->sw_if_index = htonl (sw_if_index);
12004
12005   S (mp);
12006
12007   /* Use a control ping for synchronization */
12008   M (CONTROL_PING, mp_ping);
12009   S (mp_ping);
12010
12011   W (ret);
12012   return ret;
12013 }
12014
12015 static int
12016 api_l2_fib_clear_table (vat_main_t * vam)
12017 {
12018 //  unformat_input_t * i = vam->input;
12019   vl_api_l2_fib_clear_table_t *mp;
12020   int ret;
12021
12022   M (L2_FIB_CLEAR_TABLE, mp);
12023
12024   S (mp);
12025   W (ret);
12026   return ret;
12027 }
12028
12029 static int
12030 api_l2_interface_efp_filter (vat_main_t * vam)
12031 {
12032   unformat_input_t *i = vam->input;
12033   vl_api_l2_interface_efp_filter_t *mp;
12034   u32 sw_if_index;
12035   u8 enable = 1;
12036   u8 sw_if_index_set = 0;
12037   int ret;
12038
12039   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12040     {
12041       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12042         sw_if_index_set = 1;
12043       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12044         sw_if_index_set = 1;
12045       else if (unformat (i, "enable"))
12046         enable = 1;
12047       else if (unformat (i, "disable"))
12048         enable = 0;
12049       else
12050         {
12051           clib_warning ("parse error '%U'", format_unformat_error, i);
12052           return -99;
12053         }
12054     }
12055
12056   if (sw_if_index_set == 0)
12057     {
12058       errmsg ("missing sw_if_index");
12059       return -99;
12060     }
12061
12062   M (L2_INTERFACE_EFP_FILTER, mp);
12063
12064   mp->sw_if_index = ntohl (sw_if_index);
12065   mp->enable_disable = enable;
12066
12067   S (mp);
12068   W (ret);
12069   return ret;
12070 }
12071
12072 #define foreach_vtr_op                          \
12073 _("disable",  L2_VTR_DISABLED)                  \
12074 _("push-1",  L2_VTR_PUSH_1)                     \
12075 _("push-2",  L2_VTR_PUSH_2)                     \
12076 _("pop-1",  L2_VTR_POP_1)                       \
12077 _("pop-2",  L2_VTR_POP_2)                       \
12078 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12079 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12080 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12081 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12082
12083 static int
12084 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12085 {
12086   unformat_input_t *i = vam->input;
12087   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12088   u32 sw_if_index;
12089   u8 sw_if_index_set = 0;
12090   u8 vtr_op_set = 0;
12091   u32 vtr_op = 0;
12092   u32 push_dot1q = 1;
12093   u32 tag1 = ~0;
12094   u32 tag2 = ~0;
12095   int ret;
12096
12097   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12098     {
12099       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12100         sw_if_index_set = 1;
12101       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12102         sw_if_index_set = 1;
12103       else if (unformat (i, "vtr_op %d", &vtr_op))
12104         vtr_op_set = 1;
12105 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12106       foreach_vtr_op
12107 #undef _
12108         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12109         ;
12110       else if (unformat (i, "tag1 %d", &tag1))
12111         ;
12112       else if (unformat (i, "tag2 %d", &tag2))
12113         ;
12114       else
12115         {
12116           clib_warning ("parse error '%U'", format_unformat_error, i);
12117           return -99;
12118         }
12119     }
12120
12121   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12122     {
12123       errmsg ("missing vtr operation or sw_if_index");
12124       return -99;
12125     }
12126
12127   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12128   mp->sw_if_index = ntohl (sw_if_index);
12129   mp->vtr_op = ntohl (vtr_op);
12130   mp->push_dot1q = ntohl (push_dot1q);
12131   mp->tag1 = ntohl (tag1);
12132   mp->tag2 = ntohl (tag2);
12133
12134   S (mp);
12135   W (ret);
12136   return ret;
12137 }
12138
12139 static int
12140 api_create_vhost_user_if (vat_main_t * vam)
12141 {
12142   unformat_input_t *i = vam->input;
12143   vl_api_create_vhost_user_if_t *mp;
12144   u8 *file_name;
12145   u8 is_server = 0;
12146   u8 file_name_set = 0;
12147   u32 custom_dev_instance = ~0;
12148   u8 hwaddr[6];
12149   u8 use_custom_mac = 0;
12150   u8 *tag = 0;
12151   int ret;
12152
12153   /* Shut up coverity */
12154   memset (hwaddr, 0, sizeof (hwaddr));
12155
12156   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12157     {
12158       if (unformat (i, "socket %s", &file_name))
12159         {
12160           file_name_set = 1;
12161         }
12162       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12163         ;
12164       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12165         use_custom_mac = 1;
12166       else if (unformat (i, "server"))
12167         is_server = 1;
12168       else if (unformat (i, "tag %s", &tag))
12169         ;
12170       else
12171         break;
12172     }
12173
12174   if (file_name_set == 0)
12175     {
12176       errmsg ("missing socket file name");
12177       return -99;
12178     }
12179
12180   if (vec_len (file_name) > 255)
12181     {
12182       errmsg ("socket file name too long");
12183       return -99;
12184     }
12185   vec_add1 (file_name, 0);
12186
12187   M (CREATE_VHOST_USER_IF, mp);
12188
12189   mp->is_server = is_server;
12190   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12191   vec_free (file_name);
12192   if (custom_dev_instance != ~0)
12193     {
12194       mp->renumber = 1;
12195       mp->custom_dev_instance = ntohl (custom_dev_instance);
12196     }
12197   mp->use_custom_mac = use_custom_mac;
12198   clib_memcpy (mp->mac_address, hwaddr, 6);
12199   if (tag)
12200     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12201   vec_free (tag);
12202
12203   S (mp);
12204   W (ret);
12205   return ret;
12206 }
12207
12208 static int
12209 api_modify_vhost_user_if (vat_main_t * vam)
12210 {
12211   unformat_input_t *i = vam->input;
12212   vl_api_modify_vhost_user_if_t *mp;
12213   u8 *file_name;
12214   u8 is_server = 0;
12215   u8 file_name_set = 0;
12216   u32 custom_dev_instance = ~0;
12217   u8 sw_if_index_set = 0;
12218   u32 sw_if_index = (u32) ~ 0;
12219   int ret;
12220
12221   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12222     {
12223       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12224         sw_if_index_set = 1;
12225       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12226         sw_if_index_set = 1;
12227       else if (unformat (i, "socket %s", &file_name))
12228         {
12229           file_name_set = 1;
12230         }
12231       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12232         ;
12233       else if (unformat (i, "server"))
12234         is_server = 1;
12235       else
12236         break;
12237     }
12238
12239   if (sw_if_index_set == 0)
12240     {
12241       errmsg ("missing sw_if_index or interface name");
12242       return -99;
12243     }
12244
12245   if (file_name_set == 0)
12246     {
12247       errmsg ("missing socket file name");
12248       return -99;
12249     }
12250
12251   if (vec_len (file_name) > 255)
12252     {
12253       errmsg ("socket file name too long");
12254       return -99;
12255     }
12256   vec_add1 (file_name, 0);
12257
12258   M (MODIFY_VHOST_USER_IF, mp);
12259
12260   mp->sw_if_index = ntohl (sw_if_index);
12261   mp->is_server = is_server;
12262   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12263   vec_free (file_name);
12264   if (custom_dev_instance != ~0)
12265     {
12266       mp->renumber = 1;
12267       mp->custom_dev_instance = ntohl (custom_dev_instance);
12268     }
12269
12270   S (mp);
12271   W (ret);
12272   return ret;
12273 }
12274
12275 static int
12276 api_delete_vhost_user_if (vat_main_t * vam)
12277 {
12278   unformat_input_t *i = vam->input;
12279   vl_api_delete_vhost_user_if_t *mp;
12280   u32 sw_if_index = ~0;
12281   u8 sw_if_index_set = 0;
12282   int ret;
12283
12284   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12285     {
12286       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12287         sw_if_index_set = 1;
12288       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12289         sw_if_index_set = 1;
12290       else
12291         break;
12292     }
12293
12294   if (sw_if_index_set == 0)
12295     {
12296       errmsg ("missing sw_if_index or interface name");
12297       return -99;
12298     }
12299
12300
12301   M (DELETE_VHOST_USER_IF, mp);
12302
12303   mp->sw_if_index = ntohl (sw_if_index);
12304
12305   S (mp);
12306   W (ret);
12307   return ret;
12308 }
12309
12310 static void vl_api_sw_interface_vhost_user_details_t_handler
12311   (vl_api_sw_interface_vhost_user_details_t * mp)
12312 {
12313   vat_main_t *vam = &vat_main;
12314
12315   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12316          (char *) mp->interface_name,
12317          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12318          clib_net_to_host_u64 (mp->features), mp->is_server,
12319          ntohl (mp->num_regions), (char *) mp->sock_filename);
12320   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12321 }
12322
12323 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12324   (vl_api_sw_interface_vhost_user_details_t * mp)
12325 {
12326   vat_main_t *vam = &vat_main;
12327   vat_json_node_t *node = NULL;
12328
12329   if (VAT_JSON_ARRAY != vam->json_tree.type)
12330     {
12331       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12332       vat_json_init_array (&vam->json_tree);
12333     }
12334   node = vat_json_array_add (&vam->json_tree);
12335
12336   vat_json_init_object (node);
12337   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12338   vat_json_object_add_string_copy (node, "interface_name",
12339                                    mp->interface_name);
12340   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12341                             ntohl (mp->virtio_net_hdr_sz));
12342   vat_json_object_add_uint (node, "features",
12343                             clib_net_to_host_u64 (mp->features));
12344   vat_json_object_add_uint (node, "is_server", mp->is_server);
12345   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12346   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12347   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12348 }
12349
12350 static int
12351 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12352 {
12353   vl_api_sw_interface_vhost_user_dump_t *mp;
12354   vl_api_control_ping_t *mp_ping;
12355   int ret;
12356   print (vam->ofp,
12357          "Interface name            idx hdr_sz features server regions filename");
12358
12359   /* Get list of vhost-user interfaces */
12360   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12361   S (mp);
12362
12363   /* Use a control ping for synchronization */
12364   M (CONTROL_PING, mp_ping);
12365   S (mp_ping);
12366
12367   W (ret);
12368   return ret;
12369 }
12370
12371 static int
12372 api_show_version (vat_main_t * vam)
12373 {
12374   vl_api_show_version_t *mp;
12375   int ret;
12376
12377   M (SHOW_VERSION, mp);
12378
12379   S (mp);
12380   W (ret);
12381   return ret;
12382 }
12383
12384
12385 static int
12386 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12387 {
12388   unformat_input_t *line_input = vam->input;
12389   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12390   ip4_address_t local4, remote4;
12391   ip6_address_t local6, remote6;
12392   u8 is_add = 1;
12393   u8 ipv4_set = 0, ipv6_set = 0;
12394   u8 local_set = 0;
12395   u8 remote_set = 0;
12396   u8 grp_set = 0;
12397   u32 mcast_sw_if_index = ~0;
12398   u32 encap_vrf_id = 0;
12399   u32 decap_vrf_id = 0;
12400   u8 protocol = ~0;
12401   u32 vni;
12402   u8 vni_set = 0;
12403   int ret;
12404
12405   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12406   memset (&local4, 0, sizeof local4);
12407   memset (&remote4, 0, sizeof remote4);
12408   memset (&local6, 0, sizeof local6);
12409   memset (&remote6, 0, sizeof remote6);
12410
12411   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12412     {
12413       if (unformat (line_input, "del"))
12414         is_add = 0;
12415       else if (unformat (line_input, "local %U",
12416                          unformat_ip4_address, &local4))
12417         {
12418           local_set = 1;
12419           ipv4_set = 1;
12420         }
12421       else if (unformat (line_input, "remote %U",
12422                          unformat_ip4_address, &remote4))
12423         {
12424           remote_set = 1;
12425           ipv4_set = 1;
12426         }
12427       else if (unformat (line_input, "local %U",
12428                          unformat_ip6_address, &local6))
12429         {
12430           local_set = 1;
12431           ipv6_set = 1;
12432         }
12433       else if (unformat (line_input, "remote %U",
12434                          unformat_ip6_address, &remote6))
12435         {
12436           remote_set = 1;
12437           ipv6_set = 1;
12438         }
12439       else if (unformat (line_input, "group %U %U",
12440                          unformat_ip4_address, &remote4,
12441                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12442         {
12443           grp_set = remote_set = 1;
12444           ipv4_set = 1;
12445         }
12446       else if (unformat (line_input, "group %U",
12447                          unformat_ip4_address, &remote4))
12448         {
12449           grp_set = remote_set = 1;
12450           ipv4_set = 1;
12451         }
12452       else if (unformat (line_input, "group %U %U",
12453                          unformat_ip6_address, &remote6,
12454                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12455         {
12456           grp_set = remote_set = 1;
12457           ipv6_set = 1;
12458         }
12459       else if (unformat (line_input, "group %U",
12460                          unformat_ip6_address, &remote6))
12461         {
12462           grp_set = remote_set = 1;
12463           ipv6_set = 1;
12464         }
12465       else
12466         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12467         ;
12468       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12469         ;
12470       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
12471         ;
12472       else if (unformat (line_input, "vni %d", &vni))
12473         vni_set = 1;
12474       else if (unformat (line_input, "next-ip4"))
12475         protocol = 1;
12476       else if (unformat (line_input, "next-ip6"))
12477         protocol = 2;
12478       else if (unformat (line_input, "next-ethernet"))
12479         protocol = 3;
12480       else if (unformat (line_input, "next-nsh"))
12481         protocol = 4;
12482       else
12483         {
12484           errmsg ("parse error '%U'", format_unformat_error, line_input);
12485           return -99;
12486         }
12487     }
12488
12489   if (local_set == 0)
12490     {
12491       errmsg ("tunnel local address not specified");
12492       return -99;
12493     }
12494   if (remote_set == 0)
12495     {
12496       errmsg ("tunnel remote address not specified");
12497       return -99;
12498     }
12499   if (grp_set && mcast_sw_if_index == ~0)
12500     {
12501       errmsg ("tunnel nonexistent multicast device");
12502       return -99;
12503     }
12504   if (ipv4_set && ipv6_set)
12505     {
12506       errmsg ("both IPv4 and IPv6 addresses specified");
12507       return -99;
12508     }
12509
12510   if (vni_set == 0)
12511     {
12512       errmsg ("vni not specified");
12513       return -99;
12514     }
12515
12516   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
12517
12518
12519   if (ipv6_set)
12520     {
12521       clib_memcpy (&mp->local, &local6, sizeof (local6));
12522       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
12523     }
12524   else
12525     {
12526       clib_memcpy (&mp->local, &local4, sizeof (local4));
12527       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
12528     }
12529
12530   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12531   mp->encap_vrf_id = ntohl (encap_vrf_id);
12532   mp->decap_vrf_id = ntohl (decap_vrf_id);
12533   mp->protocol = protocol;
12534   mp->vni = ntohl (vni);
12535   mp->is_add = is_add;
12536   mp->is_ipv6 = ipv6_set;
12537
12538   S (mp);
12539   W (ret);
12540   return ret;
12541 }
12542
12543 static void vl_api_vxlan_gpe_tunnel_details_t_handler
12544   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12545 {
12546   vat_main_t *vam = &vat_main;
12547   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
12548   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
12549
12550   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
12551          ntohl (mp->sw_if_index),
12552          format_ip46_address, &local, IP46_TYPE_ANY,
12553          format_ip46_address, &remote, IP46_TYPE_ANY,
12554          ntohl (mp->vni), mp->protocol,
12555          ntohl (mp->mcast_sw_if_index),
12556          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
12557 }
12558
12559
12560 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
12561   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12562 {
12563   vat_main_t *vam = &vat_main;
12564   vat_json_node_t *node = NULL;
12565   struct in_addr ip4;
12566   struct in6_addr ip6;
12567
12568   if (VAT_JSON_ARRAY != vam->json_tree.type)
12569     {
12570       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12571       vat_json_init_array (&vam->json_tree);
12572     }
12573   node = vat_json_array_add (&vam->json_tree);
12574
12575   vat_json_init_object (node);
12576   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12577   if (mp->is_ipv6)
12578     {
12579       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
12580       vat_json_object_add_ip6 (node, "local", ip6);
12581       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
12582       vat_json_object_add_ip6 (node, "remote", ip6);
12583     }
12584   else
12585     {
12586       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
12587       vat_json_object_add_ip4 (node, "local", ip4);
12588       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
12589       vat_json_object_add_ip4 (node, "remote", ip4);
12590     }
12591   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12592   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
12593   vat_json_object_add_uint (node, "mcast_sw_if_index",
12594                             ntohl (mp->mcast_sw_if_index));
12595   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12596   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
12597   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12598 }
12599
12600 static int
12601 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
12602 {
12603   unformat_input_t *i = vam->input;
12604   vl_api_vxlan_gpe_tunnel_dump_t *mp;
12605   vl_api_control_ping_t *mp_ping;
12606   u32 sw_if_index;
12607   u8 sw_if_index_set = 0;
12608   int ret;
12609
12610   /* Parse args required to build the message */
12611   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12612     {
12613       if (unformat (i, "sw_if_index %d", &sw_if_index))
12614         sw_if_index_set = 1;
12615       else
12616         break;
12617     }
12618
12619   if (sw_if_index_set == 0)
12620     {
12621       sw_if_index = ~0;
12622     }
12623
12624   if (!vam->json_output)
12625     {
12626       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
12627              "sw_if_index", "local", "remote", "vni",
12628              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
12629     }
12630
12631   /* Get list of vxlan-tunnel interfaces */
12632   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12633
12634   mp->sw_if_index = htonl (sw_if_index);
12635
12636   S (mp);
12637
12638   /* Use a control ping for synchronization */
12639   M (CONTROL_PING, mp_ping);
12640   S (mp_ping);
12641
12642   W (ret);
12643   return ret;
12644 }
12645
12646
12647 u8 *
12648 format_l2_fib_mac_address (u8 * s, va_list * args)
12649 {
12650   u8 *a = va_arg (*args, u8 *);
12651
12652   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
12653                  a[2], a[3], a[4], a[5], a[6], a[7]);
12654 }
12655
12656 static void vl_api_l2_fib_table_details_t_handler
12657   (vl_api_l2_fib_table_details_t * mp)
12658 {
12659   vat_main_t *vam = &vat_main;
12660
12661   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
12662          "       %d       %d     %d",
12663          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
12664          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
12665          mp->bvi_mac);
12666 }
12667
12668 static void vl_api_l2_fib_table_details_t_handler_json
12669   (vl_api_l2_fib_table_details_t * mp)
12670 {
12671   vat_main_t *vam = &vat_main;
12672   vat_json_node_t *node = NULL;
12673
12674   if (VAT_JSON_ARRAY != vam->json_tree.type)
12675     {
12676       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12677       vat_json_init_array (&vam->json_tree);
12678     }
12679   node = vat_json_array_add (&vam->json_tree);
12680
12681   vat_json_init_object (node);
12682   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
12683   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
12684   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12685   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
12686   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
12687   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
12688 }
12689
12690 static int
12691 api_l2_fib_table_dump (vat_main_t * vam)
12692 {
12693   unformat_input_t *i = vam->input;
12694   vl_api_l2_fib_table_dump_t *mp;
12695   vl_api_control_ping_t *mp_ping;
12696   u32 bd_id;
12697   u8 bd_id_set = 0;
12698   int ret;
12699
12700   /* Parse args required to build the message */
12701   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12702     {
12703       if (unformat (i, "bd_id %d", &bd_id))
12704         bd_id_set = 1;
12705       else
12706         break;
12707     }
12708
12709   if (bd_id_set == 0)
12710     {
12711       errmsg ("missing bridge domain");
12712       return -99;
12713     }
12714
12715   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
12716
12717   /* Get list of l2 fib entries */
12718   M (L2_FIB_TABLE_DUMP, mp);
12719
12720   mp->bd_id = ntohl (bd_id);
12721   S (mp);
12722
12723   /* Use a control ping for synchronization */
12724   M (CONTROL_PING, mp_ping);
12725   S (mp_ping);
12726
12727   W (ret);
12728   return ret;
12729 }
12730
12731
12732 static int
12733 api_interface_name_renumber (vat_main_t * vam)
12734 {
12735   unformat_input_t *line_input = vam->input;
12736   vl_api_interface_name_renumber_t *mp;
12737   u32 sw_if_index = ~0;
12738   u32 new_show_dev_instance = ~0;
12739   int ret;
12740
12741   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12742     {
12743       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
12744                     &sw_if_index))
12745         ;
12746       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12747         ;
12748       else if (unformat (line_input, "new_show_dev_instance %d",
12749                          &new_show_dev_instance))
12750         ;
12751       else
12752         break;
12753     }
12754
12755   if (sw_if_index == ~0)
12756     {
12757       errmsg ("missing interface name or sw_if_index");
12758       return -99;
12759     }
12760
12761   if (new_show_dev_instance == ~0)
12762     {
12763       errmsg ("missing new_show_dev_instance");
12764       return -99;
12765     }
12766
12767   M (INTERFACE_NAME_RENUMBER, mp);
12768
12769   mp->sw_if_index = ntohl (sw_if_index);
12770   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
12771
12772   S (mp);
12773   W (ret);
12774   return ret;
12775 }
12776
12777 static int
12778 api_want_ip4_arp_events (vat_main_t * vam)
12779 {
12780   unformat_input_t *line_input = vam->input;
12781   vl_api_want_ip4_arp_events_t *mp;
12782   ip4_address_t address;
12783   int address_set = 0;
12784   u32 enable_disable = 1;
12785   int ret;
12786
12787   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12788     {
12789       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
12790         address_set = 1;
12791       else if (unformat (line_input, "del"))
12792         enable_disable = 0;
12793       else
12794         break;
12795     }
12796
12797   if (address_set == 0)
12798     {
12799       errmsg ("missing addresses");
12800       return -99;
12801     }
12802
12803   M (WANT_IP4_ARP_EVENTS, mp);
12804   mp->enable_disable = enable_disable;
12805   mp->pid = htonl (getpid ());
12806   mp->address = address.as_u32;
12807
12808   S (mp);
12809   W (ret);
12810   return ret;
12811 }
12812
12813 static int
12814 api_want_ip6_nd_events (vat_main_t * vam)
12815 {
12816   unformat_input_t *line_input = vam->input;
12817   vl_api_want_ip6_nd_events_t *mp;
12818   ip6_address_t address;
12819   int address_set = 0;
12820   u32 enable_disable = 1;
12821   int ret;
12822
12823   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12824     {
12825       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
12826         address_set = 1;
12827       else if (unformat (line_input, "del"))
12828         enable_disable = 0;
12829       else
12830         break;
12831     }
12832
12833   if (address_set == 0)
12834     {
12835       errmsg ("missing addresses");
12836       return -99;
12837     }
12838
12839   M (WANT_IP6_ND_EVENTS, mp);
12840   mp->enable_disable = enable_disable;
12841   mp->pid = htonl (getpid ());
12842   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
12843
12844   S (mp);
12845   W (ret);
12846   return ret;
12847 }
12848
12849 static int
12850 api_want_l2_macs_events (vat_main_t * vam)
12851 {
12852   unformat_input_t *line_input = vam->input;
12853   vl_api_want_l2_macs_events_t *mp;
12854   u8 enable_disable = 1;
12855   u32 scan_delay = 0;
12856   u32 max_macs_in_event = 0;
12857   u32 learn_limit = 0;
12858   int ret;
12859
12860   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12861     {
12862       if (unformat (line_input, "learn-limit %d", &learn_limit))
12863         ;
12864       else if (unformat (line_input, "scan-delay %d", &scan_delay))
12865         ;
12866       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
12867         ;
12868       else if (unformat (line_input, "disable"))
12869         enable_disable = 0;
12870       else
12871         break;
12872     }
12873
12874   M (WANT_L2_MACS_EVENTS, mp);
12875   mp->enable_disable = enable_disable;
12876   mp->pid = htonl (getpid ());
12877   mp->learn_limit = htonl (learn_limit);
12878   mp->scan_delay = (u8) scan_delay;
12879   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
12880   S (mp);
12881   W (ret);
12882   return ret;
12883 }
12884
12885 static int
12886 api_input_acl_set_interface (vat_main_t * vam)
12887 {
12888   unformat_input_t *i = vam->input;
12889   vl_api_input_acl_set_interface_t *mp;
12890   u32 sw_if_index;
12891   int sw_if_index_set;
12892   u32 ip4_table_index = ~0;
12893   u32 ip6_table_index = ~0;
12894   u32 l2_table_index = ~0;
12895   u8 is_add = 1;
12896   int ret;
12897
12898   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12899     {
12900       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12901         sw_if_index_set = 1;
12902       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12903         sw_if_index_set = 1;
12904       else if (unformat (i, "del"))
12905         is_add = 0;
12906       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12907         ;
12908       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12909         ;
12910       else if (unformat (i, "l2-table %d", &l2_table_index))
12911         ;
12912       else
12913         {
12914           clib_warning ("parse error '%U'", format_unformat_error, i);
12915           return -99;
12916         }
12917     }
12918
12919   if (sw_if_index_set == 0)
12920     {
12921       errmsg ("missing interface name or sw_if_index");
12922       return -99;
12923     }
12924
12925   M (INPUT_ACL_SET_INTERFACE, mp);
12926
12927   mp->sw_if_index = ntohl (sw_if_index);
12928   mp->ip4_table_index = ntohl (ip4_table_index);
12929   mp->ip6_table_index = ntohl (ip6_table_index);
12930   mp->l2_table_index = ntohl (l2_table_index);
12931   mp->is_add = is_add;
12932
12933   S (mp);
12934   W (ret);
12935   return ret;
12936 }
12937
12938 static int
12939 api_ip_address_dump (vat_main_t * vam)
12940 {
12941   unformat_input_t *i = vam->input;
12942   vl_api_ip_address_dump_t *mp;
12943   vl_api_control_ping_t *mp_ping;
12944   u32 sw_if_index = ~0;
12945   u8 sw_if_index_set = 0;
12946   u8 ipv4_set = 0;
12947   u8 ipv6_set = 0;
12948   int ret;
12949
12950   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12951     {
12952       if (unformat (i, "sw_if_index %d", &sw_if_index))
12953         sw_if_index_set = 1;
12954       else
12955         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12956         sw_if_index_set = 1;
12957       else if (unformat (i, "ipv4"))
12958         ipv4_set = 1;
12959       else if (unformat (i, "ipv6"))
12960         ipv6_set = 1;
12961       else
12962         break;
12963     }
12964
12965   if (ipv4_set && ipv6_set)
12966     {
12967       errmsg ("ipv4 and ipv6 flags cannot be both set");
12968       return -99;
12969     }
12970
12971   if ((!ipv4_set) && (!ipv6_set))
12972     {
12973       errmsg ("no ipv4 nor ipv6 flag set");
12974       return -99;
12975     }
12976
12977   if (sw_if_index_set == 0)
12978     {
12979       errmsg ("missing interface name or sw_if_index");
12980       return -99;
12981     }
12982
12983   vam->current_sw_if_index = sw_if_index;
12984   vam->is_ipv6 = ipv6_set;
12985
12986   M (IP_ADDRESS_DUMP, mp);
12987   mp->sw_if_index = ntohl (sw_if_index);
12988   mp->is_ipv6 = ipv6_set;
12989   S (mp);
12990
12991   /* Use a control ping for synchronization */
12992   M (CONTROL_PING, mp_ping);
12993   S (mp_ping);
12994
12995   W (ret);
12996   return ret;
12997 }
12998
12999 static int
13000 api_ip_dump (vat_main_t * vam)
13001 {
13002   vl_api_ip_dump_t *mp;
13003   vl_api_control_ping_t *mp_ping;
13004   unformat_input_t *in = vam->input;
13005   int ipv4_set = 0;
13006   int ipv6_set = 0;
13007   int is_ipv6;
13008   int i;
13009   int ret;
13010
13011   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13012     {
13013       if (unformat (in, "ipv4"))
13014         ipv4_set = 1;
13015       else if (unformat (in, "ipv6"))
13016         ipv6_set = 1;
13017       else
13018         break;
13019     }
13020
13021   if (ipv4_set && ipv6_set)
13022     {
13023       errmsg ("ipv4 and ipv6 flags cannot be both set");
13024       return -99;
13025     }
13026
13027   if ((!ipv4_set) && (!ipv6_set))
13028     {
13029       errmsg ("no ipv4 nor ipv6 flag set");
13030       return -99;
13031     }
13032
13033   is_ipv6 = ipv6_set;
13034   vam->is_ipv6 = is_ipv6;
13035
13036   /* free old data */
13037   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13038     {
13039       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13040     }
13041   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13042
13043   M (IP_DUMP, mp);
13044   mp->is_ipv6 = ipv6_set;
13045   S (mp);
13046
13047   /* Use a control ping for synchronization */
13048   M (CONTROL_PING, mp_ping);
13049   S (mp_ping);
13050
13051   W (ret);
13052   return ret;
13053 }
13054
13055 static int
13056 api_ipsec_spd_add_del (vat_main_t * vam)
13057 {
13058   unformat_input_t *i = vam->input;
13059   vl_api_ipsec_spd_add_del_t *mp;
13060   u32 spd_id = ~0;
13061   u8 is_add = 1;
13062   int ret;
13063
13064   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13065     {
13066       if (unformat (i, "spd_id %d", &spd_id))
13067         ;
13068       else if (unformat (i, "del"))
13069         is_add = 0;
13070       else
13071         {
13072           clib_warning ("parse error '%U'", format_unformat_error, i);
13073           return -99;
13074         }
13075     }
13076   if (spd_id == ~0)
13077     {
13078       errmsg ("spd_id must be set");
13079       return -99;
13080     }
13081
13082   M (IPSEC_SPD_ADD_DEL, mp);
13083
13084   mp->spd_id = ntohl (spd_id);
13085   mp->is_add = is_add;
13086
13087   S (mp);
13088   W (ret);
13089   return ret;
13090 }
13091
13092 static int
13093 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13094 {
13095   unformat_input_t *i = vam->input;
13096   vl_api_ipsec_interface_add_del_spd_t *mp;
13097   u32 sw_if_index;
13098   u8 sw_if_index_set = 0;
13099   u32 spd_id = (u32) ~ 0;
13100   u8 is_add = 1;
13101   int ret;
13102
13103   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13104     {
13105       if (unformat (i, "del"))
13106         is_add = 0;
13107       else if (unformat (i, "spd_id %d", &spd_id))
13108         ;
13109       else
13110         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13111         sw_if_index_set = 1;
13112       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13113         sw_if_index_set = 1;
13114       else
13115         {
13116           clib_warning ("parse error '%U'", format_unformat_error, i);
13117           return -99;
13118         }
13119
13120     }
13121
13122   if (spd_id == (u32) ~ 0)
13123     {
13124       errmsg ("spd_id must be set");
13125       return -99;
13126     }
13127
13128   if (sw_if_index_set == 0)
13129     {
13130       errmsg ("missing interface name or sw_if_index");
13131       return -99;
13132     }
13133
13134   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13135
13136   mp->spd_id = ntohl (spd_id);
13137   mp->sw_if_index = ntohl (sw_if_index);
13138   mp->is_add = is_add;
13139
13140   S (mp);
13141   W (ret);
13142   return ret;
13143 }
13144
13145 static int
13146 api_ipsec_spd_add_del_entry (vat_main_t * vam)
13147 {
13148   unformat_input_t *i = vam->input;
13149   vl_api_ipsec_spd_add_del_entry_t *mp;
13150   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
13151   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13152   i32 priority = 0;
13153   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13154   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13155   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
13156   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
13157   int ret;
13158
13159   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
13160   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
13161   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
13162   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
13163   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
13164   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
13165
13166   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13167     {
13168       if (unformat (i, "del"))
13169         is_add = 0;
13170       if (unformat (i, "outbound"))
13171         is_outbound = 1;
13172       if (unformat (i, "inbound"))
13173         is_outbound = 0;
13174       else if (unformat (i, "spd_id %d", &spd_id))
13175         ;
13176       else if (unformat (i, "sa_id %d", &sa_id))
13177         ;
13178       else if (unformat (i, "priority %d", &priority))
13179         ;
13180       else if (unformat (i, "protocol %d", &protocol))
13181         ;
13182       else if (unformat (i, "lport_start %d", &lport_start))
13183         ;
13184       else if (unformat (i, "lport_stop %d", &lport_stop))
13185         ;
13186       else if (unformat (i, "rport_start %d", &rport_start))
13187         ;
13188       else if (unformat (i, "rport_stop %d", &rport_stop))
13189         ;
13190       else
13191         if (unformat
13192             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
13193         {
13194           is_ipv6 = 0;
13195           is_ip_any = 0;
13196         }
13197       else
13198         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
13199         {
13200           is_ipv6 = 0;
13201           is_ip_any = 0;
13202         }
13203       else
13204         if (unformat
13205             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
13206         {
13207           is_ipv6 = 0;
13208           is_ip_any = 0;
13209         }
13210       else
13211         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
13212         {
13213           is_ipv6 = 0;
13214           is_ip_any = 0;
13215         }
13216       else
13217         if (unformat
13218             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
13219         {
13220           is_ipv6 = 1;
13221           is_ip_any = 0;
13222         }
13223       else
13224         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
13225         {
13226           is_ipv6 = 1;
13227           is_ip_any = 0;
13228         }
13229       else
13230         if (unformat
13231             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
13232         {
13233           is_ipv6 = 1;
13234           is_ip_any = 0;
13235         }
13236       else
13237         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
13238         {
13239           is_ipv6 = 1;
13240           is_ip_any = 0;
13241         }
13242       else
13243         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13244         {
13245           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13246             {
13247               clib_warning ("unsupported action: 'resolve'");
13248               return -99;
13249             }
13250         }
13251       else
13252         {
13253           clib_warning ("parse error '%U'", format_unformat_error, i);
13254           return -99;
13255         }
13256
13257     }
13258
13259   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
13260
13261   mp->spd_id = ntohl (spd_id);
13262   mp->priority = ntohl (priority);
13263   mp->is_outbound = is_outbound;
13264
13265   mp->is_ipv6 = is_ipv6;
13266   if (is_ipv6 || is_ip_any)
13267     {
13268       clib_memcpy (mp->remote_address_start, &raddr6_start,
13269                    sizeof (ip6_address_t));
13270       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
13271                    sizeof (ip6_address_t));
13272       clib_memcpy (mp->local_address_start, &laddr6_start,
13273                    sizeof (ip6_address_t));
13274       clib_memcpy (mp->local_address_stop, &laddr6_stop,
13275                    sizeof (ip6_address_t));
13276     }
13277   else
13278     {
13279       clib_memcpy (mp->remote_address_start, &raddr4_start,
13280                    sizeof (ip4_address_t));
13281       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
13282                    sizeof (ip4_address_t));
13283       clib_memcpy (mp->local_address_start, &laddr4_start,
13284                    sizeof (ip4_address_t));
13285       clib_memcpy (mp->local_address_stop, &laddr4_stop,
13286                    sizeof (ip4_address_t));
13287     }
13288   mp->protocol = (u8) protocol;
13289   mp->local_port_start = ntohs ((u16) lport_start);
13290   mp->local_port_stop = ntohs ((u16) lport_stop);
13291   mp->remote_port_start = ntohs ((u16) rport_start);
13292   mp->remote_port_stop = ntohs ((u16) rport_stop);
13293   mp->policy = (u8) policy;
13294   mp->sa_id = ntohl (sa_id);
13295   mp->is_add = is_add;
13296   mp->is_ip_any = is_ip_any;
13297   S (mp);
13298   W (ret);
13299   return ret;
13300 }
13301
13302 static int
13303 api_ipsec_sad_add_del_entry (vat_main_t * vam)
13304 {
13305   unformat_input_t *i = vam->input;
13306   vl_api_ipsec_sad_add_del_entry_t *mp;
13307   u32 sad_id = 0, spi = 0;
13308   u8 *ck = 0, *ik = 0;
13309   u8 is_add = 1;
13310
13311   u8 protocol = IPSEC_PROTOCOL_AH;
13312   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
13313   u32 crypto_alg = 0, integ_alg = 0;
13314   ip4_address_t tun_src4;
13315   ip4_address_t tun_dst4;
13316   ip6_address_t tun_src6;
13317   ip6_address_t tun_dst6;
13318   int ret;
13319
13320   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13321     {
13322       if (unformat (i, "del"))
13323         is_add = 0;
13324       else if (unformat (i, "sad_id %d", &sad_id))
13325         ;
13326       else if (unformat (i, "spi %d", &spi))
13327         ;
13328       else if (unformat (i, "esp"))
13329         protocol = IPSEC_PROTOCOL_ESP;
13330       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
13331         {
13332           is_tunnel = 1;
13333           is_tunnel_ipv6 = 0;
13334         }
13335       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
13336         {
13337           is_tunnel = 1;
13338           is_tunnel_ipv6 = 0;
13339         }
13340       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
13341         {
13342           is_tunnel = 1;
13343           is_tunnel_ipv6 = 1;
13344         }
13345       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
13346         {
13347           is_tunnel = 1;
13348           is_tunnel_ipv6 = 1;
13349         }
13350       else
13351         if (unformat
13352             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
13353         {
13354           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
13355               crypto_alg >= IPSEC_CRYPTO_N_ALG)
13356             {
13357               clib_warning ("unsupported crypto-alg: '%U'",
13358                             format_ipsec_crypto_alg, crypto_alg);
13359               return -99;
13360             }
13361         }
13362       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13363         ;
13364       else
13365         if (unformat
13366             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
13367         {
13368           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
13369               integ_alg >= IPSEC_INTEG_N_ALG)
13370             {
13371               clib_warning ("unsupported integ-alg: '%U'",
13372                             format_ipsec_integ_alg, integ_alg);
13373               return -99;
13374             }
13375         }
13376       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13377         ;
13378       else
13379         {
13380           clib_warning ("parse error '%U'", format_unformat_error, i);
13381           return -99;
13382         }
13383
13384     }
13385
13386   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
13387
13388   mp->sad_id = ntohl (sad_id);
13389   mp->is_add = is_add;
13390   mp->protocol = protocol;
13391   mp->spi = ntohl (spi);
13392   mp->is_tunnel = is_tunnel;
13393   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
13394   mp->crypto_algorithm = crypto_alg;
13395   mp->integrity_algorithm = integ_alg;
13396   mp->crypto_key_length = vec_len (ck);
13397   mp->integrity_key_length = vec_len (ik);
13398
13399   if (mp->crypto_key_length > sizeof (mp->crypto_key))
13400     mp->crypto_key_length = sizeof (mp->crypto_key);
13401
13402   if (mp->integrity_key_length > sizeof (mp->integrity_key))
13403     mp->integrity_key_length = sizeof (mp->integrity_key);
13404
13405   if (ck)
13406     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
13407   if (ik)
13408     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
13409
13410   if (is_tunnel)
13411     {
13412       if (is_tunnel_ipv6)
13413         {
13414           clib_memcpy (mp->tunnel_src_address, &tun_src6,
13415                        sizeof (ip6_address_t));
13416           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
13417                        sizeof (ip6_address_t));
13418         }
13419       else
13420         {
13421           clib_memcpy (mp->tunnel_src_address, &tun_src4,
13422                        sizeof (ip4_address_t));
13423           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
13424                        sizeof (ip4_address_t));
13425         }
13426     }
13427
13428   S (mp);
13429   W (ret);
13430   return ret;
13431 }
13432
13433 static int
13434 api_ipsec_sa_set_key (vat_main_t * vam)
13435 {
13436   unformat_input_t *i = vam->input;
13437   vl_api_ipsec_sa_set_key_t *mp;
13438   u32 sa_id;
13439   u8 *ck = 0, *ik = 0;
13440   int ret;
13441
13442   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13443     {
13444       if (unformat (i, "sa_id %d", &sa_id))
13445         ;
13446       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13447         ;
13448       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13449         ;
13450       else
13451         {
13452           clib_warning ("parse error '%U'", format_unformat_error, i);
13453           return -99;
13454         }
13455     }
13456
13457   M (IPSEC_SA_SET_KEY, mp);
13458
13459   mp->sa_id = ntohl (sa_id);
13460   mp->crypto_key_length = vec_len (ck);
13461   mp->integrity_key_length = vec_len (ik);
13462
13463   if (mp->crypto_key_length > sizeof (mp->crypto_key))
13464     mp->crypto_key_length = sizeof (mp->crypto_key);
13465
13466   if (mp->integrity_key_length > sizeof (mp->integrity_key))
13467     mp->integrity_key_length = sizeof (mp->integrity_key);
13468
13469   if (ck)
13470     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
13471   if (ik)
13472     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
13473
13474   S (mp);
13475   W (ret);
13476   return ret;
13477 }
13478
13479 static int
13480 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
13481 {
13482   unformat_input_t *i = vam->input;
13483   vl_api_ipsec_tunnel_if_add_del_t *mp;
13484   u32 local_spi = 0, remote_spi = 0;
13485   u32 crypto_alg = 0, integ_alg = 0;
13486   u8 *lck = NULL, *rck = NULL;
13487   u8 *lik = NULL, *rik = NULL;
13488   ip4_address_t local_ip = { {0} };
13489   ip4_address_t remote_ip = { {0} };
13490   u8 is_add = 1;
13491   u8 esn = 0;
13492   u8 anti_replay = 0;
13493   int ret;
13494
13495   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13496     {
13497       if (unformat (i, "del"))
13498         is_add = 0;
13499       else if (unformat (i, "esn"))
13500         esn = 1;
13501       else if (unformat (i, "anti_replay"))
13502         anti_replay = 1;
13503       else if (unformat (i, "local_spi %d", &local_spi))
13504         ;
13505       else if (unformat (i, "remote_spi %d", &remote_spi))
13506         ;
13507       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
13508         ;
13509       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
13510         ;
13511       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
13512         ;
13513       else
13514         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
13515         ;
13516       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
13517         ;
13518       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
13519         ;
13520       else
13521         if (unformat
13522             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
13523         {
13524           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
13525               crypto_alg >= IPSEC_CRYPTO_N_ALG)
13526             {
13527               errmsg ("unsupported crypto-alg: '%U'\n",
13528                       format_ipsec_crypto_alg, crypto_alg);
13529               return -99;
13530             }
13531         }
13532       else
13533         if (unformat
13534             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
13535         {
13536           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
13537               integ_alg >= IPSEC_INTEG_N_ALG)
13538             {
13539               errmsg ("unsupported integ-alg: '%U'\n",
13540                       format_ipsec_integ_alg, integ_alg);
13541               return -99;
13542             }
13543         }
13544       else
13545         {
13546           errmsg ("parse error '%U'\n", format_unformat_error, i);
13547           return -99;
13548         }
13549     }
13550
13551   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
13552
13553   mp->is_add = is_add;
13554   mp->esn = esn;
13555   mp->anti_replay = anti_replay;
13556
13557   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
13558   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
13559
13560   mp->local_spi = htonl (local_spi);
13561   mp->remote_spi = htonl (remote_spi);
13562   mp->crypto_alg = (u8) crypto_alg;
13563
13564   mp->local_crypto_key_len = 0;
13565   if (lck)
13566     {
13567       mp->local_crypto_key_len = vec_len (lck);
13568       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
13569         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
13570       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
13571     }
13572
13573   mp->remote_crypto_key_len = 0;
13574   if (rck)
13575     {
13576       mp->remote_crypto_key_len = vec_len (rck);
13577       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
13578         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
13579       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
13580     }
13581
13582   mp->integ_alg = (u8) integ_alg;
13583
13584   mp->local_integ_key_len = 0;
13585   if (lik)
13586     {
13587       mp->local_integ_key_len = vec_len (lik);
13588       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
13589         mp->local_integ_key_len = sizeof (mp->local_integ_key);
13590       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
13591     }
13592
13593   mp->remote_integ_key_len = 0;
13594   if (rik)
13595     {
13596       mp->remote_integ_key_len = vec_len (rik);
13597       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
13598         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
13599       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
13600     }
13601
13602   S (mp);
13603   W (ret);
13604   return ret;
13605 }
13606
13607 static int
13608 api_ikev2_profile_add_del (vat_main_t * vam)
13609 {
13610   unformat_input_t *i = vam->input;
13611   vl_api_ikev2_profile_add_del_t *mp;
13612   u8 is_add = 1;
13613   u8 *name = 0;
13614   int ret;
13615
13616   const char *valid_chars = "a-zA-Z0-9_";
13617
13618   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13619     {
13620       if (unformat (i, "del"))
13621         is_add = 0;
13622       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13623         vec_add1 (name, 0);
13624       else
13625         {
13626           errmsg ("parse error '%U'", format_unformat_error, i);
13627           return -99;
13628         }
13629     }
13630
13631   if (!vec_len (name))
13632     {
13633       errmsg ("profile name must be specified");
13634       return -99;
13635     }
13636
13637   if (vec_len (name) > 64)
13638     {
13639       errmsg ("profile name too long");
13640       return -99;
13641     }
13642
13643   M (IKEV2_PROFILE_ADD_DEL, mp);
13644
13645   clib_memcpy (mp->name, name, vec_len (name));
13646   mp->is_add = is_add;
13647   vec_free (name);
13648
13649   S (mp);
13650   W (ret);
13651   return ret;
13652 }
13653
13654 static int
13655 api_ikev2_profile_set_auth (vat_main_t * vam)
13656 {
13657   unformat_input_t *i = vam->input;
13658   vl_api_ikev2_profile_set_auth_t *mp;
13659   u8 *name = 0;
13660   u8 *data = 0;
13661   u32 auth_method = 0;
13662   u8 is_hex = 0;
13663   int ret;
13664
13665   const char *valid_chars = "a-zA-Z0-9_";
13666
13667   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13668     {
13669       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13670         vec_add1 (name, 0);
13671       else if (unformat (i, "auth_method %U",
13672                          unformat_ikev2_auth_method, &auth_method))
13673         ;
13674       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
13675         is_hex = 1;
13676       else if (unformat (i, "auth_data %v", &data))
13677         ;
13678       else
13679         {
13680           errmsg ("parse error '%U'", format_unformat_error, i);
13681           return -99;
13682         }
13683     }
13684
13685   if (!vec_len (name))
13686     {
13687       errmsg ("profile name must be specified");
13688       return -99;
13689     }
13690
13691   if (vec_len (name) > 64)
13692     {
13693       errmsg ("profile name too long");
13694       return -99;
13695     }
13696
13697   if (!vec_len (data))
13698     {
13699       errmsg ("auth_data must be specified");
13700       return -99;
13701     }
13702
13703   if (!auth_method)
13704     {
13705       errmsg ("auth_method must be specified");
13706       return -99;
13707     }
13708
13709   M (IKEV2_PROFILE_SET_AUTH, mp);
13710
13711   mp->is_hex = is_hex;
13712   mp->auth_method = (u8) auth_method;
13713   mp->data_len = vec_len (data);
13714   clib_memcpy (mp->name, name, vec_len (name));
13715   clib_memcpy (mp->data, data, vec_len (data));
13716   vec_free (name);
13717   vec_free (data);
13718
13719   S (mp);
13720   W (ret);
13721   return ret;
13722 }
13723
13724 static int
13725 api_ikev2_profile_set_id (vat_main_t * vam)
13726 {
13727   unformat_input_t *i = vam->input;
13728   vl_api_ikev2_profile_set_id_t *mp;
13729   u8 *name = 0;
13730   u8 *data = 0;
13731   u8 is_local = 0;
13732   u32 id_type = 0;
13733   ip4_address_t ip4;
13734   int ret;
13735
13736   const char *valid_chars = "a-zA-Z0-9_";
13737
13738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13739     {
13740       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13741         vec_add1 (name, 0);
13742       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
13743         ;
13744       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
13745         {
13746           data = vec_new (u8, 4);
13747           clib_memcpy (data, ip4.as_u8, 4);
13748         }
13749       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
13750         ;
13751       else if (unformat (i, "id_data %v", &data))
13752         ;
13753       else if (unformat (i, "local"))
13754         is_local = 1;
13755       else if (unformat (i, "remote"))
13756         is_local = 0;
13757       else
13758         {
13759           errmsg ("parse error '%U'", format_unformat_error, i);
13760           return -99;
13761         }
13762     }
13763
13764   if (!vec_len (name))
13765     {
13766       errmsg ("profile name must be specified");
13767       return -99;
13768     }
13769
13770   if (vec_len (name) > 64)
13771     {
13772       errmsg ("profile name too long");
13773       return -99;
13774     }
13775
13776   if (!vec_len (data))
13777     {
13778       errmsg ("id_data must be specified");
13779       return -99;
13780     }
13781
13782   if (!id_type)
13783     {
13784       errmsg ("id_type must be specified");
13785       return -99;
13786     }
13787
13788   M (IKEV2_PROFILE_SET_ID, mp);
13789
13790   mp->is_local = is_local;
13791   mp->id_type = (u8) id_type;
13792   mp->data_len = vec_len (data);
13793   clib_memcpy (mp->name, name, vec_len (name));
13794   clib_memcpy (mp->data, data, vec_len (data));
13795   vec_free (name);
13796   vec_free (data);
13797
13798   S (mp);
13799   W (ret);
13800   return ret;
13801 }
13802
13803 static int
13804 api_ikev2_profile_set_ts (vat_main_t * vam)
13805 {
13806   unformat_input_t *i = vam->input;
13807   vl_api_ikev2_profile_set_ts_t *mp;
13808   u8 *name = 0;
13809   u8 is_local = 0;
13810   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
13811   ip4_address_t start_addr, end_addr;
13812
13813   const char *valid_chars = "a-zA-Z0-9_";
13814   int ret;
13815
13816   start_addr.as_u32 = 0;
13817   end_addr.as_u32 = (u32) ~ 0;
13818
13819   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13820     {
13821       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13822         vec_add1 (name, 0);
13823       else if (unformat (i, "protocol %d", &proto))
13824         ;
13825       else if (unformat (i, "start_port %d", &start_port))
13826         ;
13827       else if (unformat (i, "end_port %d", &end_port))
13828         ;
13829       else
13830         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
13831         ;
13832       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
13833         ;
13834       else if (unformat (i, "local"))
13835         is_local = 1;
13836       else if (unformat (i, "remote"))
13837         is_local = 0;
13838       else
13839         {
13840           errmsg ("parse error '%U'", format_unformat_error, i);
13841           return -99;
13842         }
13843     }
13844
13845   if (!vec_len (name))
13846     {
13847       errmsg ("profile name must be specified");
13848       return -99;
13849     }
13850
13851   if (vec_len (name) > 64)
13852     {
13853       errmsg ("profile name too long");
13854       return -99;
13855     }
13856
13857   M (IKEV2_PROFILE_SET_TS, mp);
13858
13859   mp->is_local = is_local;
13860   mp->proto = (u8) proto;
13861   mp->start_port = (u16) start_port;
13862   mp->end_port = (u16) end_port;
13863   mp->start_addr = start_addr.as_u32;
13864   mp->end_addr = end_addr.as_u32;
13865   clib_memcpy (mp->name, name, vec_len (name));
13866   vec_free (name);
13867
13868   S (mp);
13869   W (ret);
13870   return ret;
13871 }
13872
13873 static int
13874 api_ikev2_set_local_key (vat_main_t * vam)
13875 {
13876   unformat_input_t *i = vam->input;
13877   vl_api_ikev2_set_local_key_t *mp;
13878   u8 *file = 0;
13879   int ret;
13880
13881   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13882     {
13883       if (unformat (i, "file %v", &file))
13884         vec_add1 (file, 0);
13885       else
13886         {
13887           errmsg ("parse error '%U'", format_unformat_error, i);
13888           return -99;
13889         }
13890     }
13891
13892   if (!vec_len (file))
13893     {
13894       errmsg ("RSA key file must be specified");
13895       return -99;
13896     }
13897
13898   if (vec_len (file) > 256)
13899     {
13900       errmsg ("file name too long");
13901       return -99;
13902     }
13903
13904   M (IKEV2_SET_LOCAL_KEY, mp);
13905
13906   clib_memcpy (mp->key_file, file, vec_len (file));
13907   vec_free (file);
13908
13909   S (mp);
13910   W (ret);
13911   return ret;
13912 }
13913
13914 static int
13915 api_ikev2_set_responder (vat_main_t * vam)
13916 {
13917   unformat_input_t *i = vam->input;
13918   vl_api_ikev2_set_responder_t *mp;
13919   int ret;
13920   u8 *name = 0;
13921   u32 sw_if_index = ~0;
13922   ip4_address_t address;
13923
13924   const char *valid_chars = "a-zA-Z0-9_";
13925
13926   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13927     {
13928       if (unformat
13929           (i, "%U interface %d address %U", unformat_token, valid_chars,
13930            &name, &sw_if_index, unformat_ip4_address, &address))
13931         vec_add1 (name, 0);
13932       else
13933         {
13934           errmsg ("parse error '%U'", format_unformat_error, i);
13935           return -99;
13936         }
13937     }
13938
13939   if (!vec_len (name))
13940     {
13941       errmsg ("profile name must be specified");
13942       return -99;
13943     }
13944
13945   if (vec_len (name) > 64)
13946     {
13947       errmsg ("profile name too long");
13948       return -99;
13949     }
13950
13951   M (IKEV2_SET_RESPONDER, mp);
13952
13953   clib_memcpy (mp->name, name, vec_len (name));
13954   vec_free (name);
13955
13956   mp->sw_if_index = sw_if_index;
13957   clib_memcpy (mp->address, &address, sizeof (address));
13958
13959   S (mp);
13960   W (ret);
13961   return ret;
13962 }
13963
13964 static int
13965 api_ikev2_set_ike_transforms (vat_main_t * vam)
13966 {
13967   unformat_input_t *i = vam->input;
13968   vl_api_ikev2_set_ike_transforms_t *mp;
13969   int ret;
13970   u8 *name = 0;
13971   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13972
13973   const char *valid_chars = "a-zA-Z0-9_";
13974
13975   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13976     {
13977       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13978                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13979         vec_add1 (name, 0);
13980       else
13981         {
13982           errmsg ("parse error '%U'", format_unformat_error, i);
13983           return -99;
13984         }
13985     }
13986
13987   if (!vec_len (name))
13988     {
13989       errmsg ("profile name must be specified");
13990       return -99;
13991     }
13992
13993   if (vec_len (name) > 64)
13994     {
13995       errmsg ("profile name too long");
13996       return -99;
13997     }
13998
13999   M (IKEV2_SET_IKE_TRANSFORMS, mp);
14000
14001   clib_memcpy (mp->name, name, vec_len (name));
14002   vec_free (name);
14003   mp->crypto_alg = crypto_alg;
14004   mp->crypto_key_size = crypto_key_size;
14005   mp->integ_alg = integ_alg;
14006   mp->dh_group = dh_group;
14007
14008   S (mp);
14009   W (ret);
14010   return ret;
14011 }
14012
14013
14014 static int
14015 api_ikev2_set_esp_transforms (vat_main_t * vam)
14016 {
14017   unformat_input_t *i = vam->input;
14018   vl_api_ikev2_set_esp_transforms_t *mp;
14019   int ret;
14020   u8 *name = 0;
14021   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
14022
14023   const char *valid_chars = "a-zA-Z0-9_";
14024
14025   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14026     {
14027       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
14028                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
14029         vec_add1 (name, 0);
14030       else
14031         {
14032           errmsg ("parse error '%U'", format_unformat_error, i);
14033           return -99;
14034         }
14035     }
14036
14037   if (!vec_len (name))
14038     {
14039       errmsg ("profile name must be specified");
14040       return -99;
14041     }
14042
14043   if (vec_len (name) > 64)
14044     {
14045       errmsg ("profile name too long");
14046       return -99;
14047     }
14048
14049   M (IKEV2_SET_ESP_TRANSFORMS, mp);
14050
14051   clib_memcpy (mp->name, name, vec_len (name));
14052   vec_free (name);
14053   mp->crypto_alg = crypto_alg;
14054   mp->crypto_key_size = crypto_key_size;
14055   mp->integ_alg = integ_alg;
14056   mp->dh_group = dh_group;
14057
14058   S (mp);
14059   W (ret);
14060   return ret;
14061 }
14062
14063 static int
14064 api_ikev2_set_sa_lifetime (vat_main_t * vam)
14065 {
14066   unformat_input_t *i = vam->input;
14067   vl_api_ikev2_set_sa_lifetime_t *mp;
14068   int ret;
14069   u8 *name = 0;
14070   u64 lifetime, lifetime_maxdata;
14071   u32 lifetime_jitter, handover;
14072
14073   const char *valid_chars = "a-zA-Z0-9_";
14074
14075   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14076     {
14077       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
14078                     &lifetime, &lifetime_jitter, &handover,
14079                     &lifetime_maxdata))
14080         vec_add1 (name, 0);
14081       else
14082         {
14083           errmsg ("parse error '%U'", format_unformat_error, i);
14084           return -99;
14085         }
14086     }
14087
14088   if (!vec_len (name))
14089     {
14090       errmsg ("profile name must be specified");
14091       return -99;
14092     }
14093
14094   if (vec_len (name) > 64)
14095     {
14096       errmsg ("profile name too long");
14097       return -99;
14098     }
14099
14100   M (IKEV2_SET_SA_LIFETIME, mp);
14101
14102   clib_memcpy (mp->name, name, vec_len (name));
14103   vec_free (name);
14104   mp->lifetime = lifetime;
14105   mp->lifetime_jitter = lifetime_jitter;
14106   mp->handover = handover;
14107   mp->lifetime_maxdata = lifetime_maxdata;
14108
14109   S (mp);
14110   W (ret);
14111   return ret;
14112 }
14113
14114 static int
14115 api_ikev2_initiate_sa_init (vat_main_t * vam)
14116 {
14117   unformat_input_t *i = vam->input;
14118   vl_api_ikev2_initiate_sa_init_t *mp;
14119   int ret;
14120   u8 *name = 0;
14121
14122   const char *valid_chars = "a-zA-Z0-9_";
14123
14124   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14125     {
14126       if (unformat (i, "%U", unformat_token, valid_chars, &name))
14127         vec_add1 (name, 0);
14128       else
14129         {
14130           errmsg ("parse error '%U'", format_unformat_error, i);
14131           return -99;
14132         }
14133     }
14134
14135   if (!vec_len (name))
14136     {
14137       errmsg ("profile name must be specified");
14138       return -99;
14139     }
14140
14141   if (vec_len (name) > 64)
14142     {
14143       errmsg ("profile name too long");
14144       return -99;
14145     }
14146
14147   M (IKEV2_INITIATE_SA_INIT, mp);
14148
14149   clib_memcpy (mp->name, name, vec_len (name));
14150   vec_free (name);
14151
14152   S (mp);
14153   W (ret);
14154   return ret;
14155 }
14156
14157 static int
14158 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
14159 {
14160   unformat_input_t *i = vam->input;
14161   vl_api_ikev2_initiate_del_ike_sa_t *mp;
14162   int ret;
14163   u64 ispi;
14164
14165
14166   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14167     {
14168       if (unformat (i, "%lx", &ispi))
14169         ;
14170       else
14171         {
14172           errmsg ("parse error '%U'", format_unformat_error, i);
14173           return -99;
14174         }
14175     }
14176
14177   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
14178
14179   mp->ispi = ispi;
14180
14181   S (mp);
14182   W (ret);
14183   return ret;
14184 }
14185
14186 static int
14187 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
14188 {
14189   unformat_input_t *i = vam->input;
14190   vl_api_ikev2_initiate_del_child_sa_t *mp;
14191   int ret;
14192   u32 ispi;
14193
14194
14195   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14196     {
14197       if (unformat (i, "%x", &ispi))
14198         ;
14199       else
14200         {
14201           errmsg ("parse error '%U'", format_unformat_error, i);
14202           return -99;
14203         }
14204     }
14205
14206   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
14207
14208   mp->ispi = ispi;
14209
14210   S (mp);
14211   W (ret);
14212   return ret;
14213 }
14214
14215 static int
14216 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
14217 {
14218   unformat_input_t *i = vam->input;
14219   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
14220   int ret;
14221   u32 ispi;
14222
14223
14224   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14225     {
14226       if (unformat (i, "%x", &ispi))
14227         ;
14228       else
14229         {
14230           errmsg ("parse error '%U'", format_unformat_error, i);
14231           return -99;
14232         }
14233     }
14234
14235   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
14236
14237   mp->ispi = ispi;
14238
14239   S (mp);
14240   W (ret);
14241   return ret;
14242 }
14243
14244 /*
14245  * MAP
14246  */
14247 static int
14248 api_map_add_domain (vat_main_t * vam)
14249 {
14250   unformat_input_t *i = vam->input;
14251   vl_api_map_add_domain_t *mp;
14252
14253   ip4_address_t ip4_prefix;
14254   ip6_address_t ip6_prefix;
14255   ip6_address_t ip6_src;
14256   u32 num_m_args = 0;
14257   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
14258     0, psid_length = 0;
14259   u8 is_translation = 0;
14260   u32 mtu = 0;
14261   u32 ip6_src_len = 128;
14262   int ret;
14263
14264   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14265     {
14266       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
14267                     &ip4_prefix, &ip4_prefix_len))
14268         num_m_args++;
14269       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
14270                          &ip6_prefix, &ip6_prefix_len))
14271         num_m_args++;
14272       else
14273         if (unformat
14274             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
14275              &ip6_src_len))
14276         num_m_args++;
14277       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
14278         num_m_args++;
14279       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
14280         num_m_args++;
14281       else if (unformat (i, "psid-offset %d", &psid_offset))
14282         num_m_args++;
14283       else if (unformat (i, "psid-len %d", &psid_length))
14284         num_m_args++;
14285       else if (unformat (i, "mtu %d", &mtu))
14286         num_m_args++;
14287       else if (unformat (i, "map-t"))
14288         is_translation = 1;
14289       else
14290         {
14291           clib_warning ("parse error '%U'", format_unformat_error, i);
14292           return -99;
14293         }
14294     }
14295
14296   if (num_m_args < 3)
14297     {
14298       errmsg ("mandatory argument(s) missing");
14299       return -99;
14300     }
14301
14302   /* Construct the API message */
14303   M (MAP_ADD_DOMAIN, mp);
14304
14305   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
14306   mp->ip4_prefix_len = ip4_prefix_len;
14307
14308   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
14309   mp->ip6_prefix_len = ip6_prefix_len;
14310
14311   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
14312   mp->ip6_src_prefix_len = ip6_src_len;
14313
14314   mp->ea_bits_len = ea_bits_len;
14315   mp->psid_offset = psid_offset;
14316   mp->psid_length = psid_length;
14317   mp->is_translation = is_translation;
14318   mp->mtu = htons (mtu);
14319
14320   /* send it... */
14321   S (mp);
14322
14323   /* Wait for a reply, return good/bad news  */
14324   W (ret);
14325   return ret;
14326 }
14327
14328 static int
14329 api_map_del_domain (vat_main_t * vam)
14330 {
14331   unformat_input_t *i = vam->input;
14332   vl_api_map_del_domain_t *mp;
14333
14334   u32 num_m_args = 0;
14335   u32 index;
14336   int ret;
14337
14338   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14339     {
14340       if (unformat (i, "index %d", &index))
14341         num_m_args++;
14342       else
14343         {
14344           clib_warning ("parse error '%U'", format_unformat_error, i);
14345           return -99;
14346         }
14347     }
14348
14349   if (num_m_args != 1)
14350     {
14351       errmsg ("mandatory argument(s) missing");
14352       return -99;
14353     }
14354
14355   /* Construct the API message */
14356   M (MAP_DEL_DOMAIN, mp);
14357
14358   mp->index = ntohl (index);
14359
14360   /* send it... */
14361   S (mp);
14362
14363   /* Wait for a reply, return good/bad news  */
14364   W (ret);
14365   return ret;
14366 }
14367
14368 static int
14369 api_map_add_del_rule (vat_main_t * vam)
14370 {
14371   unformat_input_t *i = vam->input;
14372   vl_api_map_add_del_rule_t *mp;
14373   u8 is_add = 1;
14374   ip6_address_t ip6_dst;
14375   u32 num_m_args = 0, index, psid = 0;
14376   int ret;
14377
14378   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14379     {
14380       if (unformat (i, "index %d", &index))
14381         num_m_args++;
14382       else if (unformat (i, "psid %d", &psid))
14383         num_m_args++;
14384       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
14385         num_m_args++;
14386       else if (unformat (i, "del"))
14387         {
14388           is_add = 0;
14389         }
14390       else
14391         {
14392           clib_warning ("parse error '%U'", format_unformat_error, i);
14393           return -99;
14394         }
14395     }
14396
14397   /* Construct the API message */
14398   M (MAP_ADD_DEL_RULE, mp);
14399
14400   mp->index = ntohl (index);
14401   mp->is_add = is_add;
14402   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
14403   mp->psid = ntohs (psid);
14404
14405   /* send it... */
14406   S (mp);
14407
14408   /* Wait for a reply, return good/bad news  */
14409   W (ret);
14410   return ret;
14411 }
14412
14413 static int
14414 api_map_domain_dump (vat_main_t * vam)
14415 {
14416   vl_api_map_domain_dump_t *mp;
14417   vl_api_control_ping_t *mp_ping;
14418   int ret;
14419
14420   /* Construct the API message */
14421   M (MAP_DOMAIN_DUMP, mp);
14422
14423   /* send it... */
14424   S (mp);
14425
14426   /* Use a control ping for synchronization */
14427   M (CONTROL_PING, mp_ping);
14428   S (mp_ping);
14429
14430   W (ret);
14431   return ret;
14432 }
14433
14434 static int
14435 api_map_rule_dump (vat_main_t * vam)
14436 {
14437   unformat_input_t *i = vam->input;
14438   vl_api_map_rule_dump_t *mp;
14439   vl_api_control_ping_t *mp_ping;
14440   u32 domain_index = ~0;
14441   int ret;
14442
14443   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14444     {
14445       if (unformat (i, "index %u", &domain_index))
14446         ;
14447       else
14448         break;
14449     }
14450
14451   if (domain_index == ~0)
14452     {
14453       clib_warning ("parse error: domain index expected");
14454       return -99;
14455     }
14456
14457   /* Construct the API message */
14458   M (MAP_RULE_DUMP, mp);
14459
14460   mp->domain_index = htonl (domain_index);
14461
14462   /* send it... */
14463   S (mp);
14464
14465   /* Use a control ping for synchronization */
14466   M (CONTROL_PING, mp_ping);
14467   S (mp_ping);
14468
14469   W (ret);
14470   return ret;
14471 }
14472
14473 static void vl_api_map_add_domain_reply_t_handler
14474   (vl_api_map_add_domain_reply_t * mp)
14475 {
14476   vat_main_t *vam = &vat_main;
14477   i32 retval = ntohl (mp->retval);
14478
14479   if (vam->async_mode)
14480     {
14481       vam->async_errors += (retval < 0);
14482     }
14483   else
14484     {
14485       vam->retval = retval;
14486       vam->result_ready = 1;
14487     }
14488 }
14489
14490 static void vl_api_map_add_domain_reply_t_handler_json
14491   (vl_api_map_add_domain_reply_t * mp)
14492 {
14493   vat_main_t *vam = &vat_main;
14494   vat_json_node_t node;
14495
14496   vat_json_init_object (&node);
14497   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
14498   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
14499
14500   vat_json_print (vam->ofp, &node);
14501   vat_json_free (&node);
14502
14503   vam->retval = ntohl (mp->retval);
14504   vam->result_ready = 1;
14505 }
14506
14507 static int
14508 api_get_first_msg_id (vat_main_t * vam)
14509 {
14510   vl_api_get_first_msg_id_t *mp;
14511   unformat_input_t *i = vam->input;
14512   u8 *name;
14513   u8 name_set = 0;
14514   int ret;
14515
14516   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14517     {
14518       if (unformat (i, "client %s", &name))
14519         name_set = 1;
14520       else
14521         break;
14522     }
14523
14524   if (name_set == 0)
14525     {
14526       errmsg ("missing client name");
14527       return -99;
14528     }
14529   vec_add1 (name, 0);
14530
14531   if (vec_len (name) > 63)
14532     {
14533       errmsg ("client name too long");
14534       return -99;
14535     }
14536
14537   M (GET_FIRST_MSG_ID, mp);
14538   clib_memcpy (mp->name, name, vec_len (name));
14539   S (mp);
14540   W (ret);
14541   return ret;
14542 }
14543
14544 static int
14545 api_cop_interface_enable_disable (vat_main_t * vam)
14546 {
14547   unformat_input_t *line_input = vam->input;
14548   vl_api_cop_interface_enable_disable_t *mp;
14549   u32 sw_if_index = ~0;
14550   u8 enable_disable = 1;
14551   int ret;
14552
14553   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14554     {
14555       if (unformat (line_input, "disable"))
14556         enable_disable = 0;
14557       if (unformat (line_input, "enable"))
14558         enable_disable = 1;
14559       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14560                          vam, &sw_if_index))
14561         ;
14562       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14563         ;
14564       else
14565         break;
14566     }
14567
14568   if (sw_if_index == ~0)
14569     {
14570       errmsg ("missing interface name or sw_if_index");
14571       return -99;
14572     }
14573
14574   /* Construct the API message */
14575   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14576   mp->sw_if_index = ntohl (sw_if_index);
14577   mp->enable_disable = enable_disable;
14578
14579   /* send it... */
14580   S (mp);
14581   /* Wait for the reply */
14582   W (ret);
14583   return ret;
14584 }
14585
14586 static int
14587 api_cop_whitelist_enable_disable (vat_main_t * vam)
14588 {
14589   unformat_input_t *line_input = vam->input;
14590   vl_api_cop_whitelist_enable_disable_t *mp;
14591   u32 sw_if_index = ~0;
14592   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14593   u32 fib_id = 0;
14594   int ret;
14595
14596   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14597     {
14598       if (unformat (line_input, "ip4"))
14599         ip4 = 1;
14600       else if (unformat (line_input, "ip6"))
14601         ip6 = 1;
14602       else if (unformat (line_input, "default"))
14603         default_cop = 1;
14604       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14605                          vam, &sw_if_index))
14606         ;
14607       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14608         ;
14609       else if (unformat (line_input, "fib-id %d", &fib_id))
14610         ;
14611       else
14612         break;
14613     }
14614
14615   if (sw_if_index == ~0)
14616     {
14617       errmsg ("missing interface name or sw_if_index");
14618       return -99;
14619     }
14620
14621   /* Construct the API message */
14622   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14623   mp->sw_if_index = ntohl (sw_if_index);
14624   mp->fib_id = ntohl (fib_id);
14625   mp->ip4 = ip4;
14626   mp->ip6 = ip6;
14627   mp->default_cop = default_cop;
14628
14629   /* send it... */
14630   S (mp);
14631   /* Wait for the reply */
14632   W (ret);
14633   return ret;
14634 }
14635
14636 static int
14637 api_get_node_graph (vat_main_t * vam)
14638 {
14639   vl_api_get_node_graph_t *mp;
14640   int ret;
14641
14642   M (GET_NODE_GRAPH, mp);
14643
14644   /* send it... */
14645   S (mp);
14646   /* Wait for the reply */
14647   W (ret);
14648   return ret;
14649 }
14650
14651 /* *INDENT-OFF* */
14652 /** Used for parsing LISP eids */
14653 typedef CLIB_PACKED(struct{
14654   u8 addr[16];   /**< eid address */
14655   u32 len;       /**< prefix length if IP */
14656   u8 type;      /**< type of eid */
14657 }) lisp_eid_vat_t;
14658 /* *INDENT-ON* */
14659
14660 static uword
14661 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14662 {
14663   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14664
14665   memset (a, 0, sizeof (a[0]));
14666
14667   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
14668     {
14669       a->type = 0;              /* ipv4 type */
14670     }
14671   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
14672     {
14673       a->type = 1;              /* ipv6 type */
14674     }
14675   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
14676     {
14677       a->type = 2;              /* mac type */
14678     }
14679   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
14680     {
14681       a->type = 3;              /* NSH type */
14682       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
14683       nsh->spi = clib_host_to_net_u32 (nsh->spi);
14684     }
14685   else
14686     {
14687       return 0;
14688     }
14689
14690   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
14691     {
14692       return 0;
14693     }
14694
14695   return 1;
14696 }
14697
14698 static int
14699 lisp_eid_size_vat (u8 type)
14700 {
14701   switch (type)
14702     {
14703     case 0:
14704       return 4;
14705     case 1:
14706       return 16;
14707     case 2:
14708       return 6;
14709     case 3:
14710       return 5;
14711     }
14712   return 0;
14713 }
14714
14715 static void
14716 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
14717 {
14718   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
14719 }
14720
14721 static int
14722 api_one_add_del_locator_set (vat_main_t * vam)
14723 {
14724   unformat_input_t *input = vam->input;
14725   vl_api_one_add_del_locator_set_t *mp;
14726   u8 is_add = 1;
14727   u8 *locator_set_name = NULL;
14728   u8 locator_set_name_set = 0;
14729   vl_api_local_locator_t locator, *locators = 0;
14730   u32 sw_if_index, priority, weight;
14731   u32 data_len = 0;
14732
14733   int ret;
14734   /* Parse args required to build the message */
14735   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14736     {
14737       if (unformat (input, "del"))
14738         {
14739           is_add = 0;
14740         }
14741       else if (unformat (input, "locator-set %s", &locator_set_name))
14742         {
14743           locator_set_name_set = 1;
14744         }
14745       else if (unformat (input, "sw_if_index %u p %u w %u",
14746                          &sw_if_index, &priority, &weight))
14747         {
14748           locator.sw_if_index = htonl (sw_if_index);
14749           locator.priority = priority;
14750           locator.weight = weight;
14751           vec_add1 (locators, locator);
14752         }
14753       else
14754         if (unformat
14755             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14756              &sw_if_index, &priority, &weight))
14757         {
14758           locator.sw_if_index = htonl (sw_if_index);
14759           locator.priority = priority;
14760           locator.weight = weight;
14761           vec_add1 (locators, locator);
14762         }
14763       else
14764         break;
14765     }
14766
14767   if (locator_set_name_set == 0)
14768     {
14769       errmsg ("missing locator-set name");
14770       vec_free (locators);
14771       return -99;
14772     }
14773
14774   if (vec_len (locator_set_name) > 64)
14775     {
14776       errmsg ("locator-set name too long");
14777       vec_free (locator_set_name);
14778       vec_free (locators);
14779       return -99;
14780     }
14781   vec_add1 (locator_set_name, 0);
14782
14783   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14784
14785   /* Construct the API message */
14786   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14787
14788   mp->is_add = is_add;
14789   clib_memcpy (mp->locator_set_name, locator_set_name,
14790                vec_len (locator_set_name));
14791   vec_free (locator_set_name);
14792
14793   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14794   if (locators)
14795     clib_memcpy (mp->locators, locators, data_len);
14796   vec_free (locators);
14797
14798   /* send it... */
14799   S (mp);
14800
14801   /* Wait for a reply... */
14802   W (ret);
14803   return ret;
14804 }
14805
14806 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14807
14808 static int
14809 api_one_add_del_locator (vat_main_t * vam)
14810 {
14811   unformat_input_t *input = vam->input;
14812   vl_api_one_add_del_locator_t *mp;
14813   u32 tmp_if_index = ~0;
14814   u32 sw_if_index = ~0;
14815   u8 sw_if_index_set = 0;
14816   u8 sw_if_index_if_name_set = 0;
14817   u32 priority = ~0;
14818   u8 priority_set = 0;
14819   u32 weight = ~0;
14820   u8 weight_set = 0;
14821   u8 is_add = 1;
14822   u8 *locator_set_name = NULL;
14823   u8 locator_set_name_set = 0;
14824   int ret;
14825
14826   /* Parse args required to build the message */
14827   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14828     {
14829       if (unformat (input, "del"))
14830         {
14831           is_add = 0;
14832         }
14833       else if (unformat (input, "locator-set %s", &locator_set_name))
14834         {
14835           locator_set_name_set = 1;
14836         }
14837       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14838                          &tmp_if_index))
14839         {
14840           sw_if_index_if_name_set = 1;
14841           sw_if_index = tmp_if_index;
14842         }
14843       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14844         {
14845           sw_if_index_set = 1;
14846           sw_if_index = tmp_if_index;
14847         }
14848       else if (unformat (input, "p %d", &priority))
14849         {
14850           priority_set = 1;
14851         }
14852       else if (unformat (input, "w %d", &weight))
14853         {
14854           weight_set = 1;
14855         }
14856       else
14857         break;
14858     }
14859
14860   if (locator_set_name_set == 0)
14861     {
14862       errmsg ("missing locator-set name");
14863       return -99;
14864     }
14865
14866   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14867     {
14868       errmsg ("missing sw_if_index");
14869       vec_free (locator_set_name);
14870       return -99;
14871     }
14872
14873   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14874     {
14875       errmsg ("cannot use both params interface name and sw_if_index");
14876       vec_free (locator_set_name);
14877       return -99;
14878     }
14879
14880   if (priority_set == 0)
14881     {
14882       errmsg ("missing locator-set priority");
14883       vec_free (locator_set_name);
14884       return -99;
14885     }
14886
14887   if (weight_set == 0)
14888     {
14889       errmsg ("missing locator-set weight");
14890       vec_free (locator_set_name);
14891       return -99;
14892     }
14893
14894   if (vec_len (locator_set_name) > 64)
14895     {
14896       errmsg ("locator-set name too long");
14897       vec_free (locator_set_name);
14898       return -99;
14899     }
14900   vec_add1 (locator_set_name, 0);
14901
14902   /* Construct the API message */
14903   M (ONE_ADD_DEL_LOCATOR, mp);
14904
14905   mp->is_add = is_add;
14906   mp->sw_if_index = ntohl (sw_if_index);
14907   mp->priority = priority;
14908   mp->weight = weight;
14909   clib_memcpy (mp->locator_set_name, locator_set_name,
14910                vec_len (locator_set_name));
14911   vec_free (locator_set_name);
14912
14913   /* send it... */
14914   S (mp);
14915
14916   /* Wait for a reply... */
14917   W (ret);
14918   return ret;
14919 }
14920
14921 #define api_lisp_add_del_locator api_one_add_del_locator
14922
14923 uword
14924 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14925 {
14926   u32 *key_id = va_arg (*args, u32 *);
14927   u8 *s = 0;
14928
14929   if (unformat (input, "%s", &s))
14930     {
14931       if (!strcmp ((char *) s, "sha1"))
14932         key_id[0] = HMAC_SHA_1_96;
14933       else if (!strcmp ((char *) s, "sha256"))
14934         key_id[0] = HMAC_SHA_256_128;
14935       else
14936         {
14937           clib_warning ("invalid key_id: '%s'", s);
14938           key_id[0] = HMAC_NO_KEY;
14939         }
14940     }
14941   else
14942     return 0;
14943
14944   vec_free (s);
14945   return 1;
14946 }
14947
14948 static int
14949 api_one_add_del_local_eid (vat_main_t * vam)
14950 {
14951   unformat_input_t *input = vam->input;
14952   vl_api_one_add_del_local_eid_t *mp;
14953   u8 is_add = 1;
14954   u8 eid_set = 0;
14955   lisp_eid_vat_t _eid, *eid = &_eid;
14956   u8 *locator_set_name = 0;
14957   u8 locator_set_name_set = 0;
14958   u32 vni = 0;
14959   u16 key_id = 0;
14960   u8 *key = 0;
14961   int ret;
14962
14963   /* Parse args required to build the message */
14964   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14965     {
14966       if (unformat (input, "del"))
14967         {
14968           is_add = 0;
14969         }
14970       else if (unformat (input, "vni %d", &vni))
14971         {
14972           ;
14973         }
14974       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14975         {
14976           eid_set = 1;
14977         }
14978       else if (unformat (input, "locator-set %s", &locator_set_name))
14979         {
14980           locator_set_name_set = 1;
14981         }
14982       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14983         ;
14984       else if (unformat (input, "secret-key %_%v%_", &key))
14985         ;
14986       else
14987         break;
14988     }
14989
14990   if (locator_set_name_set == 0)
14991     {
14992       errmsg ("missing locator-set name");
14993       return -99;
14994     }
14995
14996   if (0 == eid_set)
14997     {
14998       errmsg ("EID address not set!");
14999       vec_free (locator_set_name);
15000       return -99;
15001     }
15002
15003   if (key && (0 == key_id))
15004     {
15005       errmsg ("invalid key_id!");
15006       return -99;
15007     }
15008
15009   if (vec_len (key) > 64)
15010     {
15011       errmsg ("key too long");
15012       vec_free (key);
15013       return -99;
15014     }
15015
15016   if (vec_len (locator_set_name) > 64)
15017     {
15018       errmsg ("locator-set name too long");
15019       vec_free (locator_set_name);
15020       return -99;
15021     }
15022   vec_add1 (locator_set_name, 0);
15023
15024   /* Construct the API message */
15025   M (ONE_ADD_DEL_LOCAL_EID, mp);
15026
15027   mp->is_add = is_add;
15028   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15029   mp->eid_type = eid->type;
15030   mp->prefix_len = eid->len;
15031   mp->vni = clib_host_to_net_u32 (vni);
15032   mp->key_id = clib_host_to_net_u16 (key_id);
15033   clib_memcpy (mp->locator_set_name, locator_set_name,
15034                vec_len (locator_set_name));
15035   clib_memcpy (mp->key, key, vec_len (key));
15036
15037   vec_free (locator_set_name);
15038   vec_free (key);
15039
15040   /* send it... */
15041   S (mp);
15042
15043   /* Wait for a reply... */
15044   W (ret);
15045   return ret;
15046 }
15047
15048 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15049
15050 static int
15051 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15052 {
15053   u32 dp_table = 0, vni = 0;;
15054   unformat_input_t *input = vam->input;
15055   vl_api_gpe_add_del_fwd_entry_t *mp;
15056   u8 is_add = 1;
15057   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15058   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15059   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15060   u32 action = ~0, w;
15061   ip4_address_t rmt_rloc4, lcl_rloc4;
15062   ip6_address_t rmt_rloc6, lcl_rloc6;
15063   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15064   int ret;
15065
15066   memset (&rloc, 0, sizeof (rloc));
15067
15068   /* Parse args required to build the message */
15069   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15070     {
15071       if (unformat (input, "del"))
15072         is_add = 0;
15073       else if (unformat (input, "add"))
15074         is_add = 1;
15075       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15076         {
15077           rmt_eid_set = 1;
15078         }
15079       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15080         {
15081           lcl_eid_set = 1;
15082         }
15083       else if (unformat (input, "vrf %d", &dp_table))
15084         ;
15085       else if (unformat (input, "bd %d", &dp_table))
15086         ;
15087       else if (unformat (input, "vni %d", &vni))
15088         ;
15089       else if (unformat (input, "w %d", &w))
15090         {
15091           if (!curr_rloc)
15092             {
15093               errmsg ("No RLOC configured for setting priority/weight!");
15094               return -99;
15095             }
15096           curr_rloc->weight = w;
15097         }
15098       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15099                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15100         {
15101           rloc.is_ip4 = 1;
15102
15103           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15104           rloc.weight = 0;
15105           vec_add1 (lcl_locs, rloc);
15106
15107           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15108           vec_add1 (rmt_locs, rloc);
15109           /* weight saved in rmt loc */
15110           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15111         }
15112       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15113                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15114         {
15115           rloc.is_ip4 = 0;
15116           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15117           rloc.weight = 0;
15118           vec_add1 (lcl_locs, rloc);
15119
15120           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15121           vec_add1 (rmt_locs, rloc);
15122           /* weight saved in rmt loc */
15123           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15124         }
15125       else if (unformat (input, "action %d", &action))
15126         {
15127           ;
15128         }
15129       else
15130         {
15131           clib_warning ("parse error '%U'", format_unformat_error, input);
15132           return -99;
15133         }
15134     }
15135
15136   if (!rmt_eid_set)
15137     {
15138       errmsg ("remote eid addresses not set");
15139       return -99;
15140     }
15141
15142   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15143     {
15144       errmsg ("eid types don't match");
15145       return -99;
15146     }
15147
15148   if (0 == rmt_locs && (u32) ~ 0 == action)
15149     {
15150       errmsg ("action not set for negative mapping");
15151       return -99;
15152     }
15153
15154   /* Construct the API message */
15155   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15156       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15157
15158   mp->is_add = is_add;
15159   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15160   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15161   mp->eid_type = rmt_eid->type;
15162   mp->dp_table = clib_host_to_net_u32 (dp_table);
15163   mp->vni = clib_host_to_net_u32 (vni);
15164   mp->rmt_len = rmt_eid->len;
15165   mp->lcl_len = lcl_eid->len;
15166   mp->action = action;
15167
15168   if (0 != rmt_locs && 0 != lcl_locs)
15169     {
15170       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15171       clib_memcpy (mp->locs, lcl_locs,
15172                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15173
15174       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15175       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15176                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15177     }
15178   vec_free (lcl_locs);
15179   vec_free (rmt_locs);
15180
15181   /* send it... */
15182   S (mp);
15183
15184   /* Wait for a reply... */
15185   W (ret);
15186   return ret;
15187 }
15188
15189 static int
15190 api_one_add_del_map_server (vat_main_t * vam)
15191 {
15192   unformat_input_t *input = vam->input;
15193   vl_api_one_add_del_map_server_t *mp;
15194   u8 is_add = 1;
15195   u8 ipv4_set = 0;
15196   u8 ipv6_set = 0;
15197   ip4_address_t ipv4;
15198   ip6_address_t ipv6;
15199   int ret;
15200
15201   /* Parse args required to build the message */
15202   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15203     {
15204       if (unformat (input, "del"))
15205         {
15206           is_add = 0;
15207         }
15208       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15209         {
15210           ipv4_set = 1;
15211         }
15212       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15213         {
15214           ipv6_set = 1;
15215         }
15216       else
15217         break;
15218     }
15219
15220   if (ipv4_set && ipv6_set)
15221     {
15222       errmsg ("both eid v4 and v6 addresses set");
15223       return -99;
15224     }
15225
15226   if (!ipv4_set && !ipv6_set)
15227     {
15228       errmsg ("eid addresses not set");
15229       return -99;
15230     }
15231
15232   /* Construct the API message */
15233   M (ONE_ADD_DEL_MAP_SERVER, mp);
15234
15235   mp->is_add = is_add;
15236   if (ipv6_set)
15237     {
15238       mp->is_ipv6 = 1;
15239       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15240     }
15241   else
15242     {
15243       mp->is_ipv6 = 0;
15244       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15245     }
15246
15247   /* send it... */
15248   S (mp);
15249
15250   /* Wait for a reply... */
15251   W (ret);
15252   return ret;
15253 }
15254
15255 #define api_lisp_add_del_map_server api_one_add_del_map_server
15256
15257 static int
15258 api_one_add_del_map_resolver (vat_main_t * vam)
15259 {
15260   unformat_input_t *input = vam->input;
15261   vl_api_one_add_del_map_resolver_t *mp;
15262   u8 is_add = 1;
15263   u8 ipv4_set = 0;
15264   u8 ipv6_set = 0;
15265   ip4_address_t ipv4;
15266   ip6_address_t ipv6;
15267   int ret;
15268
15269   /* Parse args required to build the message */
15270   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15271     {
15272       if (unformat (input, "del"))
15273         {
15274           is_add = 0;
15275         }
15276       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15277         {
15278           ipv4_set = 1;
15279         }
15280       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15281         {
15282           ipv6_set = 1;
15283         }
15284       else
15285         break;
15286     }
15287
15288   if (ipv4_set && ipv6_set)
15289     {
15290       errmsg ("both eid v4 and v6 addresses set");
15291       return -99;
15292     }
15293
15294   if (!ipv4_set && !ipv6_set)
15295     {
15296       errmsg ("eid addresses not set");
15297       return -99;
15298     }
15299
15300   /* Construct the API message */
15301   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
15302
15303   mp->is_add = is_add;
15304   if (ipv6_set)
15305     {
15306       mp->is_ipv6 = 1;
15307       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15308     }
15309   else
15310     {
15311       mp->is_ipv6 = 0;
15312       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15313     }
15314
15315   /* send it... */
15316   S (mp);
15317
15318   /* Wait for a reply... */
15319   W (ret);
15320   return ret;
15321 }
15322
15323 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
15324
15325 static int
15326 api_lisp_gpe_enable_disable (vat_main_t * vam)
15327 {
15328   unformat_input_t *input = vam->input;
15329   vl_api_gpe_enable_disable_t *mp;
15330   u8 is_set = 0;
15331   u8 is_en = 1;
15332   int ret;
15333
15334   /* Parse args required to build the message */
15335   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15336     {
15337       if (unformat (input, "enable"))
15338         {
15339           is_set = 1;
15340           is_en = 1;
15341         }
15342       else if (unformat (input, "disable"))
15343         {
15344           is_set = 1;
15345           is_en = 0;
15346         }
15347       else
15348         break;
15349     }
15350
15351   if (is_set == 0)
15352     {
15353       errmsg ("Value not set");
15354       return -99;
15355     }
15356
15357   /* Construct the API message */
15358   M (GPE_ENABLE_DISABLE, mp);
15359
15360   mp->is_en = is_en;
15361
15362   /* send it... */
15363   S (mp);
15364
15365   /* Wait for a reply... */
15366   W (ret);
15367   return ret;
15368 }
15369
15370 static int
15371 api_one_rloc_probe_enable_disable (vat_main_t * vam)
15372 {
15373   unformat_input_t *input = vam->input;
15374   vl_api_one_rloc_probe_enable_disable_t *mp;
15375   u8 is_set = 0;
15376   u8 is_en = 0;
15377   int ret;
15378
15379   /* Parse args required to build the message */
15380   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15381     {
15382       if (unformat (input, "enable"))
15383         {
15384           is_set = 1;
15385           is_en = 1;
15386         }
15387       else if (unformat (input, "disable"))
15388         is_set = 1;
15389       else
15390         break;
15391     }
15392
15393   if (!is_set)
15394     {
15395       errmsg ("Value not set");
15396       return -99;
15397     }
15398
15399   /* Construct the API message */
15400   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
15401
15402   mp->is_enabled = is_en;
15403
15404   /* send it... */
15405   S (mp);
15406
15407   /* Wait for a reply... */
15408   W (ret);
15409   return ret;
15410 }
15411
15412 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
15413
15414 static int
15415 api_one_map_register_enable_disable (vat_main_t * vam)
15416 {
15417   unformat_input_t *input = vam->input;
15418   vl_api_one_map_register_enable_disable_t *mp;
15419   u8 is_set = 0;
15420   u8 is_en = 0;
15421   int ret;
15422
15423   /* Parse args required to build the message */
15424   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15425     {
15426       if (unformat (input, "enable"))
15427         {
15428           is_set = 1;
15429           is_en = 1;
15430         }
15431       else if (unformat (input, "disable"))
15432         is_set = 1;
15433       else
15434         break;
15435     }
15436
15437   if (!is_set)
15438     {
15439       errmsg ("Value not set");
15440       return -99;
15441     }
15442
15443   /* Construct the API message */
15444   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
15445
15446   mp->is_enabled = is_en;
15447
15448   /* send it... */
15449   S (mp);
15450
15451   /* Wait for a reply... */
15452   W (ret);
15453   return ret;
15454 }
15455
15456 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
15457
15458 static int
15459 api_one_enable_disable (vat_main_t * vam)
15460 {
15461   unformat_input_t *input = vam->input;
15462   vl_api_one_enable_disable_t *mp;
15463   u8 is_set = 0;
15464   u8 is_en = 0;
15465   int ret;
15466
15467   /* Parse args required to build the message */
15468   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15469     {
15470       if (unformat (input, "enable"))
15471         {
15472           is_set = 1;
15473           is_en = 1;
15474         }
15475       else if (unformat (input, "disable"))
15476         {
15477           is_set = 1;
15478         }
15479       else
15480         break;
15481     }
15482
15483   if (!is_set)
15484     {
15485       errmsg ("Value not set");
15486       return -99;
15487     }
15488
15489   /* Construct the API message */
15490   M (ONE_ENABLE_DISABLE, mp);
15491
15492   mp->is_en = is_en;
15493
15494   /* send it... */
15495   S (mp);
15496
15497   /* Wait for a reply... */
15498   W (ret);
15499   return ret;
15500 }
15501
15502 #define api_lisp_enable_disable api_one_enable_disable
15503
15504 static int
15505 api_show_one_map_register_state (vat_main_t * vam)
15506 {
15507   vl_api_show_one_map_register_state_t *mp;
15508   int ret;
15509
15510   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15511
15512   /* send */
15513   S (mp);
15514
15515   /* wait for reply */
15516   W (ret);
15517   return ret;
15518 }
15519
15520 #define api_show_lisp_map_register_state api_show_one_map_register_state
15521
15522 static int
15523 api_show_one_rloc_probe_state (vat_main_t * vam)
15524 {
15525   vl_api_show_one_rloc_probe_state_t *mp;
15526   int ret;
15527
15528   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15529
15530   /* send */
15531   S (mp);
15532
15533   /* wait for reply */
15534   W (ret);
15535   return ret;
15536 }
15537
15538 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15539
15540 static int
15541 api_one_add_del_ndp_entry (vat_main_t * vam)
15542 {
15543   vl_api_one_add_del_ndp_entry_t *mp;
15544   unformat_input_t *input = vam->input;
15545   u8 is_add = 1;
15546   u8 mac_set = 0;
15547   u8 bd_set = 0;
15548   u8 ip_set = 0;
15549   u8 mac[6] = { 0, };
15550   u8 ip6[16] = { 0, };
15551   u32 bd = ~0;
15552   int ret;
15553
15554   /* Parse args required to build the message */
15555   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15556     {
15557       if (unformat (input, "del"))
15558         is_add = 0;
15559       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15560         mac_set = 1;
15561       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
15562         ip_set = 1;
15563       else if (unformat (input, "bd %d", &bd))
15564         bd_set = 1;
15565       else
15566         {
15567           errmsg ("parse error '%U'", format_unformat_error, input);
15568           return -99;
15569         }
15570     }
15571
15572   if (!bd_set || !ip_set || (!mac_set && is_add))
15573     {
15574       errmsg ("Missing BD, IP or MAC!");
15575       return -99;
15576     }
15577
15578   M (ONE_ADD_DEL_NDP_ENTRY, mp);
15579   mp->is_add = is_add;
15580   clib_memcpy (mp->mac, mac, 6);
15581   mp->bd = clib_host_to_net_u32 (bd);
15582   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
15583
15584   /* send */
15585   S (mp);
15586
15587   /* wait for reply */
15588   W (ret);
15589   return ret;
15590 }
15591
15592 static int
15593 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15594 {
15595   vl_api_one_add_del_l2_arp_entry_t *mp;
15596   unformat_input_t *input = vam->input;
15597   u8 is_add = 1;
15598   u8 mac_set = 0;
15599   u8 bd_set = 0;
15600   u8 ip_set = 0;
15601   u8 mac[6] = { 0, };
15602   u32 ip4 = 0, bd = ~0;
15603   int ret;
15604
15605   /* Parse args required to build the message */
15606   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15607     {
15608       if (unformat (input, "del"))
15609         is_add = 0;
15610       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15611         mac_set = 1;
15612       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15613         ip_set = 1;
15614       else if (unformat (input, "bd %d", &bd))
15615         bd_set = 1;
15616       else
15617         {
15618           errmsg ("parse error '%U'", format_unformat_error, input);
15619           return -99;
15620         }
15621     }
15622
15623   if (!bd_set || !ip_set || (!mac_set && is_add))
15624     {
15625       errmsg ("Missing BD, IP or MAC!");
15626       return -99;
15627     }
15628
15629   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15630   mp->is_add = is_add;
15631   clib_memcpy (mp->mac, mac, 6);
15632   mp->bd = clib_host_to_net_u32 (bd);
15633   mp->ip4 = ip4;
15634
15635   /* send */
15636   S (mp);
15637
15638   /* wait for reply */
15639   W (ret);
15640   return ret;
15641 }
15642
15643 static int
15644 api_one_ndp_bd_get (vat_main_t * vam)
15645 {
15646   vl_api_one_ndp_bd_get_t *mp;
15647   int ret;
15648
15649   M (ONE_NDP_BD_GET, mp);
15650
15651   /* send */
15652   S (mp);
15653
15654   /* wait for reply */
15655   W (ret);
15656   return ret;
15657 }
15658
15659 static int
15660 api_one_ndp_entries_get (vat_main_t * vam)
15661 {
15662   vl_api_one_ndp_entries_get_t *mp;
15663   unformat_input_t *input = vam->input;
15664   u8 bd_set = 0;
15665   u32 bd = ~0;
15666   int ret;
15667
15668   /* Parse args required to build the message */
15669   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15670     {
15671       if (unformat (input, "bd %d", &bd))
15672         bd_set = 1;
15673       else
15674         {
15675           errmsg ("parse error '%U'", format_unformat_error, input);
15676           return -99;
15677         }
15678     }
15679
15680   if (!bd_set)
15681     {
15682       errmsg ("Expected bridge domain!");
15683       return -99;
15684     }
15685
15686   M (ONE_NDP_ENTRIES_GET, mp);
15687   mp->bd = clib_host_to_net_u32 (bd);
15688
15689   /* send */
15690   S (mp);
15691
15692   /* wait for reply */
15693   W (ret);
15694   return ret;
15695 }
15696
15697 static int
15698 api_one_l2_arp_bd_get (vat_main_t * vam)
15699 {
15700   vl_api_one_l2_arp_bd_get_t *mp;
15701   int ret;
15702
15703   M (ONE_L2_ARP_BD_GET, mp);
15704
15705   /* send */
15706   S (mp);
15707
15708   /* wait for reply */
15709   W (ret);
15710   return ret;
15711 }
15712
15713 static int
15714 api_one_l2_arp_entries_get (vat_main_t * vam)
15715 {
15716   vl_api_one_l2_arp_entries_get_t *mp;
15717   unformat_input_t *input = vam->input;
15718   u8 bd_set = 0;
15719   u32 bd = ~0;
15720   int ret;
15721
15722   /* Parse args required to build the message */
15723   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15724     {
15725       if (unformat (input, "bd %d", &bd))
15726         bd_set = 1;
15727       else
15728         {
15729           errmsg ("parse error '%U'", format_unformat_error, input);
15730           return -99;
15731         }
15732     }
15733
15734   if (!bd_set)
15735     {
15736       errmsg ("Expected bridge domain!");
15737       return -99;
15738     }
15739
15740   M (ONE_L2_ARP_ENTRIES_GET, mp);
15741   mp->bd = clib_host_to_net_u32 (bd);
15742
15743   /* send */
15744   S (mp);
15745
15746   /* wait for reply */
15747   W (ret);
15748   return ret;
15749 }
15750
15751 static int
15752 api_one_stats_enable_disable (vat_main_t * vam)
15753 {
15754   vl_api_one_stats_enable_disable_t *mp;
15755   unformat_input_t *input = vam->input;
15756   u8 is_set = 0;
15757   u8 is_en = 0;
15758   int ret;
15759
15760   /* Parse args required to build the message */
15761   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15762     {
15763       if (unformat (input, "enable"))
15764         {
15765           is_set = 1;
15766           is_en = 1;
15767         }
15768       else if (unformat (input, "disable"))
15769         {
15770           is_set = 1;
15771         }
15772       else
15773         break;
15774     }
15775
15776   if (!is_set)
15777     {
15778       errmsg ("Value not set");
15779       return -99;
15780     }
15781
15782   M (ONE_STATS_ENABLE_DISABLE, mp);
15783   mp->is_en = is_en;
15784
15785   /* send */
15786   S (mp);
15787
15788   /* wait for reply */
15789   W (ret);
15790   return ret;
15791 }
15792
15793 static int
15794 api_show_one_stats_enable_disable (vat_main_t * vam)
15795 {
15796   vl_api_show_one_stats_enable_disable_t *mp;
15797   int ret;
15798
15799   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
15800
15801   /* send */
15802   S (mp);
15803
15804   /* wait for reply */
15805   W (ret);
15806   return ret;
15807 }
15808
15809 static int
15810 api_show_one_map_request_mode (vat_main_t * vam)
15811 {
15812   vl_api_show_one_map_request_mode_t *mp;
15813   int ret;
15814
15815   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
15816
15817   /* send */
15818   S (mp);
15819
15820   /* wait for reply */
15821   W (ret);
15822   return ret;
15823 }
15824
15825 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
15826
15827 static int
15828 api_one_map_request_mode (vat_main_t * vam)
15829 {
15830   unformat_input_t *input = vam->input;
15831   vl_api_one_map_request_mode_t *mp;
15832   u8 mode = 0;
15833   int ret;
15834
15835   /* Parse args required to build the message */
15836   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15837     {
15838       if (unformat (input, "dst-only"))
15839         mode = 0;
15840       else if (unformat (input, "src-dst"))
15841         mode = 1;
15842       else
15843         {
15844           errmsg ("parse error '%U'", format_unformat_error, input);
15845           return -99;
15846         }
15847     }
15848
15849   M (ONE_MAP_REQUEST_MODE, mp);
15850
15851   mp->mode = mode;
15852
15853   /* send */
15854   S (mp);
15855
15856   /* wait for reply */
15857   W (ret);
15858   return ret;
15859 }
15860
15861 #define api_lisp_map_request_mode api_one_map_request_mode
15862
15863 /**
15864  * Enable/disable ONE proxy ITR.
15865  *
15866  * @param vam vpp API test context
15867  * @return return code
15868  */
15869 static int
15870 api_one_pitr_set_locator_set (vat_main_t * vam)
15871 {
15872   u8 ls_name_set = 0;
15873   unformat_input_t *input = vam->input;
15874   vl_api_one_pitr_set_locator_set_t *mp;
15875   u8 is_add = 1;
15876   u8 *ls_name = 0;
15877   int ret;
15878
15879   /* Parse args required to build the message */
15880   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15881     {
15882       if (unformat (input, "del"))
15883         is_add = 0;
15884       else if (unformat (input, "locator-set %s", &ls_name))
15885         ls_name_set = 1;
15886       else
15887         {
15888           errmsg ("parse error '%U'", format_unformat_error, input);
15889           return -99;
15890         }
15891     }
15892
15893   if (!ls_name_set)
15894     {
15895       errmsg ("locator-set name not set!");
15896       return -99;
15897     }
15898
15899   M (ONE_PITR_SET_LOCATOR_SET, mp);
15900
15901   mp->is_add = is_add;
15902   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15903   vec_free (ls_name);
15904
15905   /* send */
15906   S (mp);
15907
15908   /* wait for reply */
15909   W (ret);
15910   return ret;
15911 }
15912
15913 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
15914
15915 static int
15916 api_one_nsh_set_locator_set (vat_main_t * vam)
15917 {
15918   u8 ls_name_set = 0;
15919   unformat_input_t *input = vam->input;
15920   vl_api_one_nsh_set_locator_set_t *mp;
15921   u8 is_add = 1;
15922   u8 *ls_name = 0;
15923   int ret;
15924
15925   /* Parse args required to build the message */
15926   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15927     {
15928       if (unformat (input, "del"))
15929         is_add = 0;
15930       else if (unformat (input, "ls %s", &ls_name))
15931         ls_name_set = 1;
15932       else
15933         {
15934           errmsg ("parse error '%U'", format_unformat_error, input);
15935           return -99;
15936         }
15937     }
15938
15939   if (!ls_name_set && is_add)
15940     {
15941       errmsg ("locator-set name not set!");
15942       return -99;
15943     }
15944
15945   M (ONE_NSH_SET_LOCATOR_SET, mp);
15946
15947   mp->is_add = is_add;
15948   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15949   vec_free (ls_name);
15950
15951   /* send */
15952   S (mp);
15953
15954   /* wait for reply */
15955   W (ret);
15956   return ret;
15957 }
15958
15959 static int
15960 api_show_one_pitr (vat_main_t * vam)
15961 {
15962   vl_api_show_one_pitr_t *mp;
15963   int ret;
15964
15965   if (!vam->json_output)
15966     {
15967       print (vam->ofp, "%=20s", "lisp status:");
15968     }
15969
15970   M (SHOW_ONE_PITR, mp);
15971   /* send it... */
15972   S (mp);
15973
15974   /* Wait for a reply... */
15975   W (ret);
15976   return ret;
15977 }
15978
15979 #define api_show_lisp_pitr api_show_one_pitr
15980
15981 static int
15982 api_one_use_petr (vat_main_t * vam)
15983 {
15984   unformat_input_t *input = vam->input;
15985   vl_api_one_use_petr_t *mp;
15986   u8 is_add = 0;
15987   ip_address_t ip;
15988   int ret;
15989
15990   memset (&ip, 0, sizeof (ip));
15991
15992   /* Parse args required to build the message */
15993   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15994     {
15995       if (unformat (input, "disable"))
15996         is_add = 0;
15997       else
15998         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
15999         {
16000           is_add = 1;
16001           ip_addr_version (&ip) = IP4;
16002         }
16003       else
16004         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16005         {
16006           is_add = 1;
16007           ip_addr_version (&ip) = IP6;
16008         }
16009       else
16010         {
16011           errmsg ("parse error '%U'", format_unformat_error, input);
16012           return -99;
16013         }
16014     }
16015
16016   M (ONE_USE_PETR, mp);
16017
16018   mp->is_add = is_add;
16019   if (is_add)
16020     {
16021       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
16022       if (mp->is_ip4)
16023         clib_memcpy (mp->address, &ip, 4);
16024       else
16025         clib_memcpy (mp->address, &ip, 16);
16026     }
16027
16028   /* send */
16029   S (mp);
16030
16031   /* wait for reply */
16032   W (ret);
16033   return ret;
16034 }
16035
16036 #define api_lisp_use_petr api_one_use_petr
16037
16038 static int
16039 api_show_one_nsh_mapping (vat_main_t * vam)
16040 {
16041   vl_api_show_one_use_petr_t *mp;
16042   int ret;
16043
16044   if (!vam->json_output)
16045     {
16046       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16047     }
16048
16049   M (SHOW_ONE_NSH_MAPPING, mp);
16050   /* send it... */
16051   S (mp);
16052
16053   /* Wait for a reply... */
16054   W (ret);
16055   return ret;
16056 }
16057
16058 static int
16059 api_show_one_use_petr (vat_main_t * vam)
16060 {
16061   vl_api_show_one_use_petr_t *mp;
16062   int ret;
16063
16064   if (!vam->json_output)
16065     {
16066       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16067     }
16068
16069   M (SHOW_ONE_USE_PETR, mp);
16070   /* send it... */
16071   S (mp);
16072
16073   /* Wait for a reply... */
16074   W (ret);
16075   return ret;
16076 }
16077
16078 #define api_show_lisp_use_petr api_show_one_use_petr
16079
16080 /**
16081  * Add/delete mapping between vni and vrf
16082  */
16083 static int
16084 api_one_eid_table_add_del_map (vat_main_t * vam)
16085 {
16086   unformat_input_t *input = vam->input;
16087   vl_api_one_eid_table_add_del_map_t *mp;
16088   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
16089   u32 vni, vrf, bd_index;
16090   int ret;
16091
16092   /* Parse args required to build the message */
16093   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16094     {
16095       if (unformat (input, "del"))
16096         is_add = 0;
16097       else if (unformat (input, "vrf %d", &vrf))
16098         vrf_set = 1;
16099       else if (unformat (input, "bd_index %d", &bd_index))
16100         bd_index_set = 1;
16101       else if (unformat (input, "vni %d", &vni))
16102         vni_set = 1;
16103       else
16104         break;
16105     }
16106
16107   if (!vni_set || (!vrf_set && !bd_index_set))
16108     {
16109       errmsg ("missing arguments!");
16110       return -99;
16111     }
16112
16113   if (vrf_set && bd_index_set)
16114     {
16115       errmsg ("error: both vrf and bd entered!");
16116       return -99;
16117     }
16118
16119   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
16120
16121   mp->is_add = is_add;
16122   mp->vni = htonl (vni);
16123   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
16124   mp->is_l2 = bd_index_set;
16125
16126   /* send */
16127   S (mp);
16128
16129   /* wait for reply */
16130   W (ret);
16131   return ret;
16132 }
16133
16134 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
16135
16136 uword
16137 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
16138 {
16139   u32 *action = va_arg (*args, u32 *);
16140   u8 *s = 0;
16141
16142   if (unformat (input, "%s", &s))
16143     {
16144       if (!strcmp ((char *) s, "no-action"))
16145         action[0] = 0;
16146       else if (!strcmp ((char *) s, "natively-forward"))
16147         action[0] = 1;
16148       else if (!strcmp ((char *) s, "send-map-request"))
16149         action[0] = 2;
16150       else if (!strcmp ((char *) s, "drop"))
16151         action[0] = 3;
16152       else
16153         {
16154           clib_warning ("invalid action: '%s'", s);
16155           action[0] = 3;
16156         }
16157     }
16158   else
16159     return 0;
16160
16161   vec_free (s);
16162   return 1;
16163 }
16164
16165 /**
16166  * Add/del remote mapping to/from ONE control plane
16167  *
16168  * @param vam vpp API test context
16169  * @return return code
16170  */
16171 static int
16172 api_one_add_del_remote_mapping (vat_main_t * vam)
16173 {
16174   unformat_input_t *input = vam->input;
16175   vl_api_one_add_del_remote_mapping_t *mp;
16176   u32 vni = 0;
16177   lisp_eid_vat_t _eid, *eid = &_eid;
16178   lisp_eid_vat_t _seid, *seid = &_seid;
16179   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
16180   u32 action = ~0, p, w, data_len;
16181   ip4_address_t rloc4;
16182   ip6_address_t rloc6;
16183   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
16184   int ret;
16185
16186   memset (&rloc, 0, sizeof (rloc));
16187
16188   /* Parse args required to build the message */
16189   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16190     {
16191       if (unformat (input, "del-all"))
16192         {
16193           del_all = 1;
16194         }
16195       else if (unformat (input, "del"))
16196         {
16197           is_add = 0;
16198         }
16199       else if (unformat (input, "add"))
16200         {
16201           is_add = 1;
16202         }
16203       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16204         {
16205           eid_set = 1;
16206         }
16207       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
16208         {
16209           seid_set = 1;
16210         }
16211       else if (unformat (input, "vni %d", &vni))
16212         {
16213           ;
16214         }
16215       else if (unformat (input, "p %d w %d", &p, &w))
16216         {
16217           if (!curr_rloc)
16218             {
16219               errmsg ("No RLOC configured for setting priority/weight!");
16220               return -99;
16221             }
16222           curr_rloc->priority = p;
16223           curr_rloc->weight = w;
16224         }
16225       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
16226         {
16227           rloc.is_ip4 = 1;
16228           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
16229           vec_add1 (rlocs, rloc);
16230           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16231         }
16232       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
16233         {
16234           rloc.is_ip4 = 0;
16235           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
16236           vec_add1 (rlocs, rloc);
16237           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16238         }
16239       else if (unformat (input, "action %U",
16240                          unformat_negative_mapping_action, &action))
16241         {
16242           ;
16243         }
16244       else
16245         {
16246           clib_warning ("parse error '%U'", format_unformat_error, input);
16247           return -99;
16248         }
16249     }
16250
16251   if (0 == eid_set)
16252     {
16253       errmsg ("missing params!");
16254       return -99;
16255     }
16256
16257   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
16258     {
16259       errmsg ("no action set for negative map-reply!");
16260       return -99;
16261     }
16262
16263   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
16264
16265   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
16266   mp->is_add = is_add;
16267   mp->vni = htonl (vni);
16268   mp->action = (u8) action;
16269   mp->is_src_dst = seid_set;
16270   mp->eid_len = eid->len;
16271   mp->seid_len = seid->len;
16272   mp->del_all = del_all;
16273   mp->eid_type = eid->type;
16274   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16275   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
16276
16277   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
16278   clib_memcpy (mp->rlocs, rlocs, data_len);
16279   vec_free (rlocs);
16280
16281   /* send it... */
16282   S (mp);
16283
16284   /* Wait for a reply... */
16285   W (ret);
16286   return ret;
16287 }
16288
16289 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
16290
16291 /**
16292  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
16293  * forwarding entries in data-plane accordingly.
16294  *
16295  * @param vam vpp API test context
16296  * @return return code
16297  */
16298 static int
16299 api_one_add_del_adjacency (vat_main_t * vam)
16300 {
16301   unformat_input_t *input = vam->input;
16302   vl_api_one_add_del_adjacency_t *mp;
16303   u32 vni = 0;
16304   ip4_address_t leid4, reid4;
16305   ip6_address_t leid6, reid6;
16306   u8 reid_mac[6] = { 0 };
16307   u8 leid_mac[6] = { 0 };
16308   u8 reid_type, leid_type;
16309   u32 leid_len = 0, reid_len = 0, len;
16310   u8 is_add = 1;
16311   int ret;
16312
16313   leid_type = reid_type = (u8) ~ 0;
16314
16315   /* Parse args required to build the message */
16316   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16317     {
16318       if (unformat (input, "del"))
16319         {
16320           is_add = 0;
16321         }
16322       else if (unformat (input, "add"))
16323         {
16324           is_add = 1;
16325         }
16326       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
16327                          &reid4, &len))
16328         {
16329           reid_type = 0;        /* ipv4 */
16330           reid_len = len;
16331         }
16332       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
16333                          &reid6, &len))
16334         {
16335           reid_type = 1;        /* ipv6 */
16336           reid_len = len;
16337         }
16338       else if (unformat (input, "reid %U", unformat_ethernet_address,
16339                          reid_mac))
16340         {
16341           reid_type = 2;        /* mac */
16342         }
16343       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
16344                          &leid4, &len))
16345         {
16346           leid_type = 0;        /* ipv4 */
16347           leid_len = len;
16348         }
16349       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
16350                          &leid6, &len))
16351         {
16352           leid_type = 1;        /* ipv6 */
16353           leid_len = len;
16354         }
16355       else if (unformat (input, "leid %U", unformat_ethernet_address,
16356                          leid_mac))
16357         {
16358           leid_type = 2;        /* mac */
16359         }
16360       else if (unformat (input, "vni %d", &vni))
16361         {
16362           ;
16363         }
16364       else
16365         {
16366           errmsg ("parse error '%U'", format_unformat_error, input);
16367           return -99;
16368         }
16369     }
16370
16371   if ((u8) ~ 0 == reid_type)
16372     {
16373       errmsg ("missing params!");
16374       return -99;
16375     }
16376
16377   if (leid_type != reid_type)
16378     {
16379       errmsg ("remote and local EIDs are of different types!");
16380       return -99;
16381     }
16382
16383   M (ONE_ADD_DEL_ADJACENCY, mp);
16384   mp->is_add = is_add;
16385   mp->vni = htonl (vni);
16386   mp->leid_len = leid_len;
16387   mp->reid_len = reid_len;
16388   mp->eid_type = reid_type;
16389
16390   switch (mp->eid_type)
16391     {
16392     case 0:
16393       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
16394       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
16395       break;
16396     case 1:
16397       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
16398       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
16399       break;
16400     case 2:
16401       clib_memcpy (mp->leid, leid_mac, 6);
16402       clib_memcpy (mp->reid, reid_mac, 6);
16403       break;
16404     default:
16405       errmsg ("unknown EID type %d!", mp->eid_type);
16406       return 0;
16407     }
16408
16409   /* send it... */
16410   S (mp);
16411
16412   /* Wait for a reply... */
16413   W (ret);
16414   return ret;
16415 }
16416
16417 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16418
16419 uword
16420 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16421 {
16422   u32 *mode = va_arg (*args, u32 *);
16423
16424   if (unformat (input, "lisp"))
16425     *mode = 0;
16426   else if (unformat (input, "vxlan"))
16427     *mode = 1;
16428   else
16429     return 0;
16430
16431   return 1;
16432 }
16433
16434 static int
16435 api_gpe_get_encap_mode (vat_main_t * vam)
16436 {
16437   vl_api_gpe_get_encap_mode_t *mp;
16438   int ret;
16439
16440   /* Construct the API message */
16441   M (GPE_GET_ENCAP_MODE, mp);
16442
16443   /* send it... */
16444   S (mp);
16445
16446   /* Wait for a reply... */
16447   W (ret);
16448   return ret;
16449 }
16450
16451 static int
16452 api_gpe_set_encap_mode (vat_main_t * vam)
16453 {
16454   unformat_input_t *input = vam->input;
16455   vl_api_gpe_set_encap_mode_t *mp;
16456   int ret;
16457   u32 mode = 0;
16458
16459   /* Parse args required to build the message */
16460   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16461     {
16462       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16463         ;
16464       else
16465         break;
16466     }
16467
16468   /* Construct the API message */
16469   M (GPE_SET_ENCAP_MODE, mp);
16470
16471   mp->mode = mode;
16472
16473   /* send it... */
16474   S (mp);
16475
16476   /* Wait for a reply... */
16477   W (ret);
16478   return ret;
16479 }
16480
16481 static int
16482 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16483 {
16484   unformat_input_t *input = vam->input;
16485   vl_api_gpe_add_del_iface_t *mp;
16486   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16487   u32 dp_table = 0, vni = 0;
16488   int ret;
16489
16490   /* Parse args required to build the message */
16491   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16492     {
16493       if (unformat (input, "up"))
16494         {
16495           action_set = 1;
16496           is_add = 1;
16497         }
16498       else if (unformat (input, "down"))
16499         {
16500           action_set = 1;
16501           is_add = 0;
16502         }
16503       else if (unformat (input, "table_id %d", &dp_table))
16504         {
16505           dp_table_set = 1;
16506         }
16507       else if (unformat (input, "bd_id %d", &dp_table))
16508         {
16509           dp_table_set = 1;
16510           is_l2 = 1;
16511         }
16512       else if (unformat (input, "vni %d", &vni))
16513         {
16514           vni_set = 1;
16515         }
16516       else
16517         break;
16518     }
16519
16520   if (action_set == 0)
16521     {
16522       errmsg ("Action not set");
16523       return -99;
16524     }
16525   if (dp_table_set == 0 || vni_set == 0)
16526     {
16527       errmsg ("vni and dp_table must be set");
16528       return -99;
16529     }
16530
16531   /* Construct the API message */
16532   M (GPE_ADD_DEL_IFACE, mp);
16533
16534   mp->is_add = is_add;
16535   mp->dp_table = clib_host_to_net_u32 (dp_table);
16536   mp->is_l2 = is_l2;
16537   mp->vni = clib_host_to_net_u32 (vni);
16538
16539   /* send it... */
16540   S (mp);
16541
16542   /* Wait for a reply... */
16543   W (ret);
16544   return ret;
16545 }
16546
16547 static int
16548 api_one_map_register_fallback_threshold (vat_main_t * vam)
16549 {
16550   unformat_input_t *input = vam->input;
16551   vl_api_one_map_register_fallback_threshold_t *mp;
16552   u32 value = 0;
16553   u8 is_set = 0;
16554   int ret;
16555
16556   /* Parse args required to build the message */
16557   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16558     {
16559       if (unformat (input, "%u", &value))
16560         is_set = 1;
16561       else
16562         {
16563           clib_warning ("parse error '%U'", format_unformat_error, input);
16564           return -99;
16565         }
16566     }
16567
16568   if (!is_set)
16569     {
16570       errmsg ("fallback threshold value is missing!");
16571       return -99;
16572     }
16573
16574   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16575   mp->value = clib_host_to_net_u32 (value);
16576
16577   /* send it... */
16578   S (mp);
16579
16580   /* Wait for a reply... */
16581   W (ret);
16582   return ret;
16583 }
16584
16585 static int
16586 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16587 {
16588   vl_api_show_one_map_register_fallback_threshold_t *mp;
16589   int ret;
16590
16591   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16592
16593   /* send it... */
16594   S (mp);
16595
16596   /* Wait for a reply... */
16597   W (ret);
16598   return ret;
16599 }
16600
16601 static int
16602 api_one_map_register_set_ttl (vat_main_t * vam)
16603 {
16604   unformat_input_t *input = vam->input;
16605   vl_api_one_map_register_set_ttl_t *mp;
16606   u32 ttl = 0;
16607   u8 is_set = 0;
16608   int ret;
16609
16610   /* Parse args required to build the message */
16611   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16612     {
16613       if (unformat (input, "%u", &ttl))
16614         is_set = 1;
16615       else
16616         {
16617           clib_warning ("parse error '%U'", format_unformat_error, input);
16618           return -99;
16619         }
16620     }
16621
16622   if (!is_set)
16623     {
16624       errmsg ("TTL value missing!");
16625       return -99;
16626     }
16627
16628   M (ONE_MAP_REGISTER_SET_TTL, mp);
16629   mp->ttl = clib_host_to_net_u32 (ttl);
16630
16631   /* send it... */
16632   S (mp);
16633
16634   /* Wait for a reply... */
16635   W (ret);
16636   return ret;
16637 }
16638
16639 static int
16640 api_show_one_map_register_ttl (vat_main_t * vam)
16641 {
16642   vl_api_show_one_map_register_ttl_t *mp;
16643   int ret;
16644
16645   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
16646
16647   /* send it... */
16648   S (mp);
16649
16650   /* Wait for a reply... */
16651   W (ret);
16652   return ret;
16653 }
16654
16655 /**
16656  * Add/del map request itr rlocs from ONE control plane and updates
16657  *
16658  * @param vam vpp API test context
16659  * @return return code
16660  */
16661 static int
16662 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
16663 {
16664   unformat_input_t *input = vam->input;
16665   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
16666   u8 *locator_set_name = 0;
16667   u8 locator_set_name_set = 0;
16668   u8 is_add = 1;
16669   int ret;
16670
16671   /* Parse args required to build the message */
16672   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16673     {
16674       if (unformat (input, "del"))
16675         {
16676           is_add = 0;
16677         }
16678       else if (unformat (input, "%_%v%_", &locator_set_name))
16679         {
16680           locator_set_name_set = 1;
16681         }
16682       else
16683         {
16684           clib_warning ("parse error '%U'", format_unformat_error, input);
16685           return -99;
16686         }
16687     }
16688
16689   if (is_add && !locator_set_name_set)
16690     {
16691       errmsg ("itr-rloc is not set!");
16692       return -99;
16693     }
16694
16695   if (is_add && vec_len (locator_set_name) > 64)
16696     {
16697       errmsg ("itr-rloc locator-set name too long");
16698       vec_free (locator_set_name);
16699       return -99;
16700     }
16701
16702   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
16703   mp->is_add = is_add;
16704   if (is_add)
16705     {
16706       clib_memcpy (mp->locator_set_name, locator_set_name,
16707                    vec_len (locator_set_name));
16708     }
16709   else
16710     {
16711       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
16712     }
16713   vec_free (locator_set_name);
16714
16715   /* send it... */
16716   S (mp);
16717
16718   /* Wait for a reply... */
16719   W (ret);
16720   return ret;
16721 }
16722
16723 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
16724
16725 static int
16726 api_one_locator_dump (vat_main_t * vam)
16727 {
16728   unformat_input_t *input = vam->input;
16729   vl_api_one_locator_dump_t *mp;
16730   vl_api_control_ping_t *mp_ping;
16731   u8 is_index_set = 0, is_name_set = 0;
16732   u8 *ls_name = 0;
16733   u32 ls_index = ~0;
16734   int ret;
16735
16736   /* Parse args required to build the message */
16737   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16738     {
16739       if (unformat (input, "ls_name %_%v%_", &ls_name))
16740         {
16741           is_name_set = 1;
16742         }
16743       else if (unformat (input, "ls_index %d", &ls_index))
16744         {
16745           is_index_set = 1;
16746         }
16747       else
16748         {
16749           errmsg ("parse error '%U'", format_unformat_error, input);
16750           return -99;
16751         }
16752     }
16753
16754   if (!is_index_set && !is_name_set)
16755     {
16756       errmsg ("error: expected one of index or name!");
16757       return -99;
16758     }
16759
16760   if (is_index_set && is_name_set)
16761     {
16762       errmsg ("error: only one param expected!");
16763       return -99;
16764     }
16765
16766   if (vec_len (ls_name) > 62)
16767     {
16768       errmsg ("error: locator set name too long!");
16769       return -99;
16770     }
16771
16772   if (!vam->json_output)
16773     {
16774       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
16775     }
16776
16777   M (ONE_LOCATOR_DUMP, mp);
16778   mp->is_index_set = is_index_set;
16779
16780   if (is_index_set)
16781     mp->ls_index = clib_host_to_net_u32 (ls_index);
16782   else
16783     {
16784       vec_add1 (ls_name, 0);
16785       strncpy ((char *) mp->ls_name, (char *) ls_name,
16786                sizeof (mp->ls_name) - 1);
16787     }
16788
16789   /* send it... */
16790   S (mp);
16791
16792   /* Use a control ping for synchronization */
16793   M (CONTROL_PING, mp_ping);
16794   S (mp_ping);
16795
16796   /* Wait for a reply... */
16797   W (ret);
16798   return ret;
16799 }
16800
16801 #define api_lisp_locator_dump api_one_locator_dump
16802
16803 static int
16804 api_one_locator_set_dump (vat_main_t * vam)
16805 {
16806   vl_api_one_locator_set_dump_t *mp;
16807   vl_api_control_ping_t *mp_ping;
16808   unformat_input_t *input = vam->input;
16809   u8 filter = 0;
16810   int ret;
16811
16812   /* Parse args required to build the message */
16813   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16814     {
16815       if (unformat (input, "local"))
16816         {
16817           filter = 1;
16818         }
16819       else if (unformat (input, "remote"))
16820         {
16821           filter = 2;
16822         }
16823       else
16824         {
16825           errmsg ("parse error '%U'", format_unformat_error, input);
16826           return -99;
16827         }
16828     }
16829
16830   if (!vam->json_output)
16831     {
16832       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
16833     }
16834
16835   M (ONE_LOCATOR_SET_DUMP, mp);
16836
16837   mp->filter = filter;
16838
16839   /* send it... */
16840   S (mp);
16841
16842   /* Use a control ping for synchronization */
16843   M (CONTROL_PING, mp_ping);
16844   S (mp_ping);
16845
16846   /* Wait for a reply... */
16847   W (ret);
16848   return ret;
16849 }
16850
16851 #define api_lisp_locator_set_dump api_one_locator_set_dump
16852
16853 static int
16854 api_one_eid_table_map_dump (vat_main_t * vam)
16855 {
16856   u8 is_l2 = 0;
16857   u8 mode_set = 0;
16858   unformat_input_t *input = vam->input;
16859   vl_api_one_eid_table_map_dump_t *mp;
16860   vl_api_control_ping_t *mp_ping;
16861   int ret;
16862
16863   /* Parse args required to build the message */
16864   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16865     {
16866       if (unformat (input, "l2"))
16867         {
16868           is_l2 = 1;
16869           mode_set = 1;
16870         }
16871       else if (unformat (input, "l3"))
16872         {
16873           is_l2 = 0;
16874           mode_set = 1;
16875         }
16876       else
16877         {
16878           errmsg ("parse error '%U'", format_unformat_error, input);
16879           return -99;
16880         }
16881     }
16882
16883   if (!mode_set)
16884     {
16885       errmsg ("expected one of 'l2' or 'l3' parameter!");
16886       return -99;
16887     }
16888
16889   if (!vam->json_output)
16890     {
16891       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
16892     }
16893
16894   M (ONE_EID_TABLE_MAP_DUMP, mp);
16895   mp->is_l2 = is_l2;
16896
16897   /* send it... */
16898   S (mp);
16899
16900   /* Use a control ping for synchronization */
16901   M (CONTROL_PING, mp_ping);
16902   S (mp_ping);
16903
16904   /* Wait for a reply... */
16905   W (ret);
16906   return ret;
16907 }
16908
16909 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
16910
16911 static int
16912 api_one_eid_table_vni_dump (vat_main_t * vam)
16913 {
16914   vl_api_one_eid_table_vni_dump_t *mp;
16915   vl_api_control_ping_t *mp_ping;
16916   int ret;
16917
16918   if (!vam->json_output)
16919     {
16920       print (vam->ofp, "VNI");
16921     }
16922
16923   M (ONE_EID_TABLE_VNI_DUMP, mp);
16924
16925   /* send it... */
16926   S (mp);
16927
16928   /* Use a control ping for synchronization */
16929   M (CONTROL_PING, mp_ping);
16930   S (mp_ping);
16931
16932   /* Wait for a reply... */
16933   W (ret);
16934   return ret;
16935 }
16936
16937 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
16938
16939 static int
16940 api_one_eid_table_dump (vat_main_t * vam)
16941 {
16942   unformat_input_t *i = vam->input;
16943   vl_api_one_eid_table_dump_t *mp;
16944   vl_api_control_ping_t *mp_ping;
16945   struct in_addr ip4;
16946   struct in6_addr ip6;
16947   u8 mac[6];
16948   u8 eid_type = ~0, eid_set = 0;
16949   u32 prefix_length = ~0, t, vni = 0;
16950   u8 filter = 0;
16951   int ret;
16952   lisp_nsh_api_t nsh;
16953
16954   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16955     {
16956       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
16957         {
16958           eid_set = 1;
16959           eid_type = 0;
16960           prefix_length = t;
16961         }
16962       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
16963         {
16964           eid_set = 1;
16965           eid_type = 1;
16966           prefix_length = t;
16967         }
16968       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
16969         {
16970           eid_set = 1;
16971           eid_type = 2;
16972         }
16973       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
16974         {
16975           eid_set = 1;
16976           eid_type = 3;
16977         }
16978       else if (unformat (i, "vni %d", &t))
16979         {
16980           vni = t;
16981         }
16982       else if (unformat (i, "local"))
16983         {
16984           filter = 1;
16985         }
16986       else if (unformat (i, "remote"))
16987         {
16988           filter = 2;
16989         }
16990       else
16991         {
16992           errmsg ("parse error '%U'", format_unformat_error, i);
16993           return -99;
16994         }
16995     }
16996
16997   if (!vam->json_output)
16998     {
16999       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17000              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17001     }
17002
17003   M (ONE_EID_TABLE_DUMP, mp);
17004
17005   mp->filter = filter;
17006   if (eid_set)
17007     {
17008       mp->eid_set = 1;
17009       mp->vni = htonl (vni);
17010       mp->eid_type = eid_type;
17011       switch (eid_type)
17012         {
17013         case 0:
17014           mp->prefix_length = prefix_length;
17015           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17016           break;
17017         case 1:
17018           mp->prefix_length = prefix_length;
17019           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
17020           break;
17021         case 2:
17022           clib_memcpy (mp->eid, mac, sizeof (mac));
17023           break;
17024         case 3:
17025           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
17026           break;
17027         default:
17028           errmsg ("unknown EID type %d!", eid_type);
17029           return -99;
17030         }
17031     }
17032
17033   /* send it... */
17034   S (mp);
17035
17036   /* Use a control ping for synchronization */
17037   M (CONTROL_PING, mp_ping);
17038   S (mp_ping);
17039
17040   /* Wait for a reply... */
17041   W (ret);
17042   return ret;
17043 }
17044
17045 #define api_lisp_eid_table_dump api_one_eid_table_dump
17046
17047 static int
17048 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
17049 {
17050   unformat_input_t *i = vam->input;
17051   vl_api_gpe_fwd_entries_get_t *mp;
17052   u8 vni_set = 0;
17053   u32 vni = ~0;
17054   int ret;
17055
17056   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17057     {
17058       if (unformat (i, "vni %d", &vni))
17059         {
17060           vni_set = 1;
17061         }
17062       else
17063         {
17064           errmsg ("parse error '%U'", format_unformat_error, i);
17065           return -99;
17066         }
17067     }
17068
17069   if (!vni_set)
17070     {
17071       errmsg ("vni not set!");
17072       return -99;
17073     }
17074
17075   if (!vam->json_output)
17076     {
17077       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
17078              "leid", "reid");
17079     }
17080
17081   M (GPE_FWD_ENTRIES_GET, mp);
17082   mp->vni = clib_host_to_net_u32 (vni);
17083
17084   /* send it... */
17085   S (mp);
17086
17087   /* Wait for a reply... */
17088   W (ret);
17089   return ret;
17090 }
17091
17092 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
17093 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
17094 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
17095 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
17096 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
17097 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
17098 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
17099 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
17100
17101 static int
17102 api_one_adjacencies_get (vat_main_t * vam)
17103 {
17104   unformat_input_t *i = vam->input;
17105   vl_api_one_adjacencies_get_t *mp;
17106   u8 vni_set = 0;
17107   u32 vni = ~0;
17108   int ret;
17109
17110   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17111     {
17112       if (unformat (i, "vni %d", &vni))
17113         {
17114           vni_set = 1;
17115         }
17116       else
17117         {
17118           errmsg ("parse error '%U'", format_unformat_error, i);
17119           return -99;
17120         }
17121     }
17122
17123   if (!vni_set)
17124     {
17125       errmsg ("vni not set!");
17126       return -99;
17127     }
17128
17129   if (!vam->json_output)
17130     {
17131       print (vam->ofp, "%s %40s", "leid", "reid");
17132     }
17133
17134   M (ONE_ADJACENCIES_GET, mp);
17135   mp->vni = clib_host_to_net_u32 (vni);
17136
17137   /* send it... */
17138   S (mp);
17139
17140   /* Wait for a reply... */
17141   W (ret);
17142   return ret;
17143 }
17144
17145 #define api_lisp_adjacencies_get api_one_adjacencies_get
17146
17147 static int
17148 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
17149 {
17150   unformat_input_t *i = vam->input;
17151   vl_api_gpe_native_fwd_rpaths_get_t *mp;
17152   int ret;
17153   u8 ip_family_set = 0, is_ip4 = 1;
17154
17155   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17156     {
17157       if (unformat (i, "ip4"))
17158         {
17159           ip_family_set = 1;
17160           is_ip4 = 1;
17161         }
17162       else if (unformat (i, "ip6"))
17163         {
17164           ip_family_set = 1;
17165           is_ip4 = 0;
17166         }
17167       else
17168         {
17169           errmsg ("parse error '%U'", format_unformat_error, i);
17170           return -99;
17171         }
17172     }
17173
17174   if (!ip_family_set)
17175     {
17176       errmsg ("ip family not set!");
17177       return -99;
17178     }
17179
17180   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
17181   mp->is_ip4 = is_ip4;
17182
17183   /* send it... */
17184   S (mp);
17185
17186   /* Wait for a reply... */
17187   W (ret);
17188   return ret;
17189 }
17190
17191 static int
17192 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
17193 {
17194   vl_api_gpe_fwd_entry_vnis_get_t *mp;
17195   int ret;
17196
17197   if (!vam->json_output)
17198     {
17199       print (vam->ofp, "VNIs");
17200     }
17201
17202   M (GPE_FWD_ENTRY_VNIS_GET, mp);
17203
17204   /* send it... */
17205   S (mp);
17206
17207   /* Wait for a reply... */
17208   W (ret);
17209   return ret;
17210 }
17211
17212 static int
17213 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
17214 {
17215   unformat_input_t *i = vam->input;
17216   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
17217   int ret = 0;
17218   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
17219   struct in_addr ip4;
17220   struct in6_addr ip6;
17221   u32 table_id = 0, nh_sw_if_index = ~0;
17222
17223   memset (&ip4, 0, sizeof (ip4));
17224   memset (&ip6, 0, sizeof (ip6));
17225
17226   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17227     {
17228       if (unformat (i, "del"))
17229         is_add = 0;
17230       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
17231                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17232         {
17233           ip_set = 1;
17234           is_ip4 = 1;
17235         }
17236       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
17237                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17238         {
17239           ip_set = 1;
17240           is_ip4 = 0;
17241         }
17242       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
17243         {
17244           ip_set = 1;
17245           is_ip4 = 1;
17246           nh_sw_if_index = ~0;
17247         }
17248       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
17249         {
17250           ip_set = 1;
17251           is_ip4 = 0;
17252           nh_sw_if_index = ~0;
17253         }
17254       else if (unformat (i, "table %d", &table_id))
17255         ;
17256       else
17257         {
17258           errmsg ("parse error '%U'", format_unformat_error, i);
17259           return -99;
17260         }
17261     }
17262
17263   if (!ip_set)
17264     {
17265       errmsg ("nh addr not set!");
17266       return -99;
17267     }
17268
17269   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
17270   mp->is_add = is_add;
17271   mp->table_id = clib_host_to_net_u32 (table_id);
17272   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
17273   mp->is_ip4 = is_ip4;
17274   if (is_ip4)
17275     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
17276   else
17277     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
17278
17279   /* send it... */
17280   S (mp);
17281
17282   /* Wait for a reply... */
17283   W (ret);
17284   return ret;
17285 }
17286
17287 static int
17288 api_one_map_server_dump (vat_main_t * vam)
17289 {
17290   vl_api_one_map_server_dump_t *mp;
17291   vl_api_control_ping_t *mp_ping;
17292   int ret;
17293
17294   if (!vam->json_output)
17295     {
17296       print (vam->ofp, "%=20s", "Map server");
17297     }
17298
17299   M (ONE_MAP_SERVER_DUMP, mp);
17300   /* send it... */
17301   S (mp);
17302
17303   /* Use a control ping for synchronization */
17304   M (CONTROL_PING, mp_ping);
17305   S (mp_ping);
17306
17307   /* Wait for a reply... */
17308   W (ret);
17309   return ret;
17310 }
17311
17312 #define api_lisp_map_server_dump api_one_map_server_dump
17313
17314 static int
17315 api_one_map_resolver_dump (vat_main_t * vam)
17316 {
17317   vl_api_one_map_resolver_dump_t *mp;
17318   vl_api_control_ping_t *mp_ping;
17319   int ret;
17320
17321   if (!vam->json_output)
17322     {
17323       print (vam->ofp, "%=20s", "Map resolver");
17324     }
17325
17326   M (ONE_MAP_RESOLVER_DUMP, mp);
17327   /* send it... */
17328   S (mp);
17329
17330   /* Use a control ping for synchronization */
17331   M (CONTROL_PING, mp_ping);
17332   S (mp_ping);
17333
17334   /* Wait for a reply... */
17335   W (ret);
17336   return ret;
17337 }
17338
17339 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
17340
17341 static int
17342 api_one_stats_flush (vat_main_t * vam)
17343 {
17344   vl_api_one_stats_flush_t *mp;
17345   int ret = 0;
17346
17347   M (ONE_STATS_FLUSH, mp);
17348   S (mp);
17349   W (ret);
17350   return ret;
17351 }
17352
17353 static int
17354 api_one_stats_dump (vat_main_t * vam)
17355 {
17356   vl_api_one_stats_dump_t *mp;
17357   vl_api_control_ping_t *mp_ping;
17358   int ret;
17359
17360   M (ONE_STATS_DUMP, mp);
17361   /* send it... */
17362   S (mp);
17363
17364   /* Use a control ping for synchronization */
17365   M (CONTROL_PING, mp_ping);
17366   S (mp_ping);
17367
17368   /* Wait for a reply... */
17369   W (ret);
17370   return ret;
17371 }
17372
17373 static int
17374 api_show_one_status (vat_main_t * vam)
17375 {
17376   vl_api_show_one_status_t *mp;
17377   int ret;
17378
17379   if (!vam->json_output)
17380     {
17381       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17382     }
17383
17384   M (SHOW_ONE_STATUS, mp);
17385   /* send it... */
17386   S (mp);
17387   /* Wait for a reply... */
17388   W (ret);
17389   return ret;
17390 }
17391
17392 #define api_show_lisp_status api_show_one_status
17393
17394 static int
17395 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17396 {
17397   vl_api_gpe_fwd_entry_path_dump_t *mp;
17398   vl_api_control_ping_t *mp_ping;
17399   unformat_input_t *i = vam->input;
17400   u32 fwd_entry_index = ~0;
17401   int ret;
17402
17403   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17404     {
17405       if (unformat (i, "index %d", &fwd_entry_index))
17406         ;
17407       else
17408         break;
17409     }
17410
17411   if (~0 == fwd_entry_index)
17412     {
17413       errmsg ("no index specified!");
17414       return -99;
17415     }
17416
17417   if (!vam->json_output)
17418     {
17419       print (vam->ofp, "first line");
17420     }
17421
17422   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17423
17424   /* send it... */
17425   S (mp);
17426   /* Use a control ping for synchronization */
17427   M (CONTROL_PING, mp_ping);
17428   S (mp_ping);
17429
17430   /* Wait for a reply... */
17431   W (ret);
17432   return ret;
17433 }
17434
17435 static int
17436 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17437 {
17438   vl_api_one_get_map_request_itr_rlocs_t *mp;
17439   int ret;
17440
17441   if (!vam->json_output)
17442     {
17443       print (vam->ofp, "%=20s", "itr-rlocs:");
17444     }
17445
17446   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17447   /* send it... */
17448   S (mp);
17449   /* Wait for a reply... */
17450   W (ret);
17451   return ret;
17452 }
17453
17454 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17455
17456 static int
17457 api_af_packet_create (vat_main_t * vam)
17458 {
17459   unformat_input_t *i = vam->input;
17460   vl_api_af_packet_create_t *mp;
17461   u8 *host_if_name = 0;
17462   u8 hw_addr[6];
17463   u8 random_hw_addr = 1;
17464   int ret;
17465
17466   memset (hw_addr, 0, sizeof (hw_addr));
17467
17468   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17469     {
17470       if (unformat (i, "name %s", &host_if_name))
17471         vec_add1 (host_if_name, 0);
17472       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17473         random_hw_addr = 0;
17474       else
17475         break;
17476     }
17477
17478   if (!vec_len (host_if_name))
17479     {
17480       errmsg ("host-interface name must be specified");
17481       return -99;
17482     }
17483
17484   if (vec_len (host_if_name) > 64)
17485     {
17486       errmsg ("host-interface name too long");
17487       return -99;
17488     }
17489
17490   M (AF_PACKET_CREATE, mp);
17491
17492   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17493   clib_memcpy (mp->hw_addr, hw_addr, 6);
17494   mp->use_random_hw_addr = random_hw_addr;
17495   vec_free (host_if_name);
17496
17497   S (mp);
17498
17499   /* *INDENT-OFF* */
17500   W2 (ret,
17501       ({
17502         if (ret == 0)
17503           fprintf (vam->ofp ? vam->ofp : stderr,
17504                    " new sw_if_index = %d\n", vam->sw_if_index);
17505       }));
17506   /* *INDENT-ON* */
17507   return ret;
17508 }
17509
17510 static int
17511 api_af_packet_delete (vat_main_t * vam)
17512 {
17513   unformat_input_t *i = vam->input;
17514   vl_api_af_packet_delete_t *mp;
17515   u8 *host_if_name = 0;
17516   int ret;
17517
17518   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17519     {
17520       if (unformat (i, "name %s", &host_if_name))
17521         vec_add1 (host_if_name, 0);
17522       else
17523         break;
17524     }
17525
17526   if (!vec_len (host_if_name))
17527     {
17528       errmsg ("host-interface name must be specified");
17529       return -99;
17530     }
17531
17532   if (vec_len (host_if_name) > 64)
17533     {
17534       errmsg ("host-interface name too long");
17535       return -99;
17536     }
17537
17538   M (AF_PACKET_DELETE, mp);
17539
17540   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17541   vec_free (host_if_name);
17542
17543   S (mp);
17544   W (ret);
17545   return ret;
17546 }
17547
17548 static int
17549 api_policer_add_del (vat_main_t * vam)
17550 {
17551   unformat_input_t *i = vam->input;
17552   vl_api_policer_add_del_t *mp;
17553   u8 is_add = 1;
17554   u8 *name = 0;
17555   u32 cir = 0;
17556   u32 eir = 0;
17557   u64 cb = 0;
17558   u64 eb = 0;
17559   u8 rate_type = 0;
17560   u8 round_type = 0;
17561   u8 type = 0;
17562   u8 color_aware = 0;
17563   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17564   int ret;
17565
17566   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17567   conform_action.dscp = 0;
17568   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17569   exceed_action.dscp = 0;
17570   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17571   violate_action.dscp = 0;
17572
17573   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17574     {
17575       if (unformat (i, "del"))
17576         is_add = 0;
17577       else if (unformat (i, "name %s", &name))
17578         vec_add1 (name, 0);
17579       else if (unformat (i, "cir %u", &cir))
17580         ;
17581       else if (unformat (i, "eir %u", &eir))
17582         ;
17583       else if (unformat (i, "cb %u", &cb))
17584         ;
17585       else if (unformat (i, "eb %u", &eb))
17586         ;
17587       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17588                          &rate_type))
17589         ;
17590       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17591                          &round_type))
17592         ;
17593       else if (unformat (i, "type %U", unformat_policer_type, &type))
17594         ;
17595       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17596                          &conform_action))
17597         ;
17598       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17599                          &exceed_action))
17600         ;
17601       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17602                          &violate_action))
17603         ;
17604       else if (unformat (i, "color-aware"))
17605         color_aware = 1;
17606       else
17607         break;
17608     }
17609
17610   if (!vec_len (name))
17611     {
17612       errmsg ("policer name must be specified");
17613       return -99;
17614     }
17615
17616   if (vec_len (name) > 64)
17617     {
17618       errmsg ("policer name too long");
17619       return -99;
17620     }
17621
17622   M (POLICER_ADD_DEL, mp);
17623
17624   clib_memcpy (mp->name, name, vec_len (name));
17625   vec_free (name);
17626   mp->is_add = is_add;
17627   mp->cir = cir;
17628   mp->eir = eir;
17629   mp->cb = cb;
17630   mp->eb = eb;
17631   mp->rate_type = rate_type;
17632   mp->round_type = round_type;
17633   mp->type = type;
17634   mp->conform_action_type = conform_action.action_type;
17635   mp->conform_dscp = conform_action.dscp;
17636   mp->exceed_action_type = exceed_action.action_type;
17637   mp->exceed_dscp = exceed_action.dscp;
17638   mp->violate_action_type = violate_action.action_type;
17639   mp->violate_dscp = violate_action.dscp;
17640   mp->color_aware = color_aware;
17641
17642   S (mp);
17643   W (ret);
17644   return ret;
17645 }
17646
17647 static int
17648 api_policer_dump (vat_main_t * vam)
17649 {
17650   unformat_input_t *i = vam->input;
17651   vl_api_policer_dump_t *mp;
17652   vl_api_control_ping_t *mp_ping;
17653   u8 *match_name = 0;
17654   u8 match_name_valid = 0;
17655   int ret;
17656
17657   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17658     {
17659       if (unformat (i, "name %s", &match_name))
17660         {
17661           vec_add1 (match_name, 0);
17662           match_name_valid = 1;
17663         }
17664       else
17665         break;
17666     }
17667
17668   M (POLICER_DUMP, mp);
17669   mp->match_name_valid = match_name_valid;
17670   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
17671   vec_free (match_name);
17672   /* send it... */
17673   S (mp);
17674
17675   /* Use a control ping for synchronization */
17676   M (CONTROL_PING, mp_ping);
17677   S (mp_ping);
17678
17679   /* Wait for a reply... */
17680   W (ret);
17681   return ret;
17682 }
17683
17684 static int
17685 api_policer_classify_set_interface (vat_main_t * vam)
17686 {
17687   unformat_input_t *i = vam->input;
17688   vl_api_policer_classify_set_interface_t *mp;
17689   u32 sw_if_index;
17690   int sw_if_index_set;
17691   u32 ip4_table_index = ~0;
17692   u32 ip6_table_index = ~0;
17693   u32 l2_table_index = ~0;
17694   u8 is_add = 1;
17695   int ret;
17696
17697   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17698     {
17699       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17700         sw_if_index_set = 1;
17701       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17702         sw_if_index_set = 1;
17703       else if (unformat (i, "del"))
17704         is_add = 0;
17705       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17706         ;
17707       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17708         ;
17709       else if (unformat (i, "l2-table %d", &l2_table_index))
17710         ;
17711       else
17712         {
17713           clib_warning ("parse error '%U'", format_unformat_error, i);
17714           return -99;
17715         }
17716     }
17717
17718   if (sw_if_index_set == 0)
17719     {
17720       errmsg ("missing interface name or sw_if_index");
17721       return -99;
17722     }
17723
17724   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
17725
17726   mp->sw_if_index = ntohl (sw_if_index);
17727   mp->ip4_table_index = ntohl (ip4_table_index);
17728   mp->ip6_table_index = ntohl (ip6_table_index);
17729   mp->l2_table_index = ntohl (l2_table_index);
17730   mp->is_add = is_add;
17731
17732   S (mp);
17733   W (ret);
17734   return ret;
17735 }
17736
17737 static int
17738 api_policer_classify_dump (vat_main_t * vam)
17739 {
17740   unformat_input_t *i = vam->input;
17741   vl_api_policer_classify_dump_t *mp;
17742   vl_api_control_ping_t *mp_ping;
17743   u8 type = POLICER_CLASSIFY_N_TABLES;
17744   int ret;
17745
17746   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
17747     ;
17748   else
17749     {
17750       errmsg ("classify table type must be specified");
17751       return -99;
17752     }
17753
17754   if (!vam->json_output)
17755     {
17756       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17757     }
17758
17759   M (POLICER_CLASSIFY_DUMP, mp);
17760   mp->type = type;
17761   /* send it... */
17762   S (mp);
17763
17764   /* Use a control ping for synchronization */
17765   M (CONTROL_PING, mp_ping);
17766   S (mp_ping);
17767
17768   /* Wait for a reply... */
17769   W (ret);
17770   return ret;
17771 }
17772
17773 static int
17774 api_netmap_create (vat_main_t * vam)
17775 {
17776   unformat_input_t *i = vam->input;
17777   vl_api_netmap_create_t *mp;
17778   u8 *if_name = 0;
17779   u8 hw_addr[6];
17780   u8 random_hw_addr = 1;
17781   u8 is_pipe = 0;
17782   u8 is_master = 0;
17783   int ret;
17784
17785   memset (hw_addr, 0, sizeof (hw_addr));
17786
17787   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17788     {
17789       if (unformat (i, "name %s", &if_name))
17790         vec_add1 (if_name, 0);
17791       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17792         random_hw_addr = 0;
17793       else if (unformat (i, "pipe"))
17794         is_pipe = 1;
17795       else if (unformat (i, "master"))
17796         is_master = 1;
17797       else if (unformat (i, "slave"))
17798         is_master = 0;
17799       else
17800         break;
17801     }
17802
17803   if (!vec_len (if_name))
17804     {
17805       errmsg ("interface name must be specified");
17806       return -99;
17807     }
17808
17809   if (vec_len (if_name) > 64)
17810     {
17811       errmsg ("interface name too long");
17812       return -99;
17813     }
17814
17815   M (NETMAP_CREATE, mp);
17816
17817   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
17818   clib_memcpy (mp->hw_addr, hw_addr, 6);
17819   mp->use_random_hw_addr = random_hw_addr;
17820   mp->is_pipe = is_pipe;
17821   mp->is_master = is_master;
17822   vec_free (if_name);
17823
17824   S (mp);
17825   W (ret);
17826   return ret;
17827 }
17828
17829 static int
17830 api_netmap_delete (vat_main_t * vam)
17831 {
17832   unformat_input_t *i = vam->input;
17833   vl_api_netmap_delete_t *mp;
17834   u8 *if_name = 0;
17835   int ret;
17836
17837   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17838     {
17839       if (unformat (i, "name %s", &if_name))
17840         vec_add1 (if_name, 0);
17841       else
17842         break;
17843     }
17844
17845   if (!vec_len (if_name))
17846     {
17847       errmsg ("interface name must be specified");
17848       return -99;
17849     }
17850
17851   if (vec_len (if_name) > 64)
17852     {
17853       errmsg ("interface name too long");
17854       return -99;
17855     }
17856
17857   M (NETMAP_DELETE, mp);
17858
17859   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
17860   vec_free (if_name);
17861
17862   S (mp);
17863   W (ret);
17864   return ret;
17865 }
17866
17867 static void
17868 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
17869 {
17870   if (fp->afi == IP46_TYPE_IP6)
17871     print (vam->ofp,
17872            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17873            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17874            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17875            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17876            format_ip6_address, fp->next_hop);
17877   else if (fp->afi == IP46_TYPE_IP4)
17878     print (vam->ofp,
17879            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17880            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17881            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17882            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17883            format_ip4_address, fp->next_hop);
17884 }
17885
17886 static void
17887 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
17888                                  vl_api_fib_path2_t * fp)
17889 {
17890   struct in_addr ip4;
17891   struct in6_addr ip6;
17892
17893   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17894   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17895   vat_json_object_add_uint (node, "is_local", fp->is_local);
17896   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
17897   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
17898   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
17899   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
17900   if (fp->afi == IP46_TYPE_IP4)
17901     {
17902       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
17903       vat_json_object_add_ip4 (node, "next_hop", ip4);
17904     }
17905   else if (fp->afi == IP46_TYPE_IP6)
17906     {
17907       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
17908       vat_json_object_add_ip6 (node, "next_hop", ip6);
17909     }
17910 }
17911
17912 static void
17913 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
17914 {
17915   vat_main_t *vam = &vat_main;
17916   int count = ntohl (mp->mt_count);
17917   vl_api_fib_path2_t *fp;
17918   i32 i;
17919
17920   print (vam->ofp, "[%d]: sw_if_index %d via:",
17921          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
17922   fp = mp->mt_paths;
17923   for (i = 0; i < count; i++)
17924     {
17925       vl_api_mpls_fib_path_print (vam, fp);
17926       fp++;
17927     }
17928
17929   print (vam->ofp, "");
17930 }
17931
17932 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
17933 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
17934
17935 static void
17936 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
17937 {
17938   vat_main_t *vam = &vat_main;
17939   vat_json_node_t *node = NULL;
17940   int count = ntohl (mp->mt_count);
17941   vl_api_fib_path2_t *fp;
17942   i32 i;
17943
17944   if (VAT_JSON_ARRAY != vam->json_tree.type)
17945     {
17946       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17947       vat_json_init_array (&vam->json_tree);
17948     }
17949   node = vat_json_array_add (&vam->json_tree);
17950
17951   vat_json_init_object (node);
17952   vat_json_object_add_uint (node, "tunnel_index",
17953                             ntohl (mp->mt_tunnel_index));
17954   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
17955
17956   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
17957
17958   fp = mp->mt_paths;
17959   for (i = 0; i < count; i++)
17960     {
17961       vl_api_mpls_fib_path_json_print (node, fp);
17962       fp++;
17963     }
17964 }
17965
17966 static int
17967 api_mpls_tunnel_dump (vat_main_t * vam)
17968 {
17969   vl_api_mpls_tunnel_dump_t *mp;
17970   vl_api_control_ping_t *mp_ping;
17971   i32 index = -1;
17972   int ret;
17973
17974   /* Parse args required to build the message */
17975   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
17976     {
17977       if (!unformat (vam->input, "tunnel_index %d", &index))
17978         {
17979           index = -1;
17980           break;
17981         }
17982     }
17983
17984   print (vam->ofp, "  tunnel_index %d", index);
17985
17986   M (MPLS_TUNNEL_DUMP, mp);
17987   mp->tunnel_index = htonl (index);
17988   S (mp);
17989
17990   /* Use a control ping for synchronization */
17991   M (CONTROL_PING, mp_ping);
17992   S (mp_ping);
17993
17994   W (ret);
17995   return ret;
17996 }
17997
17998 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
17999 #define vl_api_mpls_fib_details_t_print vl_noop_handler
18000
18001
18002 static void
18003 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
18004 {
18005   vat_main_t *vam = &vat_main;
18006   int count = ntohl (mp->count);
18007   vl_api_fib_path2_t *fp;
18008   int i;
18009
18010   print (vam->ofp,
18011          "table-id %d, label %u, ess_bit %u",
18012          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
18013   fp = mp->path;
18014   for (i = 0; i < count; i++)
18015     {
18016       vl_api_mpls_fib_path_print (vam, fp);
18017       fp++;
18018     }
18019 }
18020
18021 static void vl_api_mpls_fib_details_t_handler_json
18022   (vl_api_mpls_fib_details_t * mp)
18023 {
18024   vat_main_t *vam = &vat_main;
18025   int count = ntohl (mp->count);
18026   vat_json_node_t *node = NULL;
18027   vl_api_fib_path2_t *fp;
18028   int i;
18029
18030   if (VAT_JSON_ARRAY != vam->json_tree.type)
18031     {
18032       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18033       vat_json_init_array (&vam->json_tree);
18034     }
18035   node = vat_json_array_add (&vam->json_tree);
18036
18037   vat_json_init_object (node);
18038   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
18039   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
18040   vat_json_object_add_uint (node, "label", ntohl (mp->label));
18041   vat_json_object_add_uint (node, "path_count", count);
18042   fp = mp->path;
18043   for (i = 0; i < count; i++)
18044     {
18045       vl_api_mpls_fib_path_json_print (node, fp);
18046       fp++;
18047     }
18048 }
18049
18050 static int
18051 api_mpls_fib_dump (vat_main_t * vam)
18052 {
18053   vl_api_mpls_fib_dump_t *mp;
18054   vl_api_control_ping_t *mp_ping;
18055   int ret;
18056
18057   M (MPLS_FIB_DUMP, mp);
18058   S (mp);
18059
18060   /* Use a control ping for synchronization */
18061   M (CONTROL_PING, mp_ping);
18062   S (mp_ping);
18063
18064   W (ret);
18065   return ret;
18066 }
18067
18068 #define vl_api_ip_fib_details_t_endian vl_noop_handler
18069 #define vl_api_ip_fib_details_t_print vl_noop_handler
18070
18071 static void
18072 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
18073 {
18074   vat_main_t *vam = &vat_main;
18075   int count = ntohl (mp->count);
18076   vl_api_fib_path_t *fp;
18077   int i;
18078
18079   print (vam->ofp,
18080          "table-id %d, prefix %U/%d",
18081          ntohl (mp->table_id), format_ip4_address, mp->address,
18082          mp->address_length);
18083   fp = mp->path;
18084   for (i = 0; i < count; i++)
18085     {
18086       if (fp->afi == IP46_TYPE_IP6)
18087         print (vam->ofp,
18088                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18089                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18090                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18091                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18092                format_ip6_address, fp->next_hop);
18093       else if (fp->afi == IP46_TYPE_IP4)
18094         print (vam->ofp,
18095                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18096                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18097                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18098                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18099                format_ip4_address, fp->next_hop);
18100       fp++;
18101     }
18102 }
18103
18104 static void vl_api_ip_fib_details_t_handler_json
18105   (vl_api_ip_fib_details_t * mp)
18106 {
18107   vat_main_t *vam = &vat_main;
18108   int count = ntohl (mp->count);
18109   vat_json_node_t *node = NULL;
18110   struct in_addr ip4;
18111   struct in6_addr ip6;
18112   vl_api_fib_path_t *fp;
18113   int i;
18114
18115   if (VAT_JSON_ARRAY != vam->json_tree.type)
18116     {
18117       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18118       vat_json_init_array (&vam->json_tree);
18119     }
18120   node = vat_json_array_add (&vam->json_tree);
18121
18122   vat_json_init_object (node);
18123   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
18124   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
18125   vat_json_object_add_ip4 (node, "prefix", ip4);
18126   vat_json_object_add_uint (node, "mask_length", mp->address_length);
18127   vat_json_object_add_uint (node, "path_count", count);
18128   fp = mp->path;
18129   for (i = 0; i < count; i++)
18130     {
18131       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18132       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18133       vat_json_object_add_uint (node, "is_local", fp->is_local);
18134       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
18135       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
18136       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
18137       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
18138       if (fp->afi == IP46_TYPE_IP4)
18139         {
18140           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
18141           vat_json_object_add_ip4 (node, "next_hop", ip4);
18142         }
18143       else if (fp->afi == IP46_TYPE_IP6)
18144         {
18145           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
18146           vat_json_object_add_ip6 (node, "next_hop", ip6);
18147         }
18148     }
18149 }
18150
18151 static int
18152 api_ip_fib_dump (vat_main_t * vam)
18153 {
18154   vl_api_ip_fib_dump_t *mp;
18155   vl_api_control_ping_t *mp_ping;
18156   int ret;
18157
18158   M (IP_FIB_DUMP, mp);
18159   S (mp);
18160
18161   /* Use a control ping for synchronization */
18162   M (CONTROL_PING, mp_ping);
18163   S (mp_ping);
18164
18165   W (ret);
18166   return ret;
18167 }
18168
18169 static int
18170 api_ip_mfib_dump (vat_main_t * vam)
18171 {
18172   vl_api_ip_mfib_dump_t *mp;
18173   vl_api_control_ping_t *mp_ping;
18174   int ret;
18175
18176   M (IP_MFIB_DUMP, mp);
18177   S (mp);
18178
18179   /* Use a control ping for synchronization */
18180   M (CONTROL_PING, mp_ping);
18181   S (mp_ping);
18182
18183   W (ret);
18184   return ret;
18185 }
18186
18187 static void vl_api_ip_neighbor_details_t_handler
18188   (vl_api_ip_neighbor_details_t * mp)
18189 {
18190   vat_main_t *vam = &vat_main;
18191
18192   print (vam->ofp, "%c %U %U",
18193          (mp->is_static) ? 'S' : 'D',
18194          format_ethernet_address, &mp->mac_address,
18195          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
18196          &mp->ip_address);
18197 }
18198
18199 static void vl_api_ip_neighbor_details_t_handler_json
18200   (vl_api_ip_neighbor_details_t * mp)
18201 {
18202
18203   vat_main_t *vam = &vat_main;
18204   vat_json_node_t *node;
18205   struct in_addr ip4;
18206   struct in6_addr ip6;
18207
18208   if (VAT_JSON_ARRAY != vam->json_tree.type)
18209     {
18210       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18211       vat_json_init_array (&vam->json_tree);
18212     }
18213   node = vat_json_array_add (&vam->json_tree);
18214
18215   vat_json_init_object (node);
18216   vat_json_object_add_string_copy (node, "flag",
18217                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
18218                                    "dynamic");
18219
18220   vat_json_object_add_string_copy (node, "link_layer",
18221                                    format (0, "%U", format_ethernet_address,
18222                                            &mp->mac_address));
18223
18224   if (mp->is_ipv6)
18225     {
18226       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
18227       vat_json_object_add_ip6 (node, "ip_address", ip6);
18228     }
18229   else
18230     {
18231       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
18232       vat_json_object_add_ip4 (node, "ip_address", ip4);
18233     }
18234 }
18235
18236 static int
18237 api_ip_neighbor_dump (vat_main_t * vam)
18238 {
18239   unformat_input_t *i = vam->input;
18240   vl_api_ip_neighbor_dump_t *mp;
18241   vl_api_control_ping_t *mp_ping;
18242   u8 is_ipv6 = 0;
18243   u32 sw_if_index = ~0;
18244   int ret;
18245
18246   /* Parse args required to build the message */
18247   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18248     {
18249       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18250         ;
18251       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18252         ;
18253       else if (unformat (i, "ip6"))
18254         is_ipv6 = 1;
18255       else
18256         break;
18257     }
18258
18259   if (sw_if_index == ~0)
18260     {
18261       errmsg ("missing interface name or sw_if_index");
18262       return -99;
18263     }
18264
18265   M (IP_NEIGHBOR_DUMP, mp);
18266   mp->is_ipv6 = (u8) is_ipv6;
18267   mp->sw_if_index = ntohl (sw_if_index);
18268   S (mp);
18269
18270   /* Use a control ping for synchronization */
18271   M (CONTROL_PING, mp_ping);
18272   S (mp_ping);
18273
18274   W (ret);
18275   return ret;
18276 }
18277
18278 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
18279 #define vl_api_ip6_fib_details_t_print vl_noop_handler
18280
18281 static void
18282 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
18283 {
18284   vat_main_t *vam = &vat_main;
18285   int count = ntohl (mp->count);
18286   vl_api_fib_path_t *fp;
18287   int i;
18288
18289   print (vam->ofp,
18290          "table-id %d, prefix %U/%d",
18291          ntohl (mp->table_id), format_ip6_address, mp->address,
18292          mp->address_length);
18293   fp = mp->path;
18294   for (i = 0; i < count; i++)
18295     {
18296       if (fp->afi == IP46_TYPE_IP6)
18297         print (vam->ofp,
18298                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18299                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18300                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18301                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18302                format_ip6_address, fp->next_hop);
18303       else if (fp->afi == IP46_TYPE_IP4)
18304         print (vam->ofp,
18305                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18306                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18307                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18308                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18309                format_ip4_address, fp->next_hop);
18310       fp++;
18311     }
18312 }
18313
18314 static void vl_api_ip6_fib_details_t_handler_json
18315   (vl_api_ip6_fib_details_t * mp)
18316 {
18317   vat_main_t *vam = &vat_main;
18318   int count = ntohl (mp->count);
18319   vat_json_node_t *node = NULL;
18320   struct in_addr ip4;
18321   struct in6_addr ip6;
18322   vl_api_fib_path_t *fp;
18323   int i;
18324
18325   if (VAT_JSON_ARRAY != vam->json_tree.type)
18326     {
18327       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18328       vat_json_init_array (&vam->json_tree);
18329     }
18330   node = vat_json_array_add (&vam->json_tree);
18331
18332   vat_json_init_object (node);
18333   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
18334   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
18335   vat_json_object_add_ip6 (node, "prefix", ip6);
18336   vat_json_object_add_uint (node, "mask_length", mp->address_length);
18337   vat_json_object_add_uint (node, "path_count", count);
18338   fp = mp->path;
18339   for (i = 0; i < count; i++)
18340     {
18341       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18342       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18343       vat_json_object_add_uint (node, "is_local", fp->is_local);
18344       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
18345       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
18346       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
18347       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
18348       if (fp->afi == IP46_TYPE_IP4)
18349         {
18350           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
18351           vat_json_object_add_ip4 (node, "next_hop", ip4);
18352         }
18353       else if (fp->afi == IP46_TYPE_IP6)
18354         {
18355           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
18356           vat_json_object_add_ip6 (node, "next_hop", ip6);
18357         }
18358     }
18359 }
18360
18361 static int
18362 api_ip6_fib_dump (vat_main_t * vam)
18363 {
18364   vl_api_ip6_fib_dump_t *mp;
18365   vl_api_control_ping_t *mp_ping;
18366   int ret;
18367
18368   M (IP6_FIB_DUMP, mp);
18369   S (mp);
18370
18371   /* Use a control ping for synchronization */
18372   M (CONTROL_PING, mp_ping);
18373   S (mp_ping);
18374
18375   W (ret);
18376   return ret;
18377 }
18378
18379 static int
18380 api_ip6_mfib_dump (vat_main_t * vam)
18381 {
18382   vl_api_ip6_mfib_dump_t *mp;
18383   vl_api_control_ping_t *mp_ping;
18384   int ret;
18385
18386   M (IP6_MFIB_DUMP, mp);
18387   S (mp);
18388
18389   /* Use a control ping for synchronization */
18390   M (CONTROL_PING, mp_ping);
18391   S (mp_ping);
18392
18393   W (ret);
18394   return ret;
18395 }
18396
18397 int
18398 api_classify_table_ids (vat_main_t * vam)
18399 {
18400   vl_api_classify_table_ids_t *mp;
18401   int ret;
18402
18403   /* Construct the API message */
18404   M (CLASSIFY_TABLE_IDS, mp);
18405   mp->context = 0;
18406
18407   S (mp);
18408   W (ret);
18409   return ret;
18410 }
18411
18412 int
18413 api_classify_table_by_interface (vat_main_t * vam)
18414 {
18415   unformat_input_t *input = vam->input;
18416   vl_api_classify_table_by_interface_t *mp;
18417
18418   u32 sw_if_index = ~0;
18419   int ret;
18420   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18421     {
18422       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18423         ;
18424       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18425         ;
18426       else
18427         break;
18428     }
18429   if (sw_if_index == ~0)
18430     {
18431       errmsg ("missing interface name or sw_if_index");
18432       return -99;
18433     }
18434
18435   /* Construct the API message */
18436   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18437   mp->context = 0;
18438   mp->sw_if_index = ntohl (sw_if_index);
18439
18440   S (mp);
18441   W (ret);
18442   return ret;
18443 }
18444
18445 int
18446 api_classify_table_info (vat_main_t * vam)
18447 {
18448   unformat_input_t *input = vam->input;
18449   vl_api_classify_table_info_t *mp;
18450
18451   u32 table_id = ~0;
18452   int ret;
18453   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18454     {
18455       if (unformat (input, "table_id %d", &table_id))
18456         ;
18457       else
18458         break;
18459     }
18460   if (table_id == ~0)
18461     {
18462       errmsg ("missing table id");
18463       return -99;
18464     }
18465
18466   /* Construct the API message */
18467   M (CLASSIFY_TABLE_INFO, mp);
18468   mp->context = 0;
18469   mp->table_id = ntohl (table_id);
18470
18471   S (mp);
18472   W (ret);
18473   return ret;
18474 }
18475
18476 int
18477 api_classify_session_dump (vat_main_t * vam)
18478 {
18479   unformat_input_t *input = vam->input;
18480   vl_api_classify_session_dump_t *mp;
18481   vl_api_control_ping_t *mp_ping;
18482
18483   u32 table_id = ~0;
18484   int ret;
18485   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18486     {
18487       if (unformat (input, "table_id %d", &table_id))
18488         ;
18489       else
18490         break;
18491     }
18492   if (table_id == ~0)
18493     {
18494       errmsg ("missing table id");
18495       return -99;
18496     }
18497
18498   /* Construct the API message */
18499   M (CLASSIFY_SESSION_DUMP, mp);
18500   mp->context = 0;
18501   mp->table_id = ntohl (table_id);
18502   S (mp);
18503
18504   /* Use a control ping for synchronization */
18505   M (CONTROL_PING, mp_ping);
18506   S (mp_ping);
18507
18508   W (ret);
18509   return ret;
18510 }
18511
18512 static void
18513 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
18514 {
18515   vat_main_t *vam = &vat_main;
18516
18517   print (vam->ofp, "collector_address %U, collector_port %d, "
18518          "src_address %U, vrf_id %d, path_mtu %u, "
18519          "template_interval %u, udp_checksum %d",
18520          format_ip4_address, mp->collector_address,
18521          ntohs (mp->collector_port),
18522          format_ip4_address, mp->src_address,
18523          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
18524          ntohl (mp->template_interval), mp->udp_checksum);
18525
18526   vam->retval = 0;
18527   vam->result_ready = 1;
18528 }
18529
18530 static void
18531   vl_api_ipfix_exporter_details_t_handler_json
18532   (vl_api_ipfix_exporter_details_t * mp)
18533 {
18534   vat_main_t *vam = &vat_main;
18535   vat_json_node_t node;
18536   struct in_addr collector_address;
18537   struct in_addr src_address;
18538
18539   vat_json_init_object (&node);
18540   clib_memcpy (&collector_address, &mp->collector_address,
18541                sizeof (collector_address));
18542   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
18543   vat_json_object_add_uint (&node, "collector_port",
18544                             ntohs (mp->collector_port));
18545   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
18546   vat_json_object_add_ip4 (&node, "src_address", src_address);
18547   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
18548   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
18549   vat_json_object_add_uint (&node, "template_interval",
18550                             ntohl (mp->template_interval));
18551   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
18552
18553   vat_json_print (vam->ofp, &node);
18554   vat_json_free (&node);
18555   vam->retval = 0;
18556   vam->result_ready = 1;
18557 }
18558
18559 int
18560 api_ipfix_exporter_dump (vat_main_t * vam)
18561 {
18562   vl_api_ipfix_exporter_dump_t *mp;
18563   int ret;
18564
18565   /* Construct the API message */
18566   M (IPFIX_EXPORTER_DUMP, mp);
18567   mp->context = 0;
18568
18569   S (mp);
18570   W (ret);
18571   return ret;
18572 }
18573
18574 static int
18575 api_ipfix_classify_stream_dump (vat_main_t * vam)
18576 {
18577   vl_api_ipfix_classify_stream_dump_t *mp;
18578   int ret;
18579
18580   /* Construct the API message */
18581   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
18582   mp->context = 0;
18583
18584   S (mp);
18585   W (ret);
18586   return ret;
18587   /* NOTREACHED */
18588   return 0;
18589 }
18590
18591 static void
18592   vl_api_ipfix_classify_stream_details_t_handler
18593   (vl_api_ipfix_classify_stream_details_t * mp)
18594 {
18595   vat_main_t *vam = &vat_main;
18596   print (vam->ofp, "domain_id %d, src_port %d",
18597          ntohl (mp->domain_id), ntohs (mp->src_port));
18598   vam->retval = 0;
18599   vam->result_ready = 1;
18600 }
18601
18602 static void
18603   vl_api_ipfix_classify_stream_details_t_handler_json
18604   (vl_api_ipfix_classify_stream_details_t * mp)
18605 {
18606   vat_main_t *vam = &vat_main;
18607   vat_json_node_t node;
18608
18609   vat_json_init_object (&node);
18610   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
18611   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
18612
18613   vat_json_print (vam->ofp, &node);
18614   vat_json_free (&node);
18615   vam->retval = 0;
18616   vam->result_ready = 1;
18617 }
18618
18619 static int
18620 api_ipfix_classify_table_dump (vat_main_t * vam)
18621 {
18622   vl_api_ipfix_classify_table_dump_t *mp;
18623   vl_api_control_ping_t *mp_ping;
18624   int ret;
18625
18626   if (!vam->json_output)
18627     {
18628       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
18629              "transport_protocol");
18630     }
18631
18632   /* Construct the API message */
18633   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
18634
18635   /* send it... */
18636   S (mp);
18637
18638   /* Use a control ping for synchronization */
18639   M (CONTROL_PING, mp_ping);
18640   S (mp_ping);
18641
18642   W (ret);
18643   return ret;
18644 }
18645
18646 static void
18647   vl_api_ipfix_classify_table_details_t_handler
18648   (vl_api_ipfix_classify_table_details_t * mp)
18649 {
18650   vat_main_t *vam = &vat_main;
18651   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
18652          mp->transport_protocol);
18653 }
18654
18655 static void
18656   vl_api_ipfix_classify_table_details_t_handler_json
18657   (vl_api_ipfix_classify_table_details_t * mp)
18658 {
18659   vat_json_node_t *node = NULL;
18660   vat_main_t *vam = &vat_main;
18661
18662   if (VAT_JSON_ARRAY != vam->json_tree.type)
18663     {
18664       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18665       vat_json_init_array (&vam->json_tree);
18666     }
18667
18668   node = vat_json_array_add (&vam->json_tree);
18669   vat_json_init_object (node);
18670
18671   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
18672   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
18673   vat_json_object_add_uint (node, "transport_protocol",
18674                             mp->transport_protocol);
18675 }
18676
18677 static int
18678 api_sw_interface_span_enable_disable (vat_main_t * vam)
18679 {
18680   unformat_input_t *i = vam->input;
18681   vl_api_sw_interface_span_enable_disable_t *mp;
18682   u32 src_sw_if_index = ~0;
18683   u32 dst_sw_if_index = ~0;
18684   u8 state = 3;
18685   int ret;
18686   u8 is_l2 = 0;
18687
18688   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18689     {
18690       if (unformat
18691           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
18692         ;
18693       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
18694         ;
18695       else
18696         if (unformat
18697             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
18698         ;
18699       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
18700         ;
18701       else if (unformat (i, "disable"))
18702         state = 0;
18703       else if (unformat (i, "rx"))
18704         state = 1;
18705       else if (unformat (i, "tx"))
18706         state = 2;
18707       else if (unformat (i, "both"))
18708         state = 3;
18709       else if (unformat (i, "l2"))
18710         is_l2 = 1;
18711       else
18712         break;
18713     }
18714
18715   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
18716
18717   mp->sw_if_index_from = htonl (src_sw_if_index);
18718   mp->sw_if_index_to = htonl (dst_sw_if_index);
18719   mp->state = state;
18720   mp->is_l2 = is_l2;
18721
18722   S (mp);
18723   W (ret);
18724   return ret;
18725 }
18726
18727 static void
18728 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
18729                                             * mp)
18730 {
18731   vat_main_t *vam = &vat_main;
18732   u8 *sw_if_from_name = 0;
18733   u8 *sw_if_to_name = 0;
18734   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18735   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18736   char *states[] = { "none", "rx", "tx", "both" };
18737   hash_pair_t *p;
18738
18739   /* *INDENT-OFF* */
18740   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18741   ({
18742     if ((u32) p->value[0] == sw_if_index_from)
18743       {
18744         sw_if_from_name = (u8 *)(p->key);
18745         if (sw_if_to_name)
18746           break;
18747       }
18748     if ((u32) p->value[0] == sw_if_index_to)
18749       {
18750         sw_if_to_name = (u8 *)(p->key);
18751         if (sw_if_from_name)
18752           break;
18753       }
18754   }));
18755   /* *INDENT-ON* */
18756   print (vam->ofp, "%20s => %20s (%s)",
18757          sw_if_from_name, sw_if_to_name, states[mp->state]);
18758 }
18759
18760 static void
18761   vl_api_sw_interface_span_details_t_handler_json
18762   (vl_api_sw_interface_span_details_t * mp)
18763 {
18764   vat_main_t *vam = &vat_main;
18765   vat_json_node_t *node = NULL;
18766   u8 *sw_if_from_name = 0;
18767   u8 *sw_if_to_name = 0;
18768   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18769   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18770   hash_pair_t *p;
18771
18772   /* *INDENT-OFF* */
18773   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18774   ({
18775     if ((u32) p->value[0] == sw_if_index_from)
18776       {
18777         sw_if_from_name = (u8 *)(p->key);
18778         if (sw_if_to_name)
18779           break;
18780       }
18781     if ((u32) p->value[0] == sw_if_index_to)
18782       {
18783         sw_if_to_name = (u8 *)(p->key);
18784         if (sw_if_from_name)
18785           break;
18786       }
18787   }));
18788   /* *INDENT-ON* */
18789
18790   if (VAT_JSON_ARRAY != vam->json_tree.type)
18791     {
18792       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18793       vat_json_init_array (&vam->json_tree);
18794     }
18795   node = vat_json_array_add (&vam->json_tree);
18796
18797   vat_json_init_object (node);
18798   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
18799   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
18800   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
18801   if (0 != sw_if_to_name)
18802     {
18803       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
18804     }
18805   vat_json_object_add_uint (node, "state", mp->state);
18806 }
18807
18808 static int
18809 api_sw_interface_span_dump (vat_main_t * vam)
18810 {
18811   unformat_input_t *input = vam->input;
18812   vl_api_sw_interface_span_dump_t *mp;
18813   vl_api_control_ping_t *mp_ping;
18814   u8 is_l2 = 0;
18815   int ret;
18816
18817   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18818     {
18819       if (unformat (input, "l2"))
18820         is_l2 = 1;
18821       else
18822         break;
18823     }
18824
18825   M (SW_INTERFACE_SPAN_DUMP, mp);
18826   mp->is_l2 = is_l2;
18827   S (mp);
18828
18829   /* Use a control ping for synchronization */
18830   M (CONTROL_PING, mp_ping);
18831   S (mp_ping);
18832
18833   W (ret);
18834   return ret;
18835 }
18836
18837 int
18838 api_pg_create_interface (vat_main_t * vam)
18839 {
18840   unformat_input_t *input = vam->input;
18841   vl_api_pg_create_interface_t *mp;
18842
18843   u32 if_id = ~0;
18844   int ret;
18845   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18846     {
18847       if (unformat (input, "if_id %d", &if_id))
18848         ;
18849       else
18850         break;
18851     }
18852   if (if_id == ~0)
18853     {
18854       errmsg ("missing pg interface index");
18855       return -99;
18856     }
18857
18858   /* Construct the API message */
18859   M (PG_CREATE_INTERFACE, mp);
18860   mp->context = 0;
18861   mp->interface_id = ntohl (if_id);
18862
18863   S (mp);
18864   W (ret);
18865   return ret;
18866 }
18867
18868 int
18869 api_pg_capture (vat_main_t * vam)
18870 {
18871   unformat_input_t *input = vam->input;
18872   vl_api_pg_capture_t *mp;
18873
18874   u32 if_id = ~0;
18875   u8 enable = 1;
18876   u32 count = 1;
18877   u8 pcap_file_set = 0;
18878   u8 *pcap_file = 0;
18879   int ret;
18880   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18881     {
18882       if (unformat (input, "if_id %d", &if_id))
18883         ;
18884       else if (unformat (input, "pcap %s", &pcap_file))
18885         pcap_file_set = 1;
18886       else if (unformat (input, "count %d", &count))
18887         ;
18888       else if (unformat (input, "disable"))
18889         enable = 0;
18890       else
18891         break;
18892     }
18893   if (if_id == ~0)
18894     {
18895       errmsg ("missing pg interface index");
18896       return -99;
18897     }
18898   if (pcap_file_set > 0)
18899     {
18900       if (vec_len (pcap_file) > 255)
18901         {
18902           errmsg ("pcap file name is too long");
18903           return -99;
18904         }
18905     }
18906
18907   u32 name_len = vec_len (pcap_file);
18908   /* Construct the API message */
18909   M (PG_CAPTURE, mp);
18910   mp->context = 0;
18911   mp->interface_id = ntohl (if_id);
18912   mp->is_enabled = enable;
18913   mp->count = ntohl (count);
18914   mp->pcap_name_length = ntohl (name_len);
18915   if (pcap_file_set != 0)
18916     {
18917       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
18918     }
18919   vec_free (pcap_file);
18920
18921   S (mp);
18922   W (ret);
18923   return ret;
18924 }
18925
18926 int
18927 api_pg_enable_disable (vat_main_t * vam)
18928 {
18929   unformat_input_t *input = vam->input;
18930   vl_api_pg_enable_disable_t *mp;
18931
18932   u8 enable = 1;
18933   u8 stream_name_set = 0;
18934   u8 *stream_name = 0;
18935   int ret;
18936   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18937     {
18938       if (unformat (input, "stream %s", &stream_name))
18939         stream_name_set = 1;
18940       else if (unformat (input, "disable"))
18941         enable = 0;
18942       else
18943         break;
18944     }
18945
18946   if (stream_name_set > 0)
18947     {
18948       if (vec_len (stream_name) > 255)
18949         {
18950           errmsg ("stream name too long");
18951           return -99;
18952         }
18953     }
18954
18955   u32 name_len = vec_len (stream_name);
18956   /* Construct the API message */
18957   M (PG_ENABLE_DISABLE, mp);
18958   mp->context = 0;
18959   mp->is_enabled = enable;
18960   if (stream_name_set != 0)
18961     {
18962       mp->stream_name_length = ntohl (name_len);
18963       clib_memcpy (mp->stream_name, stream_name, name_len);
18964     }
18965   vec_free (stream_name);
18966
18967   S (mp);
18968   W (ret);
18969   return ret;
18970 }
18971
18972 int
18973 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
18974 {
18975   unformat_input_t *input = vam->input;
18976   vl_api_ip_source_and_port_range_check_add_del_t *mp;
18977
18978   u16 *low_ports = 0;
18979   u16 *high_ports = 0;
18980   u16 this_low;
18981   u16 this_hi;
18982   ip4_address_t ip4_addr;
18983   ip6_address_t ip6_addr;
18984   u32 length;
18985   u32 tmp, tmp2;
18986   u8 prefix_set = 0;
18987   u32 vrf_id = ~0;
18988   u8 is_add = 1;
18989   u8 is_ipv6 = 0;
18990   int ret;
18991
18992   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18993     {
18994       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
18995         {
18996           prefix_set = 1;
18997         }
18998       else
18999         if (unformat
19000             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
19001         {
19002           prefix_set = 1;
19003           is_ipv6 = 1;
19004         }
19005       else if (unformat (input, "vrf %d", &vrf_id))
19006         ;
19007       else if (unformat (input, "del"))
19008         is_add = 0;
19009       else if (unformat (input, "port %d", &tmp))
19010         {
19011           if (tmp == 0 || tmp > 65535)
19012             {
19013               errmsg ("port %d out of range", tmp);
19014               return -99;
19015             }
19016           this_low = tmp;
19017           this_hi = this_low + 1;
19018           vec_add1 (low_ports, this_low);
19019           vec_add1 (high_ports, this_hi);
19020         }
19021       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
19022         {
19023           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
19024             {
19025               errmsg ("incorrect range parameters");
19026               return -99;
19027             }
19028           this_low = tmp;
19029           /* Note: in debug CLI +1 is added to high before
19030              passing to real fn that does "the work"
19031              (ip_source_and_port_range_check_add_del).
19032              This fn is a wrapper around the binary API fn a
19033              control plane will call, which expects this increment
19034              to have occurred. Hence letting the binary API control
19035              plane fn do the increment for consistency between VAT
19036              and other control planes.
19037            */
19038           this_hi = tmp2;
19039           vec_add1 (low_ports, this_low);
19040           vec_add1 (high_ports, this_hi);
19041         }
19042       else
19043         break;
19044     }
19045
19046   if (prefix_set == 0)
19047     {
19048       errmsg ("<address>/<mask> not specified");
19049       return -99;
19050     }
19051
19052   if (vrf_id == ~0)
19053     {
19054       errmsg ("VRF ID required, not specified");
19055       return -99;
19056     }
19057
19058   if (vrf_id == 0)
19059     {
19060       errmsg
19061         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19062       return -99;
19063     }
19064
19065   if (vec_len (low_ports) == 0)
19066     {
19067       errmsg ("At least one port or port range required");
19068       return -99;
19069     }
19070
19071   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
19072
19073   mp->is_add = is_add;
19074
19075   if (is_ipv6)
19076     {
19077       mp->is_ipv6 = 1;
19078       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
19079     }
19080   else
19081     {
19082       mp->is_ipv6 = 0;
19083       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
19084     }
19085
19086   mp->mask_length = length;
19087   mp->number_of_ranges = vec_len (low_ports);
19088
19089   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
19090   vec_free (low_ports);
19091
19092   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
19093   vec_free (high_ports);
19094
19095   mp->vrf_id = ntohl (vrf_id);
19096
19097   S (mp);
19098   W (ret);
19099   return ret;
19100 }
19101
19102 int
19103 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
19104 {
19105   unformat_input_t *input = vam->input;
19106   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
19107   u32 sw_if_index = ~0;
19108   int vrf_set = 0;
19109   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
19110   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
19111   u8 is_add = 1;
19112   int ret;
19113
19114   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19115     {
19116       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19117         ;
19118       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19119         ;
19120       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
19121         vrf_set = 1;
19122       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
19123         vrf_set = 1;
19124       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
19125         vrf_set = 1;
19126       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
19127         vrf_set = 1;
19128       else if (unformat (input, "del"))
19129         is_add = 0;
19130       else
19131         break;
19132     }
19133
19134   if (sw_if_index == ~0)
19135     {
19136       errmsg ("Interface required but not specified");
19137       return -99;
19138     }
19139
19140   if (vrf_set == 0)
19141     {
19142       errmsg ("VRF ID required but not specified");
19143       return -99;
19144     }
19145
19146   if (tcp_out_vrf_id == 0
19147       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
19148     {
19149       errmsg
19150         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19151       return -99;
19152     }
19153
19154   /* Construct the API message */
19155   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
19156
19157   mp->sw_if_index = ntohl (sw_if_index);
19158   mp->is_add = is_add;
19159   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
19160   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
19161   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
19162   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
19163
19164   /* send it... */
19165   S (mp);
19166
19167   /* Wait for a reply... */
19168   W (ret);
19169   return ret;
19170 }
19171
19172 static int
19173 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
19174 {
19175   unformat_input_t *i = vam->input;
19176   vl_api_ipsec_gre_add_del_tunnel_t *mp;
19177   u32 local_sa_id = 0;
19178   u32 remote_sa_id = 0;
19179   ip4_address_t src_address;
19180   ip4_address_t dst_address;
19181   u8 is_add = 1;
19182   int ret;
19183
19184   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19185     {
19186       if (unformat (i, "local_sa %d", &local_sa_id))
19187         ;
19188       else if (unformat (i, "remote_sa %d", &remote_sa_id))
19189         ;
19190       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
19191         ;
19192       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
19193         ;
19194       else if (unformat (i, "del"))
19195         is_add = 0;
19196       else
19197         {
19198           clib_warning ("parse error '%U'", format_unformat_error, i);
19199           return -99;
19200         }
19201     }
19202
19203   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
19204
19205   mp->local_sa_id = ntohl (local_sa_id);
19206   mp->remote_sa_id = ntohl (remote_sa_id);
19207   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
19208   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
19209   mp->is_add = is_add;
19210
19211   S (mp);
19212   W (ret);
19213   return ret;
19214 }
19215
19216 static int
19217 api_punt (vat_main_t * vam)
19218 {
19219   unformat_input_t *i = vam->input;
19220   vl_api_punt_t *mp;
19221   u32 ipv = ~0;
19222   u32 protocol = ~0;
19223   u32 port = ~0;
19224   int is_add = 1;
19225   int ret;
19226
19227   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19228     {
19229       if (unformat (i, "ip %d", &ipv))
19230         ;
19231       else if (unformat (i, "protocol %d", &protocol))
19232         ;
19233       else if (unformat (i, "port %d", &port))
19234         ;
19235       else if (unformat (i, "del"))
19236         is_add = 0;
19237       else
19238         {
19239           clib_warning ("parse error '%U'", format_unformat_error, i);
19240           return -99;
19241         }
19242     }
19243
19244   M (PUNT, mp);
19245
19246   mp->is_add = (u8) is_add;
19247   mp->ipv = (u8) ipv;
19248   mp->l4_protocol = (u8) protocol;
19249   mp->l4_port = htons ((u16) port);
19250
19251   S (mp);
19252   W (ret);
19253   return ret;
19254 }
19255
19256 static void vl_api_ipsec_gre_tunnel_details_t_handler
19257   (vl_api_ipsec_gre_tunnel_details_t * mp)
19258 {
19259   vat_main_t *vam = &vat_main;
19260
19261   print (vam->ofp, "%11d%15U%15U%14d%14d",
19262          ntohl (mp->sw_if_index),
19263          format_ip4_address, &mp->src_address,
19264          format_ip4_address, &mp->dst_address,
19265          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
19266 }
19267
19268 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
19269   (vl_api_ipsec_gre_tunnel_details_t * mp)
19270 {
19271   vat_main_t *vam = &vat_main;
19272   vat_json_node_t *node = NULL;
19273   struct in_addr ip4;
19274
19275   if (VAT_JSON_ARRAY != vam->json_tree.type)
19276     {
19277       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19278       vat_json_init_array (&vam->json_tree);
19279     }
19280   node = vat_json_array_add (&vam->json_tree);
19281
19282   vat_json_init_object (node);
19283   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
19284   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
19285   vat_json_object_add_ip4 (node, "src_address", ip4);
19286   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
19287   vat_json_object_add_ip4 (node, "dst_address", ip4);
19288   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
19289   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
19290 }
19291
19292 static int
19293 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
19294 {
19295   unformat_input_t *i = vam->input;
19296   vl_api_ipsec_gre_tunnel_dump_t *mp;
19297   vl_api_control_ping_t *mp_ping;
19298   u32 sw_if_index;
19299   u8 sw_if_index_set = 0;
19300   int ret;
19301
19302   /* Parse args required to build the message */
19303   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19304     {
19305       if (unformat (i, "sw_if_index %d", &sw_if_index))
19306         sw_if_index_set = 1;
19307       else
19308         break;
19309     }
19310
19311   if (sw_if_index_set == 0)
19312     {
19313       sw_if_index = ~0;
19314     }
19315
19316   if (!vam->json_output)
19317     {
19318       print (vam->ofp, "%11s%15s%15s%14s%14s",
19319              "sw_if_index", "src_address", "dst_address",
19320              "local_sa_id", "remote_sa_id");
19321     }
19322
19323   /* Get list of gre-tunnel interfaces */
19324   M (IPSEC_GRE_TUNNEL_DUMP, mp);
19325
19326   mp->sw_if_index = htonl (sw_if_index);
19327
19328   S (mp);
19329
19330   /* Use a control ping for synchronization */
19331   M (CONTROL_PING, mp_ping);
19332   S (mp_ping);
19333
19334   W (ret);
19335   return ret;
19336 }
19337
19338 static int
19339 api_delete_subif (vat_main_t * vam)
19340 {
19341   unformat_input_t *i = vam->input;
19342   vl_api_delete_subif_t *mp;
19343   u32 sw_if_index = ~0;
19344   int ret;
19345
19346   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19347     {
19348       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19349         ;
19350       if (unformat (i, "sw_if_index %d", &sw_if_index))
19351         ;
19352       else
19353         break;
19354     }
19355
19356   if (sw_if_index == ~0)
19357     {
19358       errmsg ("missing sw_if_index");
19359       return -99;
19360     }
19361
19362   /* Construct the API message */
19363   M (DELETE_SUBIF, mp);
19364   mp->sw_if_index = ntohl (sw_if_index);
19365
19366   S (mp);
19367   W (ret);
19368   return ret;
19369 }
19370
19371 #define foreach_pbb_vtr_op      \
19372 _("disable",  L2_VTR_DISABLED)  \
19373 _("pop",  L2_VTR_POP_2)         \
19374 _("push",  L2_VTR_PUSH_2)
19375
19376 static int
19377 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
19378 {
19379   unformat_input_t *i = vam->input;
19380   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
19381   u32 sw_if_index = ~0, vtr_op = ~0;
19382   u16 outer_tag = ~0;
19383   u8 dmac[6], smac[6];
19384   u8 dmac_set = 0, smac_set = 0;
19385   u16 vlanid = 0;
19386   u32 sid = ~0;
19387   u32 tmp;
19388   int ret;
19389
19390   /* Shut up coverity */
19391   memset (dmac, 0, sizeof (dmac));
19392   memset (smac, 0, sizeof (smac));
19393
19394   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19395     {
19396       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19397         ;
19398       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19399         ;
19400       else if (unformat (i, "vtr_op %d", &vtr_op))
19401         ;
19402 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
19403       foreach_pbb_vtr_op
19404 #undef _
19405         else if (unformat (i, "translate_pbb_stag"))
19406         {
19407           if (unformat (i, "%d", &tmp))
19408             {
19409               vtr_op = L2_VTR_TRANSLATE_2_1;
19410               outer_tag = tmp;
19411             }
19412           else
19413             {
19414               errmsg
19415                 ("translate_pbb_stag operation requires outer tag definition");
19416               return -99;
19417             }
19418         }
19419       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
19420         dmac_set++;
19421       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
19422         smac_set++;
19423       else if (unformat (i, "sid %d", &sid))
19424         ;
19425       else if (unformat (i, "vlanid %d", &tmp))
19426         vlanid = tmp;
19427       else
19428         {
19429           clib_warning ("parse error '%U'", format_unformat_error, i);
19430           return -99;
19431         }
19432     }
19433
19434   if ((sw_if_index == ~0) || (vtr_op == ~0))
19435     {
19436       errmsg ("missing sw_if_index or vtr operation");
19437       return -99;
19438     }
19439   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
19440       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
19441     {
19442       errmsg
19443         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
19444       return -99;
19445     }
19446
19447   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
19448   mp->sw_if_index = ntohl (sw_if_index);
19449   mp->vtr_op = ntohl (vtr_op);
19450   mp->outer_tag = ntohs (outer_tag);
19451   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
19452   clib_memcpy (mp->b_smac, smac, sizeof (smac));
19453   mp->b_vlanid = ntohs (vlanid);
19454   mp->i_sid = ntohl (sid);
19455
19456   S (mp);
19457   W (ret);
19458   return ret;
19459 }
19460
19461 static int
19462 api_flow_classify_set_interface (vat_main_t * vam)
19463 {
19464   unformat_input_t *i = vam->input;
19465   vl_api_flow_classify_set_interface_t *mp;
19466   u32 sw_if_index;
19467   int sw_if_index_set;
19468   u32 ip4_table_index = ~0;
19469   u32 ip6_table_index = ~0;
19470   u8 is_add = 1;
19471   int ret;
19472
19473   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19474     {
19475       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19476         sw_if_index_set = 1;
19477       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19478         sw_if_index_set = 1;
19479       else if (unformat (i, "del"))
19480         is_add = 0;
19481       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19482         ;
19483       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19484         ;
19485       else
19486         {
19487           clib_warning ("parse error '%U'", format_unformat_error, i);
19488           return -99;
19489         }
19490     }
19491
19492   if (sw_if_index_set == 0)
19493     {
19494       errmsg ("missing interface name or sw_if_index");
19495       return -99;
19496     }
19497
19498   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
19499
19500   mp->sw_if_index = ntohl (sw_if_index);
19501   mp->ip4_table_index = ntohl (ip4_table_index);
19502   mp->ip6_table_index = ntohl (ip6_table_index);
19503   mp->is_add = is_add;
19504
19505   S (mp);
19506   W (ret);
19507   return ret;
19508 }
19509
19510 static int
19511 api_flow_classify_dump (vat_main_t * vam)
19512 {
19513   unformat_input_t *i = vam->input;
19514   vl_api_flow_classify_dump_t *mp;
19515   vl_api_control_ping_t *mp_ping;
19516   u8 type = FLOW_CLASSIFY_N_TABLES;
19517   int ret;
19518
19519   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19520     ;
19521   else
19522     {
19523       errmsg ("classify table type must be specified");
19524       return -99;
19525     }
19526
19527   if (!vam->json_output)
19528     {
19529       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19530     }
19531
19532   M (FLOW_CLASSIFY_DUMP, mp);
19533   mp->type = type;
19534   /* send it... */
19535   S (mp);
19536
19537   /* Use a control ping for synchronization */
19538   M (CONTROL_PING, mp_ping);
19539   S (mp_ping);
19540
19541   /* Wait for a reply... */
19542   W (ret);
19543   return ret;
19544 }
19545
19546 static int
19547 api_feature_enable_disable (vat_main_t * vam)
19548 {
19549   unformat_input_t *i = vam->input;
19550   vl_api_feature_enable_disable_t *mp;
19551   u8 *arc_name = 0;
19552   u8 *feature_name = 0;
19553   u32 sw_if_index = ~0;
19554   u8 enable = 1;
19555   int ret;
19556
19557   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19558     {
19559       if (unformat (i, "arc_name %s", &arc_name))
19560         ;
19561       else if (unformat (i, "feature_name %s", &feature_name))
19562         ;
19563       else
19564         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19565         ;
19566       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19567         ;
19568       else if (unformat (i, "disable"))
19569         enable = 0;
19570       else
19571         break;
19572     }
19573
19574   if (arc_name == 0)
19575     {
19576       errmsg ("missing arc name");
19577       return -99;
19578     }
19579   if (vec_len (arc_name) > 63)
19580     {
19581       errmsg ("arc name too long");
19582     }
19583
19584   if (feature_name == 0)
19585     {
19586       errmsg ("missing feature name");
19587       return -99;
19588     }
19589   if (vec_len (feature_name) > 63)
19590     {
19591       errmsg ("feature name too long");
19592     }
19593
19594   if (sw_if_index == ~0)
19595     {
19596       errmsg ("missing interface name or sw_if_index");
19597       return -99;
19598     }
19599
19600   /* Construct the API message */
19601   M (FEATURE_ENABLE_DISABLE, mp);
19602   mp->sw_if_index = ntohl (sw_if_index);
19603   mp->enable = enable;
19604   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
19605   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
19606   vec_free (arc_name);
19607   vec_free (feature_name);
19608
19609   S (mp);
19610   W (ret);
19611   return ret;
19612 }
19613
19614 static int
19615 api_sw_interface_tag_add_del (vat_main_t * vam)
19616 {
19617   unformat_input_t *i = vam->input;
19618   vl_api_sw_interface_tag_add_del_t *mp;
19619   u32 sw_if_index = ~0;
19620   u8 *tag = 0;
19621   u8 enable = 1;
19622   int ret;
19623
19624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19625     {
19626       if (unformat (i, "tag %s", &tag))
19627         ;
19628       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19629         ;
19630       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19631         ;
19632       else if (unformat (i, "del"))
19633         enable = 0;
19634       else
19635         break;
19636     }
19637
19638   if (sw_if_index == ~0)
19639     {
19640       errmsg ("missing interface name or sw_if_index");
19641       return -99;
19642     }
19643
19644   if (enable && (tag == 0))
19645     {
19646       errmsg ("no tag specified");
19647       return -99;
19648     }
19649
19650   /* Construct the API message */
19651   M (SW_INTERFACE_TAG_ADD_DEL, mp);
19652   mp->sw_if_index = ntohl (sw_if_index);
19653   mp->is_add = enable;
19654   if (enable)
19655     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
19656   vec_free (tag);
19657
19658   S (mp);
19659   W (ret);
19660   return ret;
19661 }
19662
19663 static void vl_api_l2_xconnect_details_t_handler
19664   (vl_api_l2_xconnect_details_t * mp)
19665 {
19666   vat_main_t *vam = &vat_main;
19667
19668   print (vam->ofp, "%15d%15d",
19669          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
19670 }
19671
19672 static void vl_api_l2_xconnect_details_t_handler_json
19673   (vl_api_l2_xconnect_details_t * mp)
19674 {
19675   vat_main_t *vam = &vat_main;
19676   vat_json_node_t *node = NULL;
19677
19678   if (VAT_JSON_ARRAY != vam->json_tree.type)
19679     {
19680       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19681       vat_json_init_array (&vam->json_tree);
19682     }
19683   node = vat_json_array_add (&vam->json_tree);
19684
19685   vat_json_init_object (node);
19686   vat_json_object_add_uint (node, "rx_sw_if_index",
19687                             ntohl (mp->rx_sw_if_index));
19688   vat_json_object_add_uint (node, "tx_sw_if_index",
19689                             ntohl (mp->tx_sw_if_index));
19690 }
19691
19692 static int
19693 api_l2_xconnect_dump (vat_main_t * vam)
19694 {
19695   vl_api_l2_xconnect_dump_t *mp;
19696   vl_api_control_ping_t *mp_ping;
19697   int ret;
19698
19699   if (!vam->json_output)
19700     {
19701       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
19702     }
19703
19704   M (L2_XCONNECT_DUMP, mp);
19705
19706   S (mp);
19707
19708   /* Use a control ping for synchronization */
19709   M (CONTROL_PING, mp_ping);
19710   S (mp_ping);
19711
19712   W (ret);
19713   return ret;
19714 }
19715
19716 static int
19717 api_sw_interface_set_mtu (vat_main_t * vam)
19718 {
19719   unformat_input_t *i = vam->input;
19720   vl_api_sw_interface_set_mtu_t *mp;
19721   u32 sw_if_index = ~0;
19722   u32 mtu = 0;
19723   int ret;
19724
19725   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19726     {
19727       if (unformat (i, "mtu %d", &mtu))
19728         ;
19729       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19730         ;
19731       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19732         ;
19733       else
19734         break;
19735     }
19736
19737   if (sw_if_index == ~0)
19738     {
19739       errmsg ("missing interface name or sw_if_index");
19740       return -99;
19741     }
19742
19743   if (mtu == 0)
19744     {
19745       errmsg ("no mtu specified");
19746       return -99;
19747     }
19748
19749   /* Construct the API message */
19750   M (SW_INTERFACE_SET_MTU, mp);
19751   mp->sw_if_index = ntohl (sw_if_index);
19752   mp->mtu = ntohs ((u16) mtu);
19753
19754   S (mp);
19755   W (ret);
19756   return ret;
19757 }
19758
19759 static int
19760 api_p2p_ethernet_add (vat_main_t * vam)
19761 {
19762   unformat_input_t *i = vam->input;
19763   vl_api_p2p_ethernet_add_t *mp;
19764   u32 parent_if_index = ~0;
19765   u32 sub_id = ~0;
19766   u8 remote_mac[6];
19767   u8 mac_set = 0;
19768   int ret;
19769
19770   memset (remote_mac, 0, sizeof (remote_mac));
19771   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19772     {
19773       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19774         ;
19775       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19776         ;
19777       else
19778         if (unformat
19779             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19780         mac_set++;
19781       else if (unformat (i, "sub_id %d", &sub_id))
19782         ;
19783       else
19784         {
19785           clib_warning ("parse error '%U'", format_unformat_error, i);
19786           return -99;
19787         }
19788     }
19789
19790   if (parent_if_index == ~0)
19791     {
19792       errmsg ("missing interface name or sw_if_index");
19793       return -99;
19794     }
19795   if (mac_set == 0)
19796     {
19797       errmsg ("missing remote mac address");
19798       return -99;
19799     }
19800   if (sub_id == ~0)
19801     {
19802       errmsg ("missing sub-interface id");
19803       return -99;
19804     }
19805
19806   M (P2P_ETHERNET_ADD, mp);
19807   mp->parent_if_index = ntohl (parent_if_index);
19808   mp->subif_id = ntohl (sub_id);
19809   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19810
19811   S (mp);
19812   W (ret);
19813   return ret;
19814 }
19815
19816 static int
19817 api_p2p_ethernet_del (vat_main_t * vam)
19818 {
19819   unformat_input_t *i = vam->input;
19820   vl_api_p2p_ethernet_del_t *mp;
19821   u32 parent_if_index = ~0;
19822   u8 remote_mac[6];
19823   u8 mac_set = 0;
19824   int ret;
19825
19826   memset (remote_mac, 0, sizeof (remote_mac));
19827   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19828     {
19829       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19830         ;
19831       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19832         ;
19833       else
19834         if (unformat
19835             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19836         mac_set++;
19837       else
19838         {
19839           clib_warning ("parse error '%U'", format_unformat_error, i);
19840           return -99;
19841         }
19842     }
19843
19844   if (parent_if_index == ~0)
19845     {
19846       errmsg ("missing interface name or sw_if_index");
19847       return -99;
19848     }
19849   if (mac_set == 0)
19850     {
19851       errmsg ("missing remote mac address");
19852       return -99;
19853     }
19854
19855   M (P2P_ETHERNET_DEL, mp);
19856   mp->parent_if_index = ntohl (parent_if_index);
19857   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19858
19859   S (mp);
19860   W (ret);
19861   return ret;
19862 }
19863
19864 static int
19865 api_lldp_config (vat_main_t * vam)
19866 {
19867   unformat_input_t *i = vam->input;
19868   vl_api_lldp_config_t *mp;
19869   int tx_hold = 0;
19870   int tx_interval = 0;
19871   u8 *sys_name = NULL;
19872   int ret;
19873
19874   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19875     {
19876       if (unformat (i, "system-name %s", &sys_name))
19877         ;
19878       else if (unformat (i, "tx-hold %d", &tx_hold))
19879         ;
19880       else if (unformat (i, "tx-interval %d", &tx_interval))
19881         ;
19882       else
19883         {
19884           clib_warning ("parse error '%U'", format_unformat_error, i);
19885           return -99;
19886         }
19887     }
19888
19889   vec_add1 (sys_name, 0);
19890
19891   M (LLDP_CONFIG, mp);
19892   mp->tx_hold = htonl (tx_hold);
19893   mp->tx_interval = htonl (tx_interval);
19894   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
19895   vec_free (sys_name);
19896
19897   S (mp);
19898   W (ret);
19899   return ret;
19900 }
19901
19902 static int
19903 api_sw_interface_set_lldp (vat_main_t * vam)
19904 {
19905   unformat_input_t *i = vam->input;
19906   vl_api_sw_interface_set_lldp_t *mp;
19907   u32 sw_if_index = ~0;
19908   u32 enable = 1;
19909   u8 *port_desc = NULL;
19910   int ret;
19911
19912   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19913     {
19914       if (unformat (i, "disable"))
19915         enable = 0;
19916       else
19917         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19918         ;
19919       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19920         ;
19921       else if (unformat (i, "port-desc %s", &port_desc))
19922         ;
19923       else
19924         break;
19925     }
19926
19927   if (sw_if_index == ~0)
19928     {
19929       errmsg ("missing interface name or sw_if_index");
19930       return -99;
19931     }
19932
19933   /* Construct the API message */
19934   vec_add1 (port_desc, 0);
19935   M (SW_INTERFACE_SET_LLDP, mp);
19936   mp->sw_if_index = ntohl (sw_if_index);
19937   mp->enable = enable;
19938   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
19939   vec_free (port_desc);
19940
19941   S (mp);
19942   W (ret);
19943   return ret;
19944 }
19945
19946 static int
19947 api_tcp_configure_src_addresses (vat_main_t * vam)
19948 {
19949   vl_api_tcp_configure_src_addresses_t *mp;
19950   unformat_input_t *i = vam->input;
19951   ip4_address_t v4first, v4last;
19952   ip6_address_t v6first, v6last;
19953   u8 range_set = 0;
19954   u32 vrf_id = 0;
19955   int ret;
19956
19957   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19958     {
19959       if (unformat (i, "%U - %U",
19960                     unformat_ip4_address, &v4first,
19961                     unformat_ip4_address, &v4last))
19962         {
19963           if (range_set)
19964             {
19965               errmsg ("one range per message (range already set)");
19966               return -99;
19967             }
19968           range_set = 1;
19969         }
19970       else if (unformat (i, "%U - %U",
19971                          unformat_ip6_address, &v6first,
19972                          unformat_ip6_address, &v6last))
19973         {
19974           if (range_set)
19975             {
19976               errmsg ("one range per message (range already set)");
19977               return -99;
19978             }
19979           range_set = 2;
19980         }
19981       else if (unformat (i, "vrf %d", &vrf_id))
19982         ;
19983       else
19984         break;
19985     }
19986
19987   if (range_set == 0)
19988     {
19989       errmsg ("address range not set");
19990       return -99;
19991     }
19992
19993   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
19994   mp->vrf_id = ntohl (vrf_id);
19995   /* ipv6? */
19996   if (range_set == 2)
19997     {
19998       mp->is_ipv6 = 1;
19999       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20000       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20001     }
20002   else
20003     {
20004       mp->is_ipv6 = 0;
20005       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
20006       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
20007     }
20008   S (mp);
20009   W (ret);
20010   return ret;
20011 }
20012
20013 static int
20014 q_or_quit (vat_main_t * vam)
20015 {
20016 #if VPP_API_TEST_BUILTIN == 0
20017   longjmp (vam->jump_buf, 1);
20018 #endif
20019   return 0;                     /* not so much */
20020 }
20021
20022 static int
20023 q (vat_main_t * vam)
20024 {
20025   return q_or_quit (vam);
20026 }
20027
20028 static int
20029 quit (vat_main_t * vam)
20030 {
20031   return q_or_quit (vam);
20032 }
20033
20034 static int
20035 comment (vat_main_t * vam)
20036 {
20037   return 0;
20038 }
20039
20040 static int
20041 cmd_cmp (void *a1, void *a2)
20042 {
20043   u8 **c1 = a1;
20044   u8 **c2 = a2;
20045
20046   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
20047 }
20048
20049 static int
20050 help (vat_main_t * vam)
20051 {
20052   u8 **cmds = 0;
20053   u8 *name = 0;
20054   hash_pair_t *p;
20055   unformat_input_t *i = vam->input;
20056   int j;
20057
20058   if (unformat (i, "%s", &name))
20059     {
20060       uword *hs;
20061
20062       vec_add1 (name, 0);
20063
20064       hs = hash_get_mem (vam->help_by_name, name);
20065       if (hs)
20066         print (vam->ofp, "usage: %s %s", name, hs[0]);
20067       else
20068         print (vam->ofp, "No such msg / command '%s'", name);
20069       vec_free (name);
20070       return 0;
20071     }
20072
20073   print (vam->ofp, "Help is available for the following:");
20074
20075     /* *INDENT-OFF* */
20076     hash_foreach_pair (p, vam->function_by_name,
20077     ({
20078       vec_add1 (cmds, (u8 *)(p->key));
20079     }));
20080     /* *INDENT-ON* */
20081
20082   vec_sort_with_function (cmds, cmd_cmp);
20083
20084   for (j = 0; j < vec_len (cmds); j++)
20085     print (vam->ofp, "%s", cmds[j]);
20086
20087   vec_free (cmds);
20088   return 0;
20089 }
20090
20091 static int
20092 set (vat_main_t * vam)
20093 {
20094   u8 *name = 0, *value = 0;
20095   unformat_input_t *i = vam->input;
20096
20097   if (unformat (i, "%s", &name))
20098     {
20099       /* The input buffer is a vector, not a string. */
20100       value = vec_dup (i->buffer);
20101       vec_delete (value, i->index, 0);
20102       /* Almost certainly has a trailing newline */
20103       if (value[vec_len (value) - 1] == '\n')
20104         value[vec_len (value) - 1] = 0;
20105       /* Make sure it's a proper string, one way or the other */
20106       vec_add1 (value, 0);
20107       (void) clib_macro_set_value (&vam->macro_main,
20108                                    (char *) name, (char *) value);
20109     }
20110   else
20111     errmsg ("usage: set <name> <value>");
20112
20113   vec_free (name);
20114   vec_free (value);
20115   return 0;
20116 }
20117
20118 static int
20119 unset (vat_main_t * vam)
20120 {
20121   u8 *name = 0;
20122
20123   if (unformat (vam->input, "%s", &name))
20124     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
20125       errmsg ("unset: %s wasn't set", name);
20126   vec_free (name);
20127   return 0;
20128 }
20129
20130 typedef struct
20131 {
20132   u8 *name;
20133   u8 *value;
20134 } macro_sort_t;
20135
20136
20137 static int
20138 macro_sort_cmp (void *a1, void *a2)
20139 {
20140   macro_sort_t *s1 = a1;
20141   macro_sort_t *s2 = a2;
20142
20143   return strcmp ((char *) (s1->name), (char *) (s2->name));
20144 }
20145
20146 static int
20147 dump_macro_table (vat_main_t * vam)
20148 {
20149   macro_sort_t *sort_me = 0, *sm;
20150   int i;
20151   hash_pair_t *p;
20152
20153     /* *INDENT-OFF* */
20154     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
20155     ({
20156       vec_add2 (sort_me, sm, 1);
20157       sm->name = (u8 *)(p->key);
20158       sm->value = (u8 *) (p->value[0]);
20159     }));
20160     /* *INDENT-ON* */
20161
20162   vec_sort_with_function (sort_me, macro_sort_cmp);
20163
20164   if (vec_len (sort_me))
20165     print (vam->ofp, "%-15s%s", "Name", "Value");
20166   else
20167     print (vam->ofp, "The macro table is empty...");
20168
20169   for (i = 0; i < vec_len (sort_me); i++)
20170     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
20171   return 0;
20172 }
20173
20174 static int
20175 dump_node_table (vat_main_t * vam)
20176 {
20177   int i, j;
20178   vlib_node_t *node, *next_node;
20179
20180   if (vec_len (vam->graph_nodes) == 0)
20181     {
20182       print (vam->ofp, "Node table empty, issue get_node_graph...");
20183       return 0;
20184     }
20185
20186   for (i = 0; i < vec_len (vam->graph_nodes); i++)
20187     {
20188       node = vam->graph_nodes[i];
20189       print (vam->ofp, "[%d] %s", i, node->name);
20190       for (j = 0; j < vec_len (node->next_nodes); j++)
20191         {
20192           if (node->next_nodes[j] != ~0)
20193             {
20194               next_node = vam->graph_nodes[node->next_nodes[j]];
20195               print (vam->ofp, "  [%d] %s", j, next_node->name);
20196             }
20197         }
20198     }
20199   return 0;
20200 }
20201
20202 static int
20203 value_sort_cmp (void *a1, void *a2)
20204 {
20205   name_sort_t *n1 = a1;
20206   name_sort_t *n2 = a2;
20207
20208   if (n1->value < n2->value)
20209     return -1;
20210   if (n1->value > n2->value)
20211     return 1;
20212   return 0;
20213 }
20214
20215
20216 static int
20217 dump_msg_api_table (vat_main_t * vam)
20218 {
20219   api_main_t *am = &api_main;
20220   name_sort_t *nses = 0, *ns;
20221   hash_pair_t *hp;
20222   int i;
20223
20224   /* *INDENT-OFF* */
20225   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
20226   ({
20227     vec_add2 (nses, ns, 1);
20228     ns->name = (u8 *)(hp->key);
20229     ns->value = (u32) hp->value[0];
20230   }));
20231   /* *INDENT-ON* */
20232
20233   vec_sort_with_function (nses, value_sort_cmp);
20234
20235   for (i = 0; i < vec_len (nses); i++)
20236     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
20237   vec_free (nses);
20238   return 0;
20239 }
20240
20241 static int
20242 get_msg_id (vat_main_t * vam)
20243 {
20244   u8 *name_and_crc;
20245   u32 message_index;
20246
20247   if (unformat (vam->input, "%s", &name_and_crc))
20248     {
20249       message_index = vl_api_get_msg_index (name_and_crc);
20250       if (message_index == ~0)
20251         {
20252           print (vam->ofp, " '%s' not found", name_and_crc);
20253           return 0;
20254         }
20255       print (vam->ofp, " '%s' has message index %d",
20256              name_and_crc, message_index);
20257       return 0;
20258     }
20259   errmsg ("name_and_crc required...");
20260   return 0;
20261 }
20262
20263 static int
20264 search_node_table (vat_main_t * vam)
20265 {
20266   unformat_input_t *line_input = vam->input;
20267   u8 *node_to_find;
20268   int j;
20269   vlib_node_t *node, *next_node;
20270   uword *p;
20271
20272   if (vam->graph_node_index_by_name == 0)
20273     {
20274       print (vam->ofp, "Node table empty, issue get_node_graph...");
20275       return 0;
20276     }
20277
20278   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20279     {
20280       if (unformat (line_input, "%s", &node_to_find))
20281         {
20282           vec_add1 (node_to_find, 0);
20283           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
20284           if (p == 0)
20285             {
20286               print (vam->ofp, "%s not found...", node_to_find);
20287               goto out;
20288             }
20289           node = vam->graph_nodes[p[0]];
20290           print (vam->ofp, "[%d] %s", p[0], node->name);
20291           for (j = 0; j < vec_len (node->next_nodes); j++)
20292             {
20293               if (node->next_nodes[j] != ~0)
20294                 {
20295                   next_node = vam->graph_nodes[node->next_nodes[j]];
20296                   print (vam->ofp, "  [%d] %s", j, next_node->name);
20297                 }
20298             }
20299         }
20300
20301       else
20302         {
20303           clib_warning ("parse error '%U'", format_unformat_error,
20304                         line_input);
20305           return -99;
20306         }
20307
20308     out:
20309       vec_free (node_to_find);
20310
20311     }
20312
20313   return 0;
20314 }
20315
20316
20317 static int
20318 script (vat_main_t * vam)
20319 {
20320 #if (VPP_API_TEST_BUILTIN==0)
20321   u8 *s = 0;
20322   char *save_current_file;
20323   unformat_input_t save_input;
20324   jmp_buf save_jump_buf;
20325   u32 save_line_number;
20326
20327   FILE *new_fp, *save_ifp;
20328
20329   if (unformat (vam->input, "%s", &s))
20330     {
20331       new_fp = fopen ((char *) s, "r");
20332       if (new_fp == 0)
20333         {
20334           errmsg ("Couldn't open script file %s", s);
20335           vec_free (s);
20336           return -99;
20337         }
20338     }
20339   else
20340     {
20341       errmsg ("Missing script name");
20342       return -99;
20343     }
20344
20345   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
20346   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
20347   save_ifp = vam->ifp;
20348   save_line_number = vam->input_line_number;
20349   save_current_file = (char *) vam->current_file;
20350
20351   vam->input_line_number = 0;
20352   vam->ifp = new_fp;
20353   vam->current_file = s;
20354   do_one_file (vam);
20355
20356   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
20357   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
20358   vam->ifp = save_ifp;
20359   vam->input_line_number = save_line_number;
20360   vam->current_file = (u8 *) save_current_file;
20361   vec_free (s);
20362
20363   return 0;
20364 #else
20365   clib_warning ("use the exec command...");
20366   return -99;
20367 #endif
20368 }
20369
20370 static int
20371 echo (vat_main_t * vam)
20372 {
20373   print (vam->ofp, "%v", vam->input->buffer);
20374   return 0;
20375 }
20376
20377 /* List of API message constructors, CLI names map to api_xxx */
20378 #define foreach_vpe_api_msg                                             \
20379 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
20380 _(sw_interface_dump,"")                                                 \
20381 _(sw_interface_set_flags,                                               \
20382   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
20383 _(sw_interface_add_del_address,                                         \
20384   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
20385 _(sw_interface_set_table,                                               \
20386   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
20387 _(sw_interface_set_mpls_enable,                                         \
20388   "<intfc> | sw_if_index [disable | dis]")                              \
20389 _(sw_interface_set_vpath,                                               \
20390   "<intfc> | sw_if_index <id> enable | disable")                        \
20391 _(sw_interface_set_vxlan_bypass,                                        \
20392   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20393 _(sw_interface_set_l2_xconnect,                                         \
20394   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20395   "enable | disable")                                                   \
20396 _(sw_interface_set_l2_bridge,                                           \
20397   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
20398   "[shg <split-horizon-group>] [bvi]\n"                                 \
20399   "enable | disable")                                                   \
20400 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
20401 _(bridge_domain_add_del,                                                \
20402   "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] [bd-tag <tag>] [del]\n") \
20403 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
20404 _(l2fib_add_del,                                                        \
20405   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
20406 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
20407 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
20408 _(l2_flags,                                                             \
20409   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20410 _(bridge_flags,                                                         \
20411   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20412 _(tap_connect,                                                          \
20413   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
20414 _(tap_modify,                                                           \
20415   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
20416 _(tap_delete,                                                           \
20417   "<vpp-if-name> | sw_if_index <id>")                                   \
20418 _(sw_interface_tap_dump, "")                                            \
20419 _(ip_table_add_del,                                                     \
20420   "table-id <n> [ipv6]\n")                                              \
20421 _(ip_add_del_route,                                                     \
20422   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
20423   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
20424   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
20425   "[multipath] [count <n>]")                                            \
20426 _(ip_mroute_add_del,                                                    \
20427   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
20428   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
20429 _(mpls_table_add_del,                                                   \
20430   "table-id <n>\n")                                                     \
20431 _(mpls_route_add_del,                                                   \
20432   "<label> <eos> via <addr> [table-id <n>]\n"                           \
20433   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
20434   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
20435   "[multipath] [count <n>]")                                            \
20436 _(mpls_ip_bind_unbind,                                                  \
20437   "<label> <addr/len>")                                                 \
20438 _(mpls_tunnel_add_del,                                                  \
20439   " via <addr> [table-id <n>]\n"                                        \
20440   "sw_if_index <id>] [l2]  [del]")                                      \
20441 _(proxy_arp_add_del,                                                    \
20442   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
20443 _(proxy_arp_intfc_enable_disable,                                       \
20444   "<intfc> | sw_if_index <id> enable | disable")                        \
20445 _(sw_interface_set_unnumbered,                                          \
20446   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
20447 _(ip_neighbor_add_del,                                                  \
20448   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
20449   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
20450 _(reset_vrf, "vrf <id> [ipv6]")                                         \
20451 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
20452 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
20453   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
20454   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
20455   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
20456 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
20457 _(reset_fib, "vrf <n> [ipv6]")                                          \
20458 _(dhcp_proxy_config,                                                    \
20459   "svr <v46-address> src <v46-address>\n"                               \
20460    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
20461 _(dhcp_proxy_set_vss,                                                   \
20462   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
20463 _(dhcp_proxy_dump, "ip6")                                               \
20464 _(dhcp_client_config,                                                   \
20465   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
20466 _(set_ip_flow_hash,                                                     \
20467   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
20468 _(sw_interface_ip6_enable_disable,                                      \
20469   "<intfc> | sw_if_index <id> enable | disable")                        \
20470 _(sw_interface_ip6_set_link_local_address,                              \
20471   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
20472 _(ip6nd_proxy_add_del,                                                  \
20473   "<intfc> | sw_if_index <id> <ip6-address>")                           \
20474 _(ip6nd_proxy_dump, "")                                                 \
20475 _(sw_interface_ip6nd_ra_prefix,                                         \
20476   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
20477   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
20478   "[nolink] [isno]")                                                    \
20479 _(sw_interface_ip6nd_ra_config,                                         \
20480   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
20481   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
20482   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
20483 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
20484 _(l2_patch_add_del,                                                     \
20485   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20486   "enable | disable")                                                   \
20487 _(sr_localsid_add_del,                                                  \
20488   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
20489   "fib-table <num> (end.psp) sw_if_index <num>")                        \
20490 _(classify_add_del_table,                                               \
20491   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
20492   " [del] [del-chain] mask <mask-value>\n"                              \
20493   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
20494   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
20495 _(classify_add_del_session,                                             \
20496   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
20497   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
20498   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
20499   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
20500 _(classify_set_interface_ip_table,                                      \
20501   "<intfc> | sw_if_index <nn> table <nn>")                              \
20502 _(classify_set_interface_l2_tables,                                     \
20503   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20504   "  [other-table <nn>]")                                               \
20505 _(get_node_index, "node <node-name")                                    \
20506 _(add_node_next, "node <node-name> next <next-node-name>")              \
20507 _(l2tpv3_create_tunnel,                                                 \
20508   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
20509   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
20510   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
20511 _(l2tpv3_set_tunnel_cookies,                                            \
20512   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
20513   "[new_remote_cookie <nn>]\n")                                         \
20514 _(l2tpv3_interface_enable_disable,                                      \
20515   "<intfc> | sw_if_index <nn> enable | disable")                        \
20516 _(l2tpv3_set_lookup_key,                                                \
20517   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
20518 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
20519 _(vxlan_add_del_tunnel,                                                 \
20520   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20521   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20522   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20523 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
20524 _(gre_add_del_tunnel,                                                   \
20525   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
20526 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
20527 _(l2_fib_clear_table, "")                                               \
20528 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
20529 _(l2_interface_vlan_tag_rewrite,                                        \
20530   "<intfc> | sw_if_index <nn> \n"                                       \
20531   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
20532   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
20533 _(create_vhost_user_if,                                                 \
20534         "socket <filename> [server] [renumber <dev_instance>] "         \
20535         "[mac <mac_address>]")                                          \
20536 _(modify_vhost_user_if,                                                 \
20537         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
20538         "[server] [renumber <dev_instance>]")                           \
20539 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
20540 _(sw_interface_vhost_user_dump, "")                                     \
20541 _(show_version, "")                                                     \
20542 _(vxlan_gpe_add_del_tunnel,                                             \
20543   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
20544   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20545   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
20546   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
20547 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
20548 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
20549 _(interface_name_renumber,                                              \
20550   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
20551 _(input_acl_set_interface,                                              \
20552   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20553   "  [l2-table <nn>] [del]")                                            \
20554 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
20555 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
20556 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
20557 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
20558 _(ip_dump, "ipv4 | ipv6")                                               \
20559 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
20560 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
20561   "  spid_id <n> ")                                                     \
20562 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
20563   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
20564   "  integ_alg <alg> integ_key <hex>")                                  \
20565 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
20566   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
20567   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
20568   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
20569 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
20570 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
20571   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
20572   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
20573   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
20574 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
20575 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
20576   "(auth_data 0x<data> | auth_data <data>)")                            \
20577 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
20578   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
20579 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
20580   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
20581   "(local|remote)")                                                     \
20582 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
20583 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
20584 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
20585 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
20586 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
20587 _(ikev2_initiate_sa_init, "<profile_name>")                             \
20588 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
20589 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
20590 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
20591 _(delete_loopback,"sw_if_index <nn>")                                   \
20592 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
20593 _(map_add_domain,                                                       \
20594   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
20595   "ip6-src <ip6addr> "                                                  \
20596   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
20597 _(map_del_domain, "index <n>")                                          \
20598 _(map_add_del_rule,                                                     \
20599   "index <n> psid <n> dst <ip6addr> [del]")                             \
20600 _(map_domain_dump, "")                                                  \
20601 _(map_rule_dump, "index <map-domain>")                                  \
20602 _(want_interface_events,  "enable|disable")                             \
20603 _(want_stats,"enable|disable")                                          \
20604 _(get_first_msg_id, "client <name>")                                    \
20605 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
20606 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
20607   "fib-id <nn> [ip4][ip6][default]")                                    \
20608 _(get_node_graph, " ")                                                  \
20609 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
20610 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
20611 _(ioam_disable, "")                                                     \
20612 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
20613                             " sw_if_index <sw_if_index> p <priority> "  \
20614                             "w <weight>] [del]")                        \
20615 _(one_add_del_locator, "locator-set <locator_name> "                    \
20616                         "iface <intf> | sw_if_index <sw_if_index> "     \
20617                         "p <priority> w <weight> [del]")                \
20618 _(one_add_del_local_eid,"vni <vni> eid "                                \
20619                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20620                          "locator-set <locator_name> [del]"             \
20621                          "[key-id sha1|sha256 secret-key <secret-key>]")\
20622 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
20623 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
20624 _(one_enable_disable, "enable|disable")                                 \
20625 _(one_map_register_enable_disable, "enable|disable")                    \
20626 _(one_map_register_fallback_threshold, "<value>")                       \
20627 _(one_rloc_probe_enable_disable, "enable|disable")                      \
20628 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
20629                                "[seid <seid>] "                         \
20630                                "rloc <locator> p <prio> "               \
20631                                "w <weight> [rloc <loc> ... ] "          \
20632                                "action <action> [del-all]")             \
20633 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
20634                           "<local-eid>")                                \
20635 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
20636 _(one_use_petr, "ip-address> | disable")                                \
20637 _(one_map_request_mode, "src-dst|dst-only")                             \
20638 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
20639 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
20640 _(one_locator_set_dump, "[local | remote]")                             \
20641 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
20642 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
20643                        "[local] | [remote]")                            \
20644 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
20645 _(one_ndp_bd_get, "")                                                   \
20646 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
20647 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
20648 _(one_l2_arp_bd_get, "")                                                \
20649 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
20650 _(one_stats_enable_disable, "enable|disalbe")                           \
20651 _(show_one_stats_enable_disable, "")                                    \
20652 _(one_eid_table_vni_dump, "")                                           \
20653 _(one_eid_table_map_dump, "l2|l3")                                      \
20654 _(one_map_resolver_dump, "")                                            \
20655 _(one_map_server_dump, "")                                              \
20656 _(one_adjacencies_get, "vni <vni>")                                     \
20657 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
20658 _(show_one_rloc_probe_state, "")                                        \
20659 _(show_one_map_register_state, "")                                      \
20660 _(show_one_status, "")                                                  \
20661 _(one_stats_dump, "")                                                   \
20662 _(one_stats_flush, "")                                                  \
20663 _(one_get_map_request_itr_rlocs, "")                                    \
20664 _(one_map_register_set_ttl, "<ttl>")                                    \
20665 _(show_one_nsh_mapping, "")                                             \
20666 _(show_one_pitr, "")                                                    \
20667 _(show_one_use_petr, "")                                                \
20668 _(show_one_map_request_mode, "")                                        \
20669 _(show_one_map_register_ttl, "")                                        \
20670 _(show_one_map_register_fallback_threshold, "")                         \
20671 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
20672                             " sw_if_index <sw_if_index> p <priority> "  \
20673                             "w <weight>] [del]")                        \
20674 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
20675                         "iface <intf> | sw_if_index <sw_if_index> "     \
20676                         "p <priority> w <weight> [del]")                \
20677 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
20678                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20679                          "locator-set <locator_name> [del]"             \
20680                          "[key-id sha1|sha256 secret-key <secret-key>]") \
20681 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
20682 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
20683 _(lisp_enable_disable, "enable|disable")                                \
20684 _(lisp_map_register_enable_disable, "enable|disable")                   \
20685 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
20686 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
20687                                "[seid <seid>] "                         \
20688                                "rloc <locator> p <prio> "               \
20689                                "w <weight> [rloc <loc> ... ] "          \
20690                                "action <action> [del-all]")             \
20691 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
20692                           "<local-eid>")                                \
20693 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
20694 _(lisp_use_petr, "<ip-address> | disable")                              \
20695 _(lisp_map_request_mode, "src-dst|dst-only")                            \
20696 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
20697 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
20698 _(lisp_locator_set_dump, "[local | remote]")                            \
20699 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
20700 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
20701                        "[local] | [remote]")                            \
20702 _(lisp_eid_table_vni_dump, "")                                          \
20703 _(lisp_eid_table_map_dump, "l2|l3")                                     \
20704 _(lisp_map_resolver_dump, "")                                           \
20705 _(lisp_map_server_dump, "")                                             \
20706 _(lisp_adjacencies_get, "vni <vni>")                                    \
20707 _(gpe_fwd_entry_vnis_get, "")                                           \
20708 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
20709 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
20710                                 "[table <table-id>]")                   \
20711 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
20712 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
20713 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
20714 _(gpe_get_encap_mode, "")                                               \
20715 _(lisp_gpe_add_del_iface, "up|down")                                    \
20716 _(lisp_gpe_enable_disable, "enable|disable")                            \
20717 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
20718   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
20719 _(show_lisp_rloc_probe_state, "")                                       \
20720 _(show_lisp_map_register_state, "")                                     \
20721 _(show_lisp_status, "")                                                 \
20722 _(lisp_get_map_request_itr_rlocs, "")                                   \
20723 _(show_lisp_pitr, "")                                                   \
20724 _(show_lisp_use_petr, "")                                               \
20725 _(show_lisp_map_request_mode, "")                                       \
20726 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
20727 _(af_packet_delete, "name <host interface name>")                       \
20728 _(policer_add_del, "name <policer name> <params> [del]")                \
20729 _(policer_dump, "[name <policer name>]")                                \
20730 _(policer_classify_set_interface,                                       \
20731   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20732   "  [l2-table <nn>] [del]")                                            \
20733 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
20734 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
20735     "[master|slave]")                                                   \
20736 _(netmap_delete, "name <interface name>")                               \
20737 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
20738 _(mpls_fib_dump, "")                                                    \
20739 _(classify_table_ids, "")                                               \
20740 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
20741 _(classify_table_info, "table_id <nn>")                                 \
20742 _(classify_session_dump, "table_id <nn>")                               \
20743 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
20744     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
20745     "[template_interval <nn>] [udp_checksum]")                          \
20746 _(ipfix_exporter_dump, "")                                              \
20747 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
20748 _(ipfix_classify_stream_dump, "")                                       \
20749 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
20750 _(ipfix_classify_table_dump, "")                                        \
20751 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
20752 _(sw_interface_span_dump, "[l2]")                                           \
20753 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
20754 _(pg_create_interface, "if_id <nn>")                                    \
20755 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
20756 _(pg_enable_disable, "[stream <id>] disable")                           \
20757 _(ip_source_and_port_range_check_add_del,                               \
20758   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
20759 _(ip_source_and_port_range_check_interface_add_del,                     \
20760   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
20761   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
20762 _(ipsec_gre_add_del_tunnel,                                             \
20763   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
20764 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
20765 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
20766 _(l2_interface_pbb_tag_rewrite,                                         \
20767   "<intfc> | sw_if_index <nn> \n"                                       \
20768   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
20769   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
20770 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
20771 _(flow_classify_set_interface,                                          \
20772   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
20773 _(flow_classify_dump, "type [ip4|ip6]")                                 \
20774 _(ip_fib_dump, "")                                                      \
20775 _(ip_mfib_dump, "")                                                     \
20776 _(ip6_fib_dump, "")                                                     \
20777 _(ip6_mfib_dump, "")                                                    \
20778 _(feature_enable_disable, "arc_name <arc_name> "                        \
20779   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
20780 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
20781 "[disable]")                                                            \
20782 _(l2_xconnect_dump, "")                                                 \
20783 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
20784 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
20785 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
20786 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
20787 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
20788 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
20789 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>] [disable]") \
20790 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")
20791
20792 /* List of command functions, CLI names map directly to functions */
20793 #define foreach_cli_function                                    \
20794 _(comment, "usage: comment <ignore-rest-of-line>")              \
20795 _(dump_interface_table, "usage: dump_interface_table")          \
20796 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
20797 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
20798 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
20799 _(dump_stats_table, "usage: dump_stats_table")                  \
20800 _(dump_macro_table, "usage: dump_macro_table ")                 \
20801 _(dump_node_table, "usage: dump_node_table")                    \
20802 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
20803 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
20804 _(echo, "usage: echo <message>")                                \
20805 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
20806 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
20807 _(help, "usage: help")                                          \
20808 _(q, "usage: quit")                                             \
20809 _(quit, "usage: quit")                                          \
20810 _(search_node_table, "usage: search_node_table <name>...")      \
20811 _(set, "usage: set <variable-name> <value>")                    \
20812 _(script, "usage: script <file-name>")                          \
20813 _(unset, "usage: unset <variable-name>")
20814 #define _(N,n)                                  \
20815     static void vl_api_##n##_t_handler_uni      \
20816     (vl_api_##n##_t * mp)                       \
20817     {                                           \
20818         vat_main_t * vam = &vat_main;           \
20819         if (vam->json_output) {                 \
20820             vl_api_##n##_t_handler_json(mp);    \
20821         } else {                                \
20822             vl_api_##n##_t_handler(mp);         \
20823         }                                       \
20824     }
20825 foreach_vpe_api_reply_msg;
20826 #if VPP_API_TEST_BUILTIN == 0
20827 foreach_standalone_reply_msg;
20828 #endif
20829 #undef _
20830
20831 void
20832 vat_api_hookup (vat_main_t * vam)
20833 {
20834 #define _(N,n)                                                  \
20835     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
20836                            vl_api_##n##_t_handler_uni,          \
20837                            vl_noop_handler,                     \
20838                            vl_api_##n##_t_endian,               \
20839                            vl_api_##n##_t_print,                \
20840                            sizeof(vl_api_##n##_t), 1);
20841   foreach_vpe_api_reply_msg;
20842 #if VPP_API_TEST_BUILTIN == 0
20843   foreach_standalone_reply_msg;
20844 #endif
20845 #undef _
20846
20847 #if (VPP_API_TEST_BUILTIN==0)
20848   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
20849
20850   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
20851
20852   vam->function_by_name = hash_create_string (0, sizeof (uword));
20853
20854   vam->help_by_name = hash_create_string (0, sizeof (uword));
20855 #endif
20856
20857   /* API messages we can send */
20858 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
20859   foreach_vpe_api_msg;
20860 #undef _
20861
20862   /* Help strings */
20863 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
20864   foreach_vpe_api_msg;
20865 #undef _
20866
20867   /* CLI functions */
20868 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
20869   foreach_cli_function;
20870 #undef _
20871
20872   /* Help strings */
20873 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
20874   foreach_cli_function;
20875 #undef _
20876 }
20877
20878 #if VPP_API_TEST_BUILTIN
20879 static clib_error_t *
20880 vat_api_hookup_shim (vlib_main_t * vm)
20881 {
20882   vat_api_hookup (&vat_main);
20883   return 0;
20884 }
20885
20886 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
20887 #endif
20888
20889 /*
20890  * fd.io coding-style-patch-verification: ON
20891  *
20892  * Local Variables:
20893  * eval: (c-set-style "gnu")
20894  * End:
20895  */