LISP: add API handlers for set/get transport protocol
[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 u8 *
1756 format_lisp_transport_protocol (u8 * s, va_list * args)
1757 {
1758   u32 proto = va_arg (*args, u32);
1759
1760   switch (proto)
1761     {
1762     case 1:
1763       return format (s, "udp");
1764     case 2:
1765       return format (s, "api");
1766     default:
1767       return 0;
1768     }
1769   return 0;
1770 }
1771
1772 static void vl_api_one_get_transport_protocol_reply_t_handler
1773   (vl_api_one_get_transport_protocol_reply_t * mp)
1774 {
1775   vat_main_t *vam = &vat_main;
1776   i32 retval = ntohl (mp->retval);
1777   if (vam->async_mode)
1778     {
1779       vam->async_errors += (retval < 0);
1780     }
1781   else
1782     {
1783       u32 proto = mp->protocol;
1784       print (vam->ofp, "Transport protocol: %U",
1785              format_lisp_transport_protocol, proto);
1786       vam->retval = retval;
1787       vam->result_ready = 1;
1788     }
1789 }
1790
1791 static void vl_api_one_get_transport_protocol_reply_t_handler_json
1792   (vl_api_one_get_transport_protocol_reply_t * mp)
1793 {
1794   vat_main_t *vam = &vat_main;
1795   vat_json_node_t node;
1796   u8 *s;
1797
1798   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
1799   vec_add1 (s, 0);
1800
1801   vat_json_init_object (&node);
1802   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1803   vat_json_object_add_string_copy (&node, "transport-protocol", s);
1804
1805   vec_free (s);
1806   vat_json_print (vam->ofp, &node);
1807   vat_json_free (&node);
1808
1809   vam->retval = ntohl (mp->retval);
1810   vam->result_ready = 1;
1811 }
1812
1813 static void vl_api_one_add_del_locator_set_reply_t_handler
1814   (vl_api_one_add_del_locator_set_reply_t * mp)
1815 {
1816   vat_main_t *vam = &vat_main;
1817   i32 retval = ntohl (mp->retval);
1818   if (vam->async_mode)
1819     {
1820       vam->async_errors += (retval < 0);
1821     }
1822   else
1823     {
1824       vam->retval = retval;
1825       vam->result_ready = 1;
1826     }
1827 }
1828
1829 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1830   (vl_api_one_add_del_locator_set_reply_t * mp)
1831 {
1832   vat_main_t *vam = &vat_main;
1833   vat_json_node_t node;
1834
1835   vat_json_init_object (&node);
1836   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1837   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1838
1839   vat_json_print (vam->ofp, &node);
1840   vat_json_free (&node);
1841
1842   vam->retval = ntohl (mp->retval);
1843   vam->result_ready = 1;
1844 }
1845
1846 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1847   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1848 {
1849   vat_main_t *vam = &vat_main;
1850   i32 retval = ntohl (mp->retval);
1851   if (vam->async_mode)
1852     {
1853       vam->async_errors += (retval < 0);
1854     }
1855   else
1856     {
1857       vam->retval = retval;
1858       vam->sw_if_index = ntohl (mp->sw_if_index);
1859       vam->result_ready = 1;
1860     }
1861 }
1862
1863 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1864   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1865 {
1866   vat_main_t *vam = &vat_main;
1867   vat_json_node_t node;
1868
1869   vat_json_init_object (&node);
1870   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1871   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1872
1873   vat_json_print (vam->ofp, &node);
1874   vat_json_free (&node);
1875
1876   vam->retval = ntohl (mp->retval);
1877   vam->result_ready = 1;
1878 }
1879
1880 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
1881   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
1882 {
1883   vat_main_t *vam = &vat_main;
1884   i32 retval = ntohl (mp->retval);
1885   if (vam->async_mode)
1886     {
1887       vam->async_errors += (retval < 0);
1888     }
1889   else
1890     {
1891       vam->retval = retval;
1892       vam->sw_if_index = ntohl (mp->sw_if_index);
1893       vam->result_ready = 1;
1894     }
1895 }
1896
1897 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
1898   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
1899 {
1900   vat_main_t *vam = &vat_main;
1901   vat_json_node_t node;
1902
1903   vat_json_init_object (&node);
1904   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1905   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1906
1907   vat_json_print (vam->ofp, &node);
1908   vat_json_free (&node);
1909
1910   vam->retval = ntohl (mp->retval);
1911   vam->result_ready = 1;
1912 }
1913
1914 static void vl_api_gre_add_del_tunnel_reply_t_handler
1915   (vl_api_gre_add_del_tunnel_reply_t * mp)
1916 {
1917   vat_main_t *vam = &vat_main;
1918   i32 retval = ntohl (mp->retval);
1919   if (vam->async_mode)
1920     {
1921       vam->async_errors += (retval < 0);
1922     }
1923   else
1924     {
1925       vam->retval = retval;
1926       vam->sw_if_index = ntohl (mp->sw_if_index);
1927       vam->result_ready = 1;
1928     }
1929 }
1930
1931 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1932   (vl_api_gre_add_del_tunnel_reply_t * mp)
1933 {
1934   vat_main_t *vam = &vat_main;
1935   vat_json_node_t node;
1936
1937   vat_json_init_object (&node);
1938   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1939   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1940
1941   vat_json_print (vam->ofp, &node);
1942   vat_json_free (&node);
1943
1944   vam->retval = ntohl (mp->retval);
1945   vam->result_ready = 1;
1946 }
1947
1948 static void vl_api_create_vhost_user_if_reply_t_handler
1949   (vl_api_create_vhost_user_if_reply_t * mp)
1950 {
1951   vat_main_t *vam = &vat_main;
1952   i32 retval = ntohl (mp->retval);
1953   if (vam->async_mode)
1954     {
1955       vam->async_errors += (retval < 0);
1956     }
1957   else
1958     {
1959       vam->retval = retval;
1960       vam->sw_if_index = ntohl (mp->sw_if_index);
1961       vam->result_ready = 1;
1962     }
1963 }
1964
1965 static void vl_api_create_vhost_user_if_reply_t_handler_json
1966   (vl_api_create_vhost_user_if_reply_t * mp)
1967 {
1968   vat_main_t *vam = &vat_main;
1969   vat_json_node_t node;
1970
1971   vat_json_init_object (&node);
1972   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1973   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1974
1975   vat_json_print (vam->ofp, &node);
1976   vat_json_free (&node);
1977
1978   vam->retval = ntohl (mp->retval);
1979   vam->result_ready = 1;
1980 }
1981
1982 static void vl_api_ip_address_details_t_handler
1983   (vl_api_ip_address_details_t * mp)
1984 {
1985   vat_main_t *vam = &vat_main;
1986   static ip_address_details_t empty_ip_address_details = { {0} };
1987   ip_address_details_t *address = NULL;
1988   ip_details_t *current_ip_details = NULL;
1989   ip_details_t *details = NULL;
1990
1991   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1992
1993   if (!details || vam->current_sw_if_index >= vec_len (details)
1994       || !details[vam->current_sw_if_index].present)
1995     {
1996       errmsg ("ip address details arrived but not stored");
1997       errmsg ("ip_dump should be called first");
1998       return;
1999     }
2000
2001   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2002
2003 #define addresses (current_ip_details->addr)
2004
2005   vec_validate_init_empty (addresses, vec_len (addresses),
2006                            empty_ip_address_details);
2007
2008   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2009
2010   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2011   address->prefix_length = mp->prefix_length;
2012 #undef addresses
2013 }
2014
2015 static void vl_api_ip_address_details_t_handler_json
2016   (vl_api_ip_address_details_t * mp)
2017 {
2018   vat_main_t *vam = &vat_main;
2019   vat_json_node_t *node = NULL;
2020   struct in6_addr ip6;
2021   struct in_addr ip4;
2022
2023   if (VAT_JSON_ARRAY != vam->json_tree.type)
2024     {
2025       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2026       vat_json_init_array (&vam->json_tree);
2027     }
2028   node = vat_json_array_add (&vam->json_tree);
2029
2030   vat_json_init_object (node);
2031   if (vam->is_ipv6)
2032     {
2033       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2034       vat_json_object_add_ip6 (node, "ip", ip6);
2035     }
2036   else
2037     {
2038       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2039       vat_json_object_add_ip4 (node, "ip", ip4);
2040     }
2041   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2042 }
2043
2044 static void
2045 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2046 {
2047   vat_main_t *vam = &vat_main;
2048   static ip_details_t empty_ip_details = { 0 };
2049   ip_details_t *ip = NULL;
2050   u32 sw_if_index = ~0;
2051
2052   sw_if_index = ntohl (mp->sw_if_index);
2053
2054   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2055                            sw_if_index, empty_ip_details);
2056
2057   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2058                          sw_if_index);
2059
2060   ip->present = 1;
2061 }
2062
2063 static void
2064 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2065 {
2066   vat_main_t *vam = &vat_main;
2067
2068   if (VAT_JSON_ARRAY != vam->json_tree.type)
2069     {
2070       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2071       vat_json_init_array (&vam->json_tree);
2072     }
2073   vat_json_array_add_uint (&vam->json_tree,
2074                            clib_net_to_host_u32 (mp->sw_if_index));
2075 }
2076
2077 static void vl_api_map_domain_details_t_handler_json
2078   (vl_api_map_domain_details_t * mp)
2079 {
2080   vat_json_node_t *node = NULL;
2081   vat_main_t *vam = &vat_main;
2082   struct in6_addr ip6;
2083   struct in_addr ip4;
2084
2085   if (VAT_JSON_ARRAY != vam->json_tree.type)
2086     {
2087       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2088       vat_json_init_array (&vam->json_tree);
2089     }
2090
2091   node = vat_json_array_add (&vam->json_tree);
2092   vat_json_init_object (node);
2093
2094   vat_json_object_add_uint (node, "domain_index",
2095                             clib_net_to_host_u32 (mp->domain_index));
2096   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
2097   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
2098   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
2099   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
2100   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
2101   vat_json_object_add_ip6 (node, "ip6_src", ip6);
2102   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
2103   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
2104   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
2105   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
2106   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
2107   vat_json_object_add_int (node, "psid_length", mp->psid_length);
2108   vat_json_object_add_uint (node, "flags", mp->flags);
2109   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
2110   vat_json_object_add_int (node, "is_translation", mp->is_translation);
2111 }
2112
2113 static void vl_api_map_domain_details_t_handler
2114   (vl_api_map_domain_details_t * mp)
2115 {
2116   vat_main_t *vam = &vat_main;
2117
2118   if (mp->is_translation)
2119     {
2120       print (vam->ofp,
2121              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2122              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2123              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2124              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2125              clib_net_to_host_u32 (mp->domain_index));
2126     }
2127   else
2128     {
2129       print (vam->ofp,
2130              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2131              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2132              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2133              format_ip6_address, mp->ip6_src,
2134              clib_net_to_host_u32 (mp->domain_index));
2135     }
2136   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2137          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2138          mp->is_translation ? "map-t" : "");
2139 }
2140
2141 static void vl_api_map_rule_details_t_handler_json
2142   (vl_api_map_rule_details_t * mp)
2143 {
2144   struct in6_addr ip6;
2145   vat_json_node_t *node = NULL;
2146   vat_main_t *vam = &vat_main;
2147
2148   if (VAT_JSON_ARRAY != vam->json_tree.type)
2149     {
2150       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2151       vat_json_init_array (&vam->json_tree);
2152     }
2153
2154   node = vat_json_array_add (&vam->json_tree);
2155   vat_json_init_object (node);
2156
2157   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2158   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2159   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2160 }
2161
2162 static void
2163 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2164 {
2165   vat_main_t *vam = &vat_main;
2166   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2167          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2168 }
2169
2170 static void
2171 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2172 {
2173   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2174           "router_addr %U host_mac %U",
2175           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2176           format_ip4_address, &mp->host_address,
2177           format_ip4_address, &mp->router_address,
2178           format_ethernet_address, mp->host_mac);
2179 }
2180
2181 static void vl_api_dhcp_compl_event_t_handler_json
2182   (vl_api_dhcp_compl_event_t * mp)
2183 {
2184   /* JSON output not supported */
2185 }
2186
2187 static void
2188 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2189                               u32 counter)
2190 {
2191   vat_main_t *vam = &vat_main;
2192   static u64 default_counter = 0;
2193
2194   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2195                            NULL);
2196   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2197                            sw_if_index, default_counter);
2198   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2199 }
2200
2201 static void
2202 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2203                                 interface_counter_t counter)
2204 {
2205   vat_main_t *vam = &vat_main;
2206   static interface_counter_t default_counter = { 0, };
2207
2208   vec_validate_init_empty (vam->combined_interface_counters,
2209                            vnet_counter_type, NULL);
2210   vec_validate_init_empty (vam->combined_interface_counters
2211                            [vnet_counter_type], sw_if_index, default_counter);
2212   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2213 }
2214
2215 static void vl_api_vnet_interface_simple_counters_t_handler
2216   (vl_api_vnet_interface_simple_counters_t * mp)
2217 {
2218   /* not supported */
2219 }
2220
2221 static void vl_api_vnet_interface_combined_counters_t_handler
2222   (vl_api_vnet_interface_combined_counters_t * mp)
2223 {
2224   /* not supported */
2225 }
2226
2227 static void vl_api_vnet_interface_simple_counters_t_handler_json
2228   (vl_api_vnet_interface_simple_counters_t * mp)
2229 {
2230   u64 *v_packets;
2231   u64 packets;
2232   u32 count;
2233   u32 first_sw_if_index;
2234   int i;
2235
2236   count = ntohl (mp->count);
2237   first_sw_if_index = ntohl (mp->first_sw_if_index);
2238
2239   v_packets = (u64 *) & mp->data;
2240   for (i = 0; i < count; i++)
2241     {
2242       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2243       set_simple_interface_counter (mp->vnet_counter_type,
2244                                     first_sw_if_index + i, packets);
2245       v_packets++;
2246     }
2247 }
2248
2249 static void vl_api_vnet_interface_combined_counters_t_handler_json
2250   (vl_api_vnet_interface_combined_counters_t * mp)
2251 {
2252   interface_counter_t counter;
2253   vlib_counter_t *v;
2254   u32 first_sw_if_index;
2255   int i;
2256   u32 count;
2257
2258   count = ntohl (mp->count);
2259   first_sw_if_index = ntohl (mp->first_sw_if_index);
2260
2261   v = (vlib_counter_t *) & mp->data;
2262   for (i = 0; i < count; i++)
2263     {
2264       counter.packets =
2265         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2266       counter.bytes =
2267         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2268       set_combined_interface_counter (mp->vnet_counter_type,
2269                                       first_sw_if_index + i, counter);
2270       v++;
2271     }
2272 }
2273
2274 static u32
2275 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2276 {
2277   vat_main_t *vam = &vat_main;
2278   u32 i;
2279
2280   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2281     {
2282       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2283         {
2284           return i;
2285         }
2286     }
2287   return ~0;
2288 }
2289
2290 static u32
2291 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2292 {
2293   vat_main_t *vam = &vat_main;
2294   u32 i;
2295
2296   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2297     {
2298       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2299         {
2300           return i;
2301         }
2302     }
2303   return ~0;
2304 }
2305
2306 static void vl_api_vnet_ip4_fib_counters_t_handler
2307   (vl_api_vnet_ip4_fib_counters_t * mp)
2308 {
2309   /* not supported */
2310 }
2311
2312 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2313   (vl_api_vnet_ip4_fib_counters_t * mp)
2314 {
2315   vat_main_t *vam = &vat_main;
2316   vl_api_ip4_fib_counter_t *v;
2317   ip4_fib_counter_t *counter;
2318   struct in_addr ip4;
2319   u32 vrf_id;
2320   u32 vrf_index;
2321   u32 count;
2322   int i;
2323
2324   vrf_id = ntohl (mp->vrf_id);
2325   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2326   if (~0 == vrf_index)
2327     {
2328       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2329       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2330       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2331       vec_validate (vam->ip4_fib_counters, vrf_index);
2332       vam->ip4_fib_counters[vrf_index] = NULL;
2333     }
2334
2335   vec_free (vam->ip4_fib_counters[vrf_index]);
2336   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2337   count = ntohl (mp->count);
2338   for (i = 0; i < count; i++)
2339     {
2340       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2341       counter = &vam->ip4_fib_counters[vrf_index][i];
2342       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2343       counter->address = ip4;
2344       counter->address_length = v->address_length;
2345       counter->packets = clib_net_to_host_u64 (v->packets);
2346       counter->bytes = clib_net_to_host_u64 (v->bytes);
2347       v++;
2348     }
2349 }
2350
2351 static void vl_api_vnet_ip4_nbr_counters_t_handler
2352   (vl_api_vnet_ip4_nbr_counters_t * mp)
2353 {
2354   /* not supported */
2355 }
2356
2357 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2358   (vl_api_vnet_ip4_nbr_counters_t * mp)
2359 {
2360   vat_main_t *vam = &vat_main;
2361   vl_api_ip4_nbr_counter_t *v;
2362   ip4_nbr_counter_t *counter;
2363   u32 sw_if_index;
2364   u32 count;
2365   int i;
2366
2367   sw_if_index = ntohl (mp->sw_if_index);
2368   count = ntohl (mp->count);
2369   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2370
2371   if (mp->begin)
2372     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2373
2374   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2375   for (i = 0; i < count; i++)
2376     {
2377       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2378       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2379       counter->address.s_addr = v->address;
2380       counter->packets = clib_net_to_host_u64 (v->packets);
2381       counter->bytes = clib_net_to_host_u64 (v->bytes);
2382       counter->linkt = v->link_type;
2383       v++;
2384     }
2385 }
2386
2387 static void vl_api_vnet_ip6_fib_counters_t_handler
2388   (vl_api_vnet_ip6_fib_counters_t * mp)
2389 {
2390   /* not supported */
2391 }
2392
2393 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2394   (vl_api_vnet_ip6_fib_counters_t * mp)
2395 {
2396   vat_main_t *vam = &vat_main;
2397   vl_api_ip6_fib_counter_t *v;
2398   ip6_fib_counter_t *counter;
2399   struct in6_addr ip6;
2400   u32 vrf_id;
2401   u32 vrf_index;
2402   u32 count;
2403   int i;
2404
2405   vrf_id = ntohl (mp->vrf_id);
2406   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2407   if (~0 == vrf_index)
2408     {
2409       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2410       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2411       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2412       vec_validate (vam->ip6_fib_counters, vrf_index);
2413       vam->ip6_fib_counters[vrf_index] = NULL;
2414     }
2415
2416   vec_free (vam->ip6_fib_counters[vrf_index]);
2417   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2418   count = ntohl (mp->count);
2419   for (i = 0; i < count; i++)
2420     {
2421       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2422       counter = &vam->ip6_fib_counters[vrf_index][i];
2423       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2424       counter->address = ip6;
2425       counter->address_length = v->address_length;
2426       counter->packets = clib_net_to_host_u64 (v->packets);
2427       counter->bytes = clib_net_to_host_u64 (v->bytes);
2428       v++;
2429     }
2430 }
2431
2432 static void vl_api_vnet_ip6_nbr_counters_t_handler
2433   (vl_api_vnet_ip6_nbr_counters_t * mp)
2434 {
2435   /* not supported */
2436 }
2437
2438 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2439   (vl_api_vnet_ip6_nbr_counters_t * mp)
2440 {
2441   vat_main_t *vam = &vat_main;
2442   vl_api_ip6_nbr_counter_t *v;
2443   ip6_nbr_counter_t *counter;
2444   struct in6_addr ip6;
2445   u32 sw_if_index;
2446   u32 count;
2447   int i;
2448
2449   sw_if_index = ntohl (mp->sw_if_index);
2450   count = ntohl (mp->count);
2451   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2452
2453   if (mp->begin)
2454     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2455
2456   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2457   for (i = 0; i < count; i++)
2458     {
2459       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2460       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2461       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2462       counter->address = ip6;
2463       counter->packets = clib_net_to_host_u64 (v->packets);
2464       counter->bytes = clib_net_to_host_u64 (v->bytes);
2465       v++;
2466     }
2467 }
2468
2469 static void vl_api_get_first_msg_id_reply_t_handler
2470   (vl_api_get_first_msg_id_reply_t * mp)
2471 {
2472   vat_main_t *vam = &vat_main;
2473   i32 retval = ntohl (mp->retval);
2474
2475   if (vam->async_mode)
2476     {
2477       vam->async_errors += (retval < 0);
2478     }
2479   else
2480     {
2481       vam->retval = retval;
2482       vam->result_ready = 1;
2483     }
2484   if (retval >= 0)
2485     {
2486       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2487     }
2488 }
2489
2490 static void vl_api_get_first_msg_id_reply_t_handler_json
2491   (vl_api_get_first_msg_id_reply_t * mp)
2492 {
2493   vat_main_t *vam = &vat_main;
2494   vat_json_node_t node;
2495
2496   vat_json_init_object (&node);
2497   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2498   vat_json_object_add_uint (&node, "first_msg_id",
2499                             (uint) ntohs (mp->first_msg_id));
2500
2501   vat_json_print (vam->ofp, &node);
2502   vat_json_free (&node);
2503
2504   vam->retval = ntohl (mp->retval);
2505   vam->result_ready = 1;
2506 }
2507
2508 static void vl_api_get_node_graph_reply_t_handler
2509   (vl_api_get_node_graph_reply_t * mp)
2510 {
2511   vat_main_t *vam = &vat_main;
2512   api_main_t *am = &api_main;
2513   i32 retval = ntohl (mp->retval);
2514   u8 *pvt_copy, *reply;
2515   void *oldheap;
2516   vlib_node_t *node;
2517   int i;
2518
2519   if (vam->async_mode)
2520     {
2521       vam->async_errors += (retval < 0);
2522     }
2523   else
2524     {
2525       vam->retval = retval;
2526       vam->result_ready = 1;
2527     }
2528
2529   /* "Should never happen..." */
2530   if (retval != 0)
2531     return;
2532
2533   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2534   pvt_copy = vec_dup (reply);
2535
2536   /* Toss the shared-memory original... */
2537   pthread_mutex_lock (&am->vlib_rp->mutex);
2538   oldheap = svm_push_data_heap (am->vlib_rp);
2539
2540   vec_free (reply);
2541
2542   svm_pop_heap (oldheap);
2543   pthread_mutex_unlock (&am->vlib_rp->mutex);
2544
2545   if (vam->graph_nodes)
2546     {
2547       hash_free (vam->graph_node_index_by_name);
2548
2549       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2550         {
2551           node = vam->graph_nodes[i];
2552           vec_free (node->name);
2553           vec_free (node->next_nodes);
2554           vec_free (node);
2555         }
2556       vec_free (vam->graph_nodes);
2557     }
2558
2559   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2560   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2561   vec_free (pvt_copy);
2562
2563   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2564     {
2565       node = vam->graph_nodes[i];
2566       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2567     }
2568 }
2569
2570 static void vl_api_get_node_graph_reply_t_handler_json
2571   (vl_api_get_node_graph_reply_t * mp)
2572 {
2573   vat_main_t *vam = &vat_main;
2574   api_main_t *am = &api_main;
2575   void *oldheap;
2576   vat_json_node_t node;
2577   u8 *reply;
2578
2579   /* $$$$ make this real? */
2580   vat_json_init_object (&node);
2581   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2582   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2583
2584   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2585
2586   /* Toss the shared-memory original... */
2587   pthread_mutex_lock (&am->vlib_rp->mutex);
2588   oldheap = svm_push_data_heap (am->vlib_rp);
2589
2590   vec_free (reply);
2591
2592   svm_pop_heap (oldheap);
2593   pthread_mutex_unlock (&am->vlib_rp->mutex);
2594
2595   vat_json_print (vam->ofp, &node);
2596   vat_json_free (&node);
2597
2598   vam->retval = ntohl (mp->retval);
2599   vam->result_ready = 1;
2600 }
2601
2602 static void
2603 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2604 {
2605   vat_main_t *vam = &vat_main;
2606   u8 *s = 0;
2607
2608   if (mp->local)
2609     {
2610       s = format (s, "%=16d%=16d%=16d",
2611                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2612     }
2613   else
2614     {
2615       s = format (s, "%=16U%=16d%=16d",
2616                   mp->is_ipv6 ? format_ip6_address :
2617                   format_ip4_address,
2618                   mp->ip_address, mp->priority, mp->weight);
2619     }
2620
2621   print (vam->ofp, "%v", s);
2622   vec_free (s);
2623 }
2624
2625 static void
2626 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2627 {
2628   vat_main_t *vam = &vat_main;
2629   vat_json_node_t *node = NULL;
2630   struct in6_addr ip6;
2631   struct in_addr ip4;
2632
2633   if (VAT_JSON_ARRAY != vam->json_tree.type)
2634     {
2635       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2636       vat_json_init_array (&vam->json_tree);
2637     }
2638   node = vat_json_array_add (&vam->json_tree);
2639   vat_json_init_object (node);
2640
2641   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2642   vat_json_object_add_uint (node, "priority", mp->priority);
2643   vat_json_object_add_uint (node, "weight", mp->weight);
2644
2645   if (mp->local)
2646     vat_json_object_add_uint (node, "sw_if_index",
2647                               clib_net_to_host_u32 (mp->sw_if_index));
2648   else
2649     {
2650       if (mp->is_ipv6)
2651         {
2652           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2653           vat_json_object_add_ip6 (node, "address", ip6);
2654         }
2655       else
2656         {
2657           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2658           vat_json_object_add_ip4 (node, "address", ip4);
2659         }
2660     }
2661 }
2662
2663 static void
2664 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2665                                           mp)
2666 {
2667   vat_main_t *vam = &vat_main;
2668   u8 *ls_name = 0;
2669
2670   ls_name = format (0, "%s", mp->ls_name);
2671
2672   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2673          ls_name);
2674   vec_free (ls_name);
2675 }
2676
2677 static void
2678   vl_api_one_locator_set_details_t_handler_json
2679   (vl_api_one_locator_set_details_t * mp)
2680 {
2681   vat_main_t *vam = &vat_main;
2682   vat_json_node_t *node = 0;
2683   u8 *ls_name = 0;
2684
2685   ls_name = format (0, "%s", mp->ls_name);
2686   vec_add1 (ls_name, 0);
2687
2688   if (VAT_JSON_ARRAY != vam->json_tree.type)
2689     {
2690       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2691       vat_json_init_array (&vam->json_tree);
2692     }
2693   node = vat_json_array_add (&vam->json_tree);
2694
2695   vat_json_init_object (node);
2696   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2697   vat_json_object_add_uint (node, "ls_index",
2698                             clib_net_to_host_u32 (mp->ls_index));
2699   vec_free (ls_name);
2700 }
2701
2702 typedef struct
2703 {
2704   u32 spi;
2705   u8 si;
2706 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2707
2708 uword
2709 unformat_nsh_address (unformat_input_t * input, va_list * args)
2710 {
2711   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2712   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2713 }
2714
2715 u8 *
2716 format_nsh_address_vat (u8 * s, va_list * args)
2717 {
2718   nsh_t *a = va_arg (*args, nsh_t *);
2719   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2720 }
2721
2722 static u8 *
2723 format_lisp_flat_eid (u8 * s, va_list * args)
2724 {
2725   u32 type = va_arg (*args, u32);
2726   u8 *eid = va_arg (*args, u8 *);
2727   u32 eid_len = va_arg (*args, u32);
2728
2729   switch (type)
2730     {
2731     case 0:
2732       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2733     case 1:
2734       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2735     case 2:
2736       return format (s, "%U", format_ethernet_address, eid);
2737     case 3:
2738       return format (s, "%U", format_nsh_address_vat, eid);
2739     }
2740   return 0;
2741 }
2742
2743 static u8 *
2744 format_lisp_eid_vat (u8 * s, va_list * args)
2745 {
2746   u32 type = va_arg (*args, u32);
2747   u8 *eid = va_arg (*args, u8 *);
2748   u32 eid_len = va_arg (*args, u32);
2749   u8 *seid = va_arg (*args, u8 *);
2750   u32 seid_len = va_arg (*args, u32);
2751   u32 is_src_dst = va_arg (*args, u32);
2752
2753   if (is_src_dst)
2754     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2755
2756   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2757
2758   return s;
2759 }
2760
2761 static void
2762 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2763 {
2764   vat_main_t *vam = &vat_main;
2765   u8 *s = 0, *eid = 0;
2766
2767   if (~0 == mp->locator_set_index)
2768     s = format (0, "action: %d", mp->action);
2769   else
2770     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2771
2772   eid = format (0, "%U", format_lisp_eid_vat,
2773                 mp->eid_type,
2774                 mp->eid,
2775                 mp->eid_prefix_len,
2776                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2777   vec_add1 (eid, 0);
2778
2779   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2780          clib_net_to_host_u32 (mp->vni),
2781          eid,
2782          mp->is_local ? "local" : "remote",
2783          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2784          clib_net_to_host_u16 (mp->key_id), mp->key);
2785
2786   vec_free (s);
2787   vec_free (eid);
2788 }
2789
2790 static void
2791 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2792                                              * mp)
2793 {
2794   vat_main_t *vam = &vat_main;
2795   vat_json_node_t *node = 0;
2796   u8 *eid = 0;
2797
2798   if (VAT_JSON_ARRAY != vam->json_tree.type)
2799     {
2800       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2801       vat_json_init_array (&vam->json_tree);
2802     }
2803   node = vat_json_array_add (&vam->json_tree);
2804
2805   vat_json_init_object (node);
2806   if (~0 == mp->locator_set_index)
2807     vat_json_object_add_uint (node, "action", mp->action);
2808   else
2809     vat_json_object_add_uint (node, "locator_set_index",
2810                               clib_net_to_host_u32 (mp->locator_set_index));
2811
2812   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2813   if (mp->eid_type == 3)
2814     {
2815       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
2816       vat_json_init_object (nsh_json);
2817       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
2818       vat_json_object_add_uint (nsh_json, "spi",
2819                                 clib_net_to_host_u32 (nsh->spi));
2820       vat_json_object_add_uint (nsh_json, "si", nsh->si);
2821     }
2822   else
2823     {
2824       eid = format (0, "%U", format_lisp_eid_vat,
2825                     mp->eid_type,
2826                     mp->eid,
2827                     mp->eid_prefix_len,
2828                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2829       vec_add1 (eid, 0);
2830       vat_json_object_add_string_copy (node, "eid", eid);
2831       vec_free (eid);
2832     }
2833   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2834   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2835   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2836
2837   if (mp->key_id)
2838     {
2839       vat_json_object_add_uint (node, "key_id",
2840                                 clib_net_to_host_u16 (mp->key_id));
2841       vat_json_object_add_string_copy (node, "key", mp->key);
2842     }
2843 }
2844
2845 static void
2846 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
2847 {
2848   vat_main_t *vam = &vat_main;
2849   u8 *seid = 0, *deid = 0;
2850   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2851
2852   deid = format (0, "%U", format_lisp_eid_vat,
2853                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2854
2855   seid = format (0, "%U", format_lisp_eid_vat,
2856                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2857
2858   vec_add1 (deid, 0);
2859   vec_add1 (seid, 0);
2860
2861   if (mp->is_ip4)
2862     format_ip_address_fcn = format_ip4_address;
2863   else
2864     format_ip_address_fcn = format_ip6_address;
2865
2866
2867   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
2868          clib_net_to_host_u32 (mp->vni),
2869          seid, deid,
2870          format_ip_address_fcn, mp->lloc,
2871          format_ip_address_fcn, mp->rloc,
2872          clib_net_to_host_u32 (mp->pkt_count),
2873          clib_net_to_host_u32 (mp->bytes));
2874
2875   vec_free (deid);
2876   vec_free (seid);
2877 }
2878
2879 static void
2880 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
2881 {
2882   struct in6_addr ip6;
2883   struct in_addr ip4;
2884   vat_main_t *vam = &vat_main;
2885   vat_json_node_t *node = 0;
2886   u8 *deid = 0, *seid = 0;
2887
2888   if (VAT_JSON_ARRAY != vam->json_tree.type)
2889     {
2890       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2891       vat_json_init_array (&vam->json_tree);
2892     }
2893   node = vat_json_array_add (&vam->json_tree);
2894
2895   vat_json_init_object (node);
2896   deid = format (0, "%U", format_lisp_eid_vat,
2897                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2898
2899   seid = format (0, "%U", format_lisp_eid_vat,
2900                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2901
2902   vec_add1 (deid, 0);
2903   vec_add1 (seid, 0);
2904
2905   vat_json_object_add_string_copy (node, "seid", seid);
2906   vat_json_object_add_string_copy (node, "deid", deid);
2907   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2908
2909   if (mp->is_ip4)
2910     {
2911       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
2912       vat_json_object_add_ip4 (node, "lloc", ip4);
2913       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
2914       vat_json_object_add_ip4 (node, "rloc", ip4);
2915     }
2916   else
2917     {
2918       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
2919       vat_json_object_add_ip6 (node, "lloc", ip6);
2920       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
2921       vat_json_object_add_ip6 (node, "rloc", ip6);
2922     }
2923   vat_json_object_add_uint (node, "pkt_count",
2924                             clib_net_to_host_u32 (mp->pkt_count));
2925   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
2926
2927   vec_free (deid);
2928   vec_free (seid);
2929 }
2930
2931 static void
2932   vl_api_one_eid_table_map_details_t_handler
2933   (vl_api_one_eid_table_map_details_t * mp)
2934 {
2935   vat_main_t *vam = &vat_main;
2936
2937   u8 *line = format (0, "%=10d%=10d",
2938                      clib_net_to_host_u32 (mp->vni),
2939                      clib_net_to_host_u32 (mp->dp_table));
2940   print (vam->ofp, "%v", line);
2941   vec_free (line);
2942 }
2943
2944 static void
2945   vl_api_one_eid_table_map_details_t_handler_json
2946   (vl_api_one_eid_table_map_details_t * mp)
2947 {
2948   vat_main_t *vam = &vat_main;
2949   vat_json_node_t *node = NULL;
2950
2951   if (VAT_JSON_ARRAY != vam->json_tree.type)
2952     {
2953       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2954       vat_json_init_array (&vam->json_tree);
2955     }
2956   node = vat_json_array_add (&vam->json_tree);
2957   vat_json_init_object (node);
2958   vat_json_object_add_uint (node, "dp_table",
2959                             clib_net_to_host_u32 (mp->dp_table));
2960   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2961 }
2962
2963 static void
2964   vl_api_one_eid_table_vni_details_t_handler
2965   (vl_api_one_eid_table_vni_details_t * mp)
2966 {
2967   vat_main_t *vam = &vat_main;
2968
2969   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2970   print (vam->ofp, "%v", line);
2971   vec_free (line);
2972 }
2973
2974 static void
2975   vl_api_one_eid_table_vni_details_t_handler_json
2976   (vl_api_one_eid_table_vni_details_t * mp)
2977 {
2978   vat_main_t *vam = &vat_main;
2979   vat_json_node_t *node = NULL;
2980
2981   if (VAT_JSON_ARRAY != vam->json_tree.type)
2982     {
2983       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2984       vat_json_init_array (&vam->json_tree);
2985     }
2986   node = vat_json_array_add (&vam->json_tree);
2987   vat_json_init_object (node);
2988   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2989 }
2990
2991 static void
2992   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
2993   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
2994 {
2995   vat_main_t *vam = &vat_main;
2996   int retval = clib_net_to_host_u32 (mp->retval);
2997
2998   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
2999   print (vam->ofp, "fallback threshold value: %d", mp->value);
3000
3001   vam->retval = retval;
3002   vam->result_ready = 1;
3003 }
3004
3005 static void
3006   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3007   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3008 {
3009   vat_main_t *vam = &vat_main;
3010   vat_json_node_t _node, *node = &_node;
3011   int retval = clib_net_to_host_u32 (mp->retval);
3012
3013   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3014   vat_json_init_object (node);
3015   vat_json_object_add_uint (node, "value", mp->value);
3016
3017   vat_json_print (vam->ofp, node);
3018   vat_json_free (node);
3019
3020   vam->retval = retval;
3021   vam->result_ready = 1;
3022 }
3023
3024 static void
3025   vl_api_show_one_map_register_state_reply_t_handler
3026   (vl_api_show_one_map_register_state_reply_t * mp)
3027 {
3028   vat_main_t *vam = &vat_main;
3029   int retval = clib_net_to_host_u32 (mp->retval);
3030
3031   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3032
3033   vam->retval = retval;
3034   vam->result_ready = 1;
3035 }
3036
3037 static void
3038   vl_api_show_one_map_register_state_reply_t_handler_json
3039   (vl_api_show_one_map_register_state_reply_t * mp)
3040 {
3041   vat_main_t *vam = &vat_main;
3042   vat_json_node_t _node, *node = &_node;
3043   int retval = clib_net_to_host_u32 (mp->retval);
3044
3045   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3046
3047   vat_json_init_object (node);
3048   vat_json_object_add_string_copy (node, "state", s);
3049
3050   vat_json_print (vam->ofp, node);
3051   vat_json_free (node);
3052
3053   vam->retval = retval;
3054   vam->result_ready = 1;
3055   vec_free (s);
3056 }
3057
3058 static void
3059   vl_api_show_one_rloc_probe_state_reply_t_handler
3060   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3061 {
3062   vat_main_t *vam = &vat_main;
3063   int retval = clib_net_to_host_u32 (mp->retval);
3064
3065   if (retval)
3066     goto end;
3067
3068   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3069 end:
3070   vam->retval = retval;
3071   vam->result_ready = 1;
3072 }
3073
3074 static void
3075   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3076   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3077 {
3078   vat_main_t *vam = &vat_main;
3079   vat_json_node_t _node, *node = &_node;
3080   int retval = clib_net_to_host_u32 (mp->retval);
3081
3082   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3083   vat_json_init_object (node);
3084   vat_json_object_add_string_copy (node, "state", s);
3085
3086   vat_json_print (vam->ofp, node);
3087   vat_json_free (node);
3088
3089   vam->retval = retval;
3090   vam->result_ready = 1;
3091   vec_free (s);
3092 }
3093
3094 static void
3095   vl_api_show_one_stats_enable_disable_reply_t_handler
3096   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3097 {
3098   vat_main_t *vam = &vat_main;
3099   int retval = clib_net_to_host_u32 (mp->retval);
3100
3101   if (retval)
3102     goto end;
3103
3104   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3105 end:
3106   vam->retval = retval;
3107   vam->result_ready = 1;
3108 }
3109
3110 static void
3111   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3112   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3113 {
3114   vat_main_t *vam = &vat_main;
3115   vat_json_node_t _node, *node = &_node;
3116   int retval = clib_net_to_host_u32 (mp->retval);
3117
3118   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3119   vat_json_init_object (node);
3120   vat_json_object_add_string_copy (node, "state", s);
3121
3122   vat_json_print (vam->ofp, node);
3123   vat_json_free (node);
3124
3125   vam->retval = retval;
3126   vam->result_ready = 1;
3127   vec_free (s);
3128 }
3129
3130 static void
3131 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3132 {
3133   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3134   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3135   e->vni = clib_net_to_host_u32 (e->vni);
3136 }
3137
3138 static void
3139   gpe_fwd_entries_get_reply_t_net_to_host
3140   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3141 {
3142   u32 i;
3143
3144   mp->count = clib_net_to_host_u32 (mp->count);
3145   for (i = 0; i < mp->count; i++)
3146     {
3147       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3148     }
3149 }
3150
3151 static u8 *
3152 format_gpe_encap_mode (u8 * s, va_list * args)
3153 {
3154   u32 mode = va_arg (*args, u32);
3155
3156   switch (mode)
3157     {
3158     case 0:
3159       return format (s, "lisp");
3160     case 1:
3161       return format (s, "vxlan");
3162     }
3163   return 0;
3164 }
3165
3166 static void
3167   vl_api_gpe_get_encap_mode_reply_t_handler
3168   (vl_api_gpe_get_encap_mode_reply_t * mp)
3169 {
3170   vat_main_t *vam = &vat_main;
3171
3172   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3173   vam->retval = ntohl (mp->retval);
3174   vam->result_ready = 1;
3175 }
3176
3177 static void
3178   vl_api_gpe_get_encap_mode_reply_t_handler_json
3179   (vl_api_gpe_get_encap_mode_reply_t * mp)
3180 {
3181   vat_main_t *vam = &vat_main;
3182   vat_json_node_t node;
3183
3184   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3185   vec_add1 (encap_mode, 0);
3186
3187   vat_json_init_object (&node);
3188   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3189
3190   vec_free (encap_mode);
3191   vat_json_print (vam->ofp, &node);
3192   vat_json_free (&node);
3193
3194   vam->retval = ntohl (mp->retval);
3195   vam->result_ready = 1;
3196 }
3197
3198 static void
3199   vl_api_gpe_fwd_entry_path_details_t_handler
3200   (vl_api_gpe_fwd_entry_path_details_t * mp)
3201 {
3202   vat_main_t *vam = &vat_main;
3203   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3204
3205   if (mp->lcl_loc.is_ip4)
3206     format_ip_address_fcn = format_ip4_address;
3207   else
3208     format_ip_address_fcn = format_ip6_address;
3209
3210   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3211          format_ip_address_fcn, &mp->lcl_loc,
3212          format_ip_address_fcn, &mp->rmt_loc);
3213 }
3214
3215 static void
3216 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3217 {
3218   struct in6_addr ip6;
3219   struct in_addr ip4;
3220
3221   if (loc->is_ip4)
3222     {
3223       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3224       vat_json_object_add_ip4 (n, "address", ip4);
3225     }
3226   else
3227     {
3228       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3229       vat_json_object_add_ip6 (n, "address", ip6);
3230     }
3231   vat_json_object_add_uint (n, "weight", loc->weight);
3232 }
3233
3234 static void
3235   vl_api_gpe_fwd_entry_path_details_t_handler_json
3236   (vl_api_gpe_fwd_entry_path_details_t * mp)
3237 {
3238   vat_main_t *vam = &vat_main;
3239   vat_json_node_t *node = NULL;
3240   vat_json_node_t *loc_node;
3241
3242   if (VAT_JSON_ARRAY != vam->json_tree.type)
3243     {
3244       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3245       vat_json_init_array (&vam->json_tree);
3246     }
3247   node = vat_json_array_add (&vam->json_tree);
3248   vat_json_init_object (node);
3249
3250   loc_node = vat_json_object_add (node, "local_locator");
3251   vat_json_init_object (loc_node);
3252   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3253
3254   loc_node = vat_json_object_add (node, "remote_locator");
3255   vat_json_init_object (loc_node);
3256   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3257 }
3258
3259 static void
3260   vl_api_gpe_fwd_entries_get_reply_t_handler
3261   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3262 {
3263   vat_main_t *vam = &vat_main;
3264   u32 i;
3265   int retval = clib_net_to_host_u32 (mp->retval);
3266   vl_api_gpe_fwd_entry_t *e;
3267
3268   if (retval)
3269     goto end;
3270
3271   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3272
3273   for (i = 0; i < mp->count; i++)
3274     {
3275       e = &mp->entries[i];
3276       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3277              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3278              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3279     }
3280
3281 end:
3282   vam->retval = retval;
3283   vam->result_ready = 1;
3284 }
3285
3286 static void
3287   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3288   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3289 {
3290   u8 *s = 0;
3291   vat_main_t *vam = &vat_main;
3292   vat_json_node_t *e = 0, root;
3293   u32 i;
3294   int retval = clib_net_to_host_u32 (mp->retval);
3295   vl_api_gpe_fwd_entry_t *fwd;
3296
3297   if (retval)
3298     goto end;
3299
3300   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3301   vat_json_init_array (&root);
3302
3303   for (i = 0; i < mp->count; i++)
3304     {
3305       e = vat_json_array_add (&root);
3306       fwd = &mp->entries[i];
3307
3308       vat_json_init_object (e);
3309       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3310       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3311       vat_json_object_add_int (e, "vni", fwd->vni);
3312       vat_json_object_add_int (e, "action", fwd->action);
3313
3314       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3315                   fwd->leid_prefix_len);
3316       vec_add1 (s, 0);
3317       vat_json_object_add_string_copy (e, "leid", s);
3318       vec_free (s);
3319
3320       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3321                   fwd->reid_prefix_len);
3322       vec_add1 (s, 0);
3323       vat_json_object_add_string_copy (e, "reid", s);
3324       vec_free (s);
3325     }
3326
3327   vat_json_print (vam->ofp, &root);
3328   vat_json_free (&root);
3329
3330 end:
3331   vam->retval = retval;
3332   vam->result_ready = 1;
3333 }
3334
3335 static void
3336   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3337   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3338 {
3339   vat_main_t *vam = &vat_main;
3340   u32 i, n;
3341   int retval = clib_net_to_host_u32 (mp->retval);
3342   vl_api_gpe_native_fwd_rpath_t *r;
3343
3344   if (retval)
3345     goto end;
3346
3347   n = clib_net_to_host_u32 (mp->count);
3348
3349   for (i = 0; i < n; i++)
3350     {
3351       r = &mp->entries[i];
3352       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3353              clib_net_to_host_u32 (r->fib_index),
3354              clib_net_to_host_u32 (r->nh_sw_if_index),
3355              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3356     }
3357
3358 end:
3359   vam->retval = retval;
3360   vam->result_ready = 1;
3361 }
3362
3363 static void
3364   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3365   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3366 {
3367   vat_main_t *vam = &vat_main;
3368   vat_json_node_t root, *e;
3369   u32 i, n;
3370   int retval = clib_net_to_host_u32 (mp->retval);
3371   vl_api_gpe_native_fwd_rpath_t *r;
3372   u8 *s;
3373
3374   if (retval)
3375     goto end;
3376
3377   n = clib_net_to_host_u32 (mp->count);
3378   vat_json_init_array (&root);
3379
3380   for (i = 0; i < n; i++)
3381     {
3382       e = vat_json_array_add (&root);
3383       vat_json_init_object (e);
3384       r = &mp->entries[i];
3385       s =
3386         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3387                 r->nh_addr);
3388       vec_add1 (s, 0);
3389       vat_json_object_add_string_copy (e, "ip4", s);
3390       vec_free (s);
3391
3392       vat_json_object_add_uint (e, "fib_index",
3393                                 clib_net_to_host_u32 (r->fib_index));
3394       vat_json_object_add_uint (e, "nh_sw_if_index",
3395                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3396     }
3397
3398   vat_json_print (vam->ofp, &root);
3399   vat_json_free (&root);
3400
3401 end:
3402   vam->retval = retval;
3403   vam->result_ready = 1;
3404 }
3405
3406 static void
3407   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3408   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3409 {
3410   vat_main_t *vam = &vat_main;
3411   u32 i, n;
3412   int retval = clib_net_to_host_u32 (mp->retval);
3413
3414   if (retval)
3415     goto end;
3416
3417   n = clib_net_to_host_u32 (mp->count);
3418
3419   for (i = 0; i < n; i++)
3420     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3421
3422 end:
3423   vam->retval = retval;
3424   vam->result_ready = 1;
3425 }
3426
3427 static void
3428   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3429   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3430 {
3431   vat_main_t *vam = &vat_main;
3432   vat_json_node_t root;
3433   u32 i, n;
3434   int retval = clib_net_to_host_u32 (mp->retval);
3435
3436   if (retval)
3437     goto end;
3438
3439   n = clib_net_to_host_u32 (mp->count);
3440   vat_json_init_array (&root);
3441
3442   for (i = 0; i < n; i++)
3443     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3444
3445   vat_json_print (vam->ofp, &root);
3446   vat_json_free (&root);
3447
3448 end:
3449   vam->retval = retval;
3450   vam->result_ready = 1;
3451 }
3452
3453 static void
3454   vl_api_one_ndp_entries_get_reply_t_handler
3455   (vl_api_one_ndp_entries_get_reply_t * mp)
3456 {
3457   vat_main_t *vam = &vat_main;
3458   u32 i, n;
3459   int retval = clib_net_to_host_u32 (mp->retval);
3460
3461   if (retval)
3462     goto end;
3463
3464   n = clib_net_to_host_u32 (mp->count);
3465
3466   for (i = 0; i < n; i++)
3467     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3468            format_ethernet_address, mp->entries[i].mac);
3469
3470 end:
3471   vam->retval = retval;
3472   vam->result_ready = 1;
3473 }
3474
3475 static void
3476   vl_api_one_ndp_entries_get_reply_t_handler_json
3477   (vl_api_one_ndp_entries_get_reply_t * mp)
3478 {
3479   u8 *s = 0;
3480   vat_main_t *vam = &vat_main;
3481   vat_json_node_t *e = 0, root;
3482   u32 i, n;
3483   int retval = clib_net_to_host_u32 (mp->retval);
3484   vl_api_one_ndp_entry_t *arp_entry;
3485
3486   if (retval)
3487     goto end;
3488
3489   n = clib_net_to_host_u32 (mp->count);
3490   vat_json_init_array (&root);
3491
3492   for (i = 0; i < n; i++)
3493     {
3494       e = vat_json_array_add (&root);
3495       arp_entry = &mp->entries[i];
3496
3497       vat_json_init_object (e);
3498       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3499       vec_add1 (s, 0);
3500
3501       vat_json_object_add_string_copy (e, "mac", s);
3502       vec_free (s);
3503
3504       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3505       vec_add1 (s, 0);
3506       vat_json_object_add_string_copy (e, "ip6", s);
3507       vec_free (s);
3508     }
3509
3510   vat_json_print (vam->ofp, &root);
3511   vat_json_free (&root);
3512
3513 end:
3514   vam->retval = retval;
3515   vam->result_ready = 1;
3516 }
3517
3518 static void
3519   vl_api_one_l2_arp_entries_get_reply_t_handler
3520   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3521 {
3522   vat_main_t *vam = &vat_main;
3523   u32 i, n;
3524   int retval = clib_net_to_host_u32 (mp->retval);
3525
3526   if (retval)
3527     goto end;
3528
3529   n = clib_net_to_host_u32 (mp->count);
3530
3531   for (i = 0; i < n; i++)
3532     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3533            format_ethernet_address, mp->entries[i].mac);
3534
3535 end:
3536   vam->retval = retval;
3537   vam->result_ready = 1;
3538 }
3539
3540 static void
3541   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3542   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3543 {
3544   u8 *s = 0;
3545   vat_main_t *vam = &vat_main;
3546   vat_json_node_t *e = 0, root;
3547   u32 i, n;
3548   int retval = clib_net_to_host_u32 (mp->retval);
3549   vl_api_one_l2_arp_entry_t *arp_entry;
3550
3551   if (retval)
3552     goto end;
3553
3554   n = clib_net_to_host_u32 (mp->count);
3555   vat_json_init_array (&root);
3556
3557   for (i = 0; i < n; i++)
3558     {
3559       e = vat_json_array_add (&root);
3560       arp_entry = &mp->entries[i];
3561
3562       vat_json_init_object (e);
3563       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3564       vec_add1 (s, 0);
3565
3566       vat_json_object_add_string_copy (e, "mac", s);
3567       vec_free (s);
3568
3569       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3570       vec_add1 (s, 0);
3571       vat_json_object_add_string_copy (e, "ip4", s);
3572       vec_free (s);
3573     }
3574
3575   vat_json_print (vam->ofp, &root);
3576   vat_json_free (&root);
3577
3578 end:
3579   vam->retval = retval;
3580   vam->result_ready = 1;
3581 }
3582
3583 static void
3584 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3585 {
3586   vat_main_t *vam = &vat_main;
3587   u32 i, n;
3588   int retval = clib_net_to_host_u32 (mp->retval);
3589
3590   if (retval)
3591     goto end;
3592
3593   n = clib_net_to_host_u32 (mp->count);
3594
3595   for (i = 0; i < n; i++)
3596     {
3597       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3598     }
3599
3600 end:
3601   vam->retval = retval;
3602   vam->result_ready = 1;
3603 }
3604
3605 static void
3606   vl_api_one_ndp_bd_get_reply_t_handler_json
3607   (vl_api_one_ndp_bd_get_reply_t * mp)
3608 {
3609   vat_main_t *vam = &vat_main;
3610   vat_json_node_t root;
3611   u32 i, n;
3612   int retval = clib_net_to_host_u32 (mp->retval);
3613
3614   if (retval)
3615     goto end;
3616
3617   n = clib_net_to_host_u32 (mp->count);
3618   vat_json_init_array (&root);
3619
3620   for (i = 0; i < n; i++)
3621     {
3622       vat_json_array_add_uint (&root,
3623                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3624     }
3625
3626   vat_json_print (vam->ofp, &root);
3627   vat_json_free (&root);
3628
3629 end:
3630   vam->retval = retval;
3631   vam->result_ready = 1;
3632 }
3633
3634 static void
3635   vl_api_one_l2_arp_bd_get_reply_t_handler
3636   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3637 {
3638   vat_main_t *vam = &vat_main;
3639   u32 i, n;
3640   int retval = clib_net_to_host_u32 (mp->retval);
3641
3642   if (retval)
3643     goto end;
3644
3645   n = clib_net_to_host_u32 (mp->count);
3646
3647   for (i = 0; i < n; i++)
3648     {
3649       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3650     }
3651
3652 end:
3653   vam->retval = retval;
3654   vam->result_ready = 1;
3655 }
3656
3657 static void
3658   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3659   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3660 {
3661   vat_main_t *vam = &vat_main;
3662   vat_json_node_t root;
3663   u32 i, n;
3664   int retval = clib_net_to_host_u32 (mp->retval);
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       vat_json_array_add_uint (&root,
3675                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3676     }
3677
3678   vat_json_print (vam->ofp, &root);
3679   vat_json_free (&root);
3680
3681 end:
3682   vam->retval = retval;
3683   vam->result_ready = 1;
3684 }
3685
3686 static void
3687   vl_api_one_adjacencies_get_reply_t_handler
3688   (vl_api_one_adjacencies_get_reply_t * mp)
3689 {
3690   vat_main_t *vam = &vat_main;
3691   u32 i, n;
3692   int retval = clib_net_to_host_u32 (mp->retval);
3693   vl_api_one_adjacency_t *a;
3694
3695   if (retval)
3696     goto end;
3697
3698   n = clib_net_to_host_u32 (mp->count);
3699
3700   for (i = 0; i < n; i++)
3701     {
3702       a = &mp->adjacencies[i];
3703       print (vam->ofp, "%U %40U",
3704              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3705              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3706     }
3707
3708 end:
3709   vam->retval = retval;
3710   vam->result_ready = 1;
3711 }
3712
3713 static void
3714   vl_api_one_adjacencies_get_reply_t_handler_json
3715   (vl_api_one_adjacencies_get_reply_t * mp)
3716 {
3717   u8 *s = 0;
3718   vat_main_t *vam = &vat_main;
3719   vat_json_node_t *e = 0, root;
3720   u32 i, n;
3721   int retval = clib_net_to_host_u32 (mp->retval);
3722   vl_api_one_adjacency_t *a;
3723
3724   if (retval)
3725     goto end;
3726
3727   n = clib_net_to_host_u32 (mp->count);
3728   vat_json_init_array (&root);
3729
3730   for (i = 0; i < n; i++)
3731     {
3732       e = vat_json_array_add (&root);
3733       a = &mp->adjacencies[i];
3734
3735       vat_json_init_object (e);
3736       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3737                   a->leid_prefix_len);
3738       vec_add1 (s, 0);
3739       vat_json_object_add_string_copy (e, "leid", s);
3740       vec_free (s);
3741
3742       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3743                   a->reid_prefix_len);
3744       vec_add1 (s, 0);
3745       vat_json_object_add_string_copy (e, "reid", s);
3746       vec_free (s);
3747     }
3748
3749   vat_json_print (vam->ofp, &root);
3750   vat_json_free (&root);
3751
3752 end:
3753   vam->retval = retval;
3754   vam->result_ready = 1;
3755 }
3756
3757 static void
3758 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3759 {
3760   vat_main_t *vam = &vat_main;
3761
3762   print (vam->ofp, "%=20U",
3763          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3764          mp->ip_address);
3765 }
3766
3767 static void
3768   vl_api_one_map_server_details_t_handler_json
3769   (vl_api_one_map_server_details_t * mp)
3770 {
3771   vat_main_t *vam = &vat_main;
3772   vat_json_node_t *node = NULL;
3773   struct in6_addr ip6;
3774   struct in_addr ip4;
3775
3776   if (VAT_JSON_ARRAY != vam->json_tree.type)
3777     {
3778       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3779       vat_json_init_array (&vam->json_tree);
3780     }
3781   node = vat_json_array_add (&vam->json_tree);
3782
3783   vat_json_init_object (node);
3784   if (mp->is_ipv6)
3785     {
3786       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3787       vat_json_object_add_ip6 (node, "map-server", ip6);
3788     }
3789   else
3790     {
3791       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3792       vat_json_object_add_ip4 (node, "map-server", ip4);
3793     }
3794 }
3795
3796 static void
3797 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3798                                            * mp)
3799 {
3800   vat_main_t *vam = &vat_main;
3801
3802   print (vam->ofp, "%=20U",
3803          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3804          mp->ip_address);
3805 }
3806
3807 static void
3808   vl_api_one_map_resolver_details_t_handler_json
3809   (vl_api_one_map_resolver_details_t * mp)
3810 {
3811   vat_main_t *vam = &vat_main;
3812   vat_json_node_t *node = NULL;
3813   struct in6_addr ip6;
3814   struct in_addr ip4;
3815
3816   if (VAT_JSON_ARRAY != vam->json_tree.type)
3817     {
3818       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3819       vat_json_init_array (&vam->json_tree);
3820     }
3821   node = vat_json_array_add (&vam->json_tree);
3822
3823   vat_json_init_object (node);
3824   if (mp->is_ipv6)
3825     {
3826       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3827       vat_json_object_add_ip6 (node, "map resolver", ip6);
3828     }
3829   else
3830     {
3831       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3832       vat_json_object_add_ip4 (node, "map resolver", ip4);
3833     }
3834 }
3835
3836 static void
3837 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
3838 {
3839   vat_main_t *vam = &vat_main;
3840   i32 retval = ntohl (mp->retval);
3841
3842   if (0 <= retval)
3843     {
3844       print (vam->ofp, "feature: %s\ngpe: %s",
3845              mp->feature_status ? "enabled" : "disabled",
3846              mp->gpe_status ? "enabled" : "disabled");
3847     }
3848
3849   vam->retval = retval;
3850   vam->result_ready = 1;
3851 }
3852
3853 static void
3854   vl_api_show_one_status_reply_t_handler_json
3855   (vl_api_show_one_status_reply_t * mp)
3856 {
3857   vat_main_t *vam = &vat_main;
3858   vat_json_node_t node;
3859   u8 *gpe_status = NULL;
3860   u8 *feature_status = NULL;
3861
3862   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
3863   feature_status = format (0, "%s",
3864                            mp->feature_status ? "enabled" : "disabled");
3865   vec_add1 (gpe_status, 0);
3866   vec_add1 (feature_status, 0);
3867
3868   vat_json_init_object (&node);
3869   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
3870   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
3871
3872   vec_free (gpe_status);
3873   vec_free (feature_status);
3874
3875   vat_json_print (vam->ofp, &node);
3876   vat_json_free (&node);
3877
3878   vam->retval = ntohl (mp->retval);
3879   vam->result_ready = 1;
3880 }
3881
3882 static void
3883   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
3884   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3885 {
3886   vat_main_t *vam = &vat_main;
3887   i32 retval = ntohl (mp->retval);
3888
3889   if (retval >= 0)
3890     {
3891       print (vam->ofp, "%=20s", mp->locator_set_name);
3892     }
3893
3894   vam->retval = retval;
3895   vam->result_ready = 1;
3896 }
3897
3898 static void
3899   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
3900   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3901 {
3902   vat_main_t *vam = &vat_main;
3903   vat_json_node_t *node = NULL;
3904
3905   if (VAT_JSON_ARRAY != vam->json_tree.type)
3906     {
3907       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3908       vat_json_init_array (&vam->json_tree);
3909     }
3910   node = vat_json_array_add (&vam->json_tree);
3911
3912   vat_json_init_object (node);
3913   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
3914
3915   vat_json_print (vam->ofp, node);
3916   vat_json_free (node);
3917
3918   vam->retval = ntohl (mp->retval);
3919   vam->result_ready = 1;
3920 }
3921
3922 static u8 *
3923 format_lisp_map_request_mode (u8 * s, va_list * args)
3924 {
3925   u32 mode = va_arg (*args, u32);
3926
3927   switch (mode)
3928     {
3929     case 0:
3930       return format (0, "dst-only");
3931     case 1:
3932       return format (0, "src-dst");
3933     }
3934   return 0;
3935 }
3936
3937 static void
3938   vl_api_show_one_map_request_mode_reply_t_handler
3939   (vl_api_show_one_map_request_mode_reply_t * mp)
3940 {
3941   vat_main_t *vam = &vat_main;
3942   i32 retval = ntohl (mp->retval);
3943
3944   if (0 <= retval)
3945     {
3946       u32 mode = mp->mode;
3947       print (vam->ofp, "map_request_mode: %U",
3948              format_lisp_map_request_mode, mode);
3949     }
3950
3951   vam->retval = retval;
3952   vam->result_ready = 1;
3953 }
3954
3955 static void
3956   vl_api_show_one_map_request_mode_reply_t_handler_json
3957   (vl_api_show_one_map_request_mode_reply_t * mp)
3958 {
3959   vat_main_t *vam = &vat_main;
3960   vat_json_node_t node;
3961   u8 *s = 0;
3962   u32 mode;
3963
3964   mode = mp->mode;
3965   s = format (0, "%U", format_lisp_map_request_mode, mode);
3966   vec_add1 (s, 0);
3967
3968   vat_json_init_object (&node);
3969   vat_json_object_add_string_copy (&node, "map_request_mode", s);
3970   vat_json_print (vam->ofp, &node);
3971   vat_json_free (&node);
3972
3973   vec_free (s);
3974   vam->retval = ntohl (mp->retval);
3975   vam->result_ready = 1;
3976 }
3977
3978 static void
3979   vl_api_show_one_use_petr_reply_t_handler
3980   (vl_api_show_one_use_petr_reply_t * mp)
3981 {
3982   vat_main_t *vam = &vat_main;
3983   i32 retval = ntohl (mp->retval);
3984
3985   if (0 <= retval)
3986     {
3987       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
3988       if (mp->status)
3989         {
3990           print (vam->ofp, "Proxy-ETR address; %U",
3991                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
3992                  mp->address);
3993         }
3994     }
3995
3996   vam->retval = retval;
3997   vam->result_ready = 1;
3998 }
3999
4000 static void
4001   vl_api_show_one_use_petr_reply_t_handler_json
4002   (vl_api_show_one_use_petr_reply_t * mp)
4003 {
4004   vat_main_t *vam = &vat_main;
4005   vat_json_node_t node;
4006   u8 *status = 0;
4007   struct in_addr ip4;
4008   struct in6_addr ip6;
4009
4010   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4011   vec_add1 (status, 0);
4012
4013   vat_json_init_object (&node);
4014   vat_json_object_add_string_copy (&node, "status", status);
4015   if (mp->status)
4016     {
4017       if (mp->is_ip4)
4018         {
4019           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4020           vat_json_object_add_ip6 (&node, "address", ip6);
4021         }
4022       else
4023         {
4024           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4025           vat_json_object_add_ip4 (&node, "address", ip4);
4026         }
4027     }
4028
4029   vec_free (status);
4030
4031   vat_json_print (vam->ofp, &node);
4032   vat_json_free (&node);
4033
4034   vam->retval = ntohl (mp->retval);
4035   vam->result_ready = 1;
4036 }
4037
4038 static void
4039   vl_api_show_one_nsh_mapping_reply_t_handler
4040   (vl_api_show_one_nsh_mapping_reply_t * mp)
4041 {
4042   vat_main_t *vam = &vat_main;
4043   i32 retval = ntohl (mp->retval);
4044
4045   if (0 <= retval)
4046     {
4047       print (vam->ofp, "%-20s%-16s",
4048              mp->is_set ? "set" : "not-set",
4049              mp->is_set ? (char *) mp->locator_set_name : "");
4050     }
4051
4052   vam->retval = retval;
4053   vam->result_ready = 1;
4054 }
4055
4056 static void
4057   vl_api_show_one_nsh_mapping_reply_t_handler_json
4058   (vl_api_show_one_nsh_mapping_reply_t * mp)
4059 {
4060   vat_main_t *vam = &vat_main;
4061   vat_json_node_t node;
4062   u8 *status = 0;
4063
4064   status = format (0, "%s", mp->is_set ? "yes" : "no");
4065   vec_add1 (status, 0);
4066
4067   vat_json_init_object (&node);
4068   vat_json_object_add_string_copy (&node, "is_set", status);
4069   if (mp->is_set)
4070     {
4071       vat_json_object_add_string_copy (&node, "locator_set",
4072                                        mp->locator_set_name);
4073     }
4074
4075   vec_free (status);
4076
4077   vat_json_print (vam->ofp, &node);
4078   vat_json_free (&node);
4079
4080   vam->retval = ntohl (mp->retval);
4081   vam->result_ready = 1;
4082 }
4083
4084 static void
4085   vl_api_show_one_map_register_ttl_reply_t_handler
4086   (vl_api_show_one_map_register_ttl_reply_t * mp)
4087 {
4088   vat_main_t *vam = &vat_main;
4089   i32 retval = ntohl (mp->retval);
4090
4091   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4092
4093   if (0 <= retval)
4094     {
4095       print (vam->ofp, "ttl: %u", mp->ttl);
4096     }
4097
4098   vam->retval = retval;
4099   vam->result_ready = 1;
4100 }
4101
4102 static void
4103   vl_api_show_one_map_register_ttl_reply_t_handler_json
4104   (vl_api_show_one_map_register_ttl_reply_t * mp)
4105 {
4106   vat_main_t *vam = &vat_main;
4107   vat_json_node_t node;
4108
4109   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4110   vat_json_init_object (&node);
4111   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4112
4113   vat_json_print (vam->ofp, &node);
4114   vat_json_free (&node);
4115
4116   vam->retval = ntohl (mp->retval);
4117   vam->result_ready = 1;
4118 }
4119
4120 static void
4121 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4122 {
4123   vat_main_t *vam = &vat_main;
4124   i32 retval = ntohl (mp->retval);
4125
4126   if (0 <= retval)
4127     {
4128       print (vam->ofp, "%-20s%-16s",
4129              mp->status ? "enabled" : "disabled",
4130              mp->status ? (char *) mp->locator_set_name : "");
4131     }
4132
4133   vam->retval = retval;
4134   vam->result_ready = 1;
4135 }
4136
4137 static void
4138 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4139 {
4140   vat_main_t *vam = &vat_main;
4141   vat_json_node_t node;
4142   u8 *status = 0;
4143
4144   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4145   vec_add1 (status, 0);
4146
4147   vat_json_init_object (&node);
4148   vat_json_object_add_string_copy (&node, "status", status);
4149   if (mp->status)
4150     {
4151       vat_json_object_add_string_copy (&node, "locator_set",
4152                                        mp->locator_set_name);
4153     }
4154
4155   vec_free (status);
4156
4157   vat_json_print (vam->ofp, &node);
4158   vat_json_free (&node);
4159
4160   vam->retval = ntohl (mp->retval);
4161   vam->result_ready = 1;
4162 }
4163
4164 static u8 *
4165 format_policer_type (u8 * s, va_list * va)
4166 {
4167   u32 i = va_arg (*va, u32);
4168
4169   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4170     s = format (s, "1r2c");
4171   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4172     s = format (s, "1r3c");
4173   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4174     s = format (s, "2r3c-2698");
4175   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4176     s = format (s, "2r3c-4115");
4177   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4178     s = format (s, "2r3c-mef5cf1");
4179   else
4180     s = format (s, "ILLEGAL");
4181   return s;
4182 }
4183
4184 static u8 *
4185 format_policer_rate_type (u8 * s, va_list * va)
4186 {
4187   u32 i = va_arg (*va, u32);
4188
4189   if (i == SSE2_QOS_RATE_KBPS)
4190     s = format (s, "kbps");
4191   else if (i == SSE2_QOS_RATE_PPS)
4192     s = format (s, "pps");
4193   else
4194     s = format (s, "ILLEGAL");
4195   return s;
4196 }
4197
4198 static u8 *
4199 format_policer_round_type (u8 * s, va_list * va)
4200 {
4201   u32 i = va_arg (*va, u32);
4202
4203   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4204     s = format (s, "closest");
4205   else if (i == SSE2_QOS_ROUND_TO_UP)
4206     s = format (s, "up");
4207   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4208     s = format (s, "down");
4209   else
4210     s = format (s, "ILLEGAL");
4211   return s;
4212 }
4213
4214 static u8 *
4215 format_policer_action_type (u8 * s, va_list * va)
4216 {
4217   u32 i = va_arg (*va, u32);
4218
4219   if (i == SSE2_QOS_ACTION_DROP)
4220     s = format (s, "drop");
4221   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4222     s = format (s, "transmit");
4223   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4224     s = format (s, "mark-and-transmit");
4225   else
4226     s = format (s, "ILLEGAL");
4227   return s;
4228 }
4229
4230 static u8 *
4231 format_dscp (u8 * s, va_list * va)
4232 {
4233   u32 i = va_arg (*va, u32);
4234   char *t = 0;
4235
4236   switch (i)
4237     {
4238 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4239       foreach_vnet_dscp
4240 #undef _
4241     default:
4242       return format (s, "ILLEGAL");
4243     }
4244   s = format (s, "%s", t);
4245   return s;
4246 }
4247
4248 static void
4249 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4250 {
4251   vat_main_t *vam = &vat_main;
4252   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4253
4254   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4255     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4256   else
4257     conform_dscp_str = format (0, "");
4258
4259   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4260     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4261   else
4262     exceed_dscp_str = format (0, "");
4263
4264   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4265     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4266   else
4267     violate_dscp_str = format (0, "");
4268
4269   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4270          "rate type %U, round type %U, %s rate, %s color-aware, "
4271          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4272          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4273          "conform action %U%s, exceed action %U%s, violate action %U%s",
4274          mp->name,
4275          format_policer_type, mp->type,
4276          ntohl (mp->cir),
4277          ntohl (mp->eir),
4278          clib_net_to_host_u64 (mp->cb),
4279          clib_net_to_host_u64 (mp->eb),
4280          format_policer_rate_type, mp->rate_type,
4281          format_policer_round_type, mp->round_type,
4282          mp->single_rate ? "single" : "dual",
4283          mp->color_aware ? "is" : "not",
4284          ntohl (mp->cir_tokens_per_period),
4285          ntohl (mp->pir_tokens_per_period),
4286          ntohl (mp->scale),
4287          ntohl (mp->current_limit),
4288          ntohl (mp->current_bucket),
4289          ntohl (mp->extended_limit),
4290          ntohl (mp->extended_bucket),
4291          clib_net_to_host_u64 (mp->last_update_time),
4292          format_policer_action_type, mp->conform_action_type,
4293          conform_dscp_str,
4294          format_policer_action_type, mp->exceed_action_type,
4295          exceed_dscp_str,
4296          format_policer_action_type, mp->violate_action_type,
4297          violate_dscp_str);
4298
4299   vec_free (conform_dscp_str);
4300   vec_free (exceed_dscp_str);
4301   vec_free (violate_dscp_str);
4302 }
4303
4304 static void vl_api_policer_details_t_handler_json
4305   (vl_api_policer_details_t * mp)
4306 {
4307   vat_main_t *vam = &vat_main;
4308   vat_json_node_t *node;
4309   u8 *rate_type_str, *round_type_str, *type_str;
4310   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4311
4312   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4313   round_type_str =
4314     format (0, "%U", format_policer_round_type, mp->round_type);
4315   type_str = format (0, "%U", format_policer_type, mp->type);
4316   conform_action_str = format (0, "%U", format_policer_action_type,
4317                                mp->conform_action_type);
4318   exceed_action_str = format (0, "%U", format_policer_action_type,
4319                               mp->exceed_action_type);
4320   violate_action_str = format (0, "%U", format_policer_action_type,
4321                                mp->violate_action_type);
4322
4323   if (VAT_JSON_ARRAY != vam->json_tree.type)
4324     {
4325       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4326       vat_json_init_array (&vam->json_tree);
4327     }
4328   node = vat_json_array_add (&vam->json_tree);
4329
4330   vat_json_init_object (node);
4331   vat_json_object_add_string_copy (node, "name", mp->name);
4332   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4333   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4334   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4335   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4336   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4337   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4338   vat_json_object_add_string_copy (node, "type", type_str);
4339   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4340   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4341   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4342   vat_json_object_add_uint (node, "cir_tokens_per_period",
4343                             ntohl (mp->cir_tokens_per_period));
4344   vat_json_object_add_uint (node, "eir_tokens_per_period",
4345                             ntohl (mp->pir_tokens_per_period));
4346   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4347   vat_json_object_add_uint (node, "current_bucket",
4348                             ntohl (mp->current_bucket));
4349   vat_json_object_add_uint (node, "extended_limit",
4350                             ntohl (mp->extended_limit));
4351   vat_json_object_add_uint (node, "extended_bucket",
4352                             ntohl (mp->extended_bucket));
4353   vat_json_object_add_uint (node, "last_update_time",
4354                             ntohl (mp->last_update_time));
4355   vat_json_object_add_string_copy (node, "conform_action",
4356                                    conform_action_str);
4357   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4358     {
4359       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4360       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4361       vec_free (dscp_str);
4362     }
4363   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4364   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4365     {
4366       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4367       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4368       vec_free (dscp_str);
4369     }
4370   vat_json_object_add_string_copy (node, "violate_action",
4371                                    violate_action_str);
4372   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4373     {
4374       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4375       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4376       vec_free (dscp_str);
4377     }
4378
4379   vec_free (rate_type_str);
4380   vec_free (round_type_str);
4381   vec_free (type_str);
4382   vec_free (conform_action_str);
4383   vec_free (exceed_action_str);
4384   vec_free (violate_action_str);
4385 }
4386
4387 static void
4388 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4389                                            mp)
4390 {
4391   vat_main_t *vam = &vat_main;
4392   int i, count = ntohl (mp->count);
4393
4394   if (count > 0)
4395     print (vam->ofp, "classify table ids (%d) : ", count);
4396   for (i = 0; i < count; i++)
4397     {
4398       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4399       print (vam->ofp, (i < count - 1) ? "," : "");
4400     }
4401   vam->retval = ntohl (mp->retval);
4402   vam->result_ready = 1;
4403 }
4404
4405 static void
4406   vl_api_classify_table_ids_reply_t_handler_json
4407   (vl_api_classify_table_ids_reply_t * mp)
4408 {
4409   vat_main_t *vam = &vat_main;
4410   int i, count = ntohl (mp->count);
4411
4412   if (count > 0)
4413     {
4414       vat_json_node_t node;
4415
4416       vat_json_init_object (&node);
4417       for (i = 0; i < count; i++)
4418         {
4419           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4420         }
4421       vat_json_print (vam->ofp, &node);
4422       vat_json_free (&node);
4423     }
4424   vam->retval = ntohl (mp->retval);
4425   vam->result_ready = 1;
4426 }
4427
4428 static void
4429   vl_api_classify_table_by_interface_reply_t_handler
4430   (vl_api_classify_table_by_interface_reply_t * mp)
4431 {
4432   vat_main_t *vam = &vat_main;
4433   u32 table_id;
4434
4435   table_id = ntohl (mp->l2_table_id);
4436   if (table_id != ~0)
4437     print (vam->ofp, "l2 table id : %d", table_id);
4438   else
4439     print (vam->ofp, "l2 table id : No input ACL tables configured");
4440   table_id = ntohl (mp->ip4_table_id);
4441   if (table_id != ~0)
4442     print (vam->ofp, "ip4 table id : %d", table_id);
4443   else
4444     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4445   table_id = ntohl (mp->ip6_table_id);
4446   if (table_id != ~0)
4447     print (vam->ofp, "ip6 table id : %d", table_id);
4448   else
4449     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4450   vam->retval = ntohl (mp->retval);
4451   vam->result_ready = 1;
4452 }
4453
4454 static void
4455   vl_api_classify_table_by_interface_reply_t_handler_json
4456   (vl_api_classify_table_by_interface_reply_t * mp)
4457 {
4458   vat_main_t *vam = &vat_main;
4459   vat_json_node_t node;
4460
4461   vat_json_init_object (&node);
4462
4463   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4464   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4465   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4466
4467   vat_json_print (vam->ofp, &node);
4468   vat_json_free (&node);
4469
4470   vam->retval = ntohl (mp->retval);
4471   vam->result_ready = 1;
4472 }
4473
4474 static void vl_api_policer_add_del_reply_t_handler
4475   (vl_api_policer_add_del_reply_t * mp)
4476 {
4477   vat_main_t *vam = &vat_main;
4478   i32 retval = ntohl (mp->retval);
4479   if (vam->async_mode)
4480     {
4481       vam->async_errors += (retval < 0);
4482     }
4483   else
4484     {
4485       vam->retval = retval;
4486       vam->result_ready = 1;
4487       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4488         /*
4489          * Note: this is just barely thread-safe, depends on
4490          * the main thread spinning waiting for an answer...
4491          */
4492         errmsg ("policer index %d", ntohl (mp->policer_index));
4493     }
4494 }
4495
4496 static void vl_api_policer_add_del_reply_t_handler_json
4497   (vl_api_policer_add_del_reply_t * mp)
4498 {
4499   vat_main_t *vam = &vat_main;
4500   vat_json_node_t node;
4501
4502   vat_json_init_object (&node);
4503   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4504   vat_json_object_add_uint (&node, "policer_index",
4505                             ntohl (mp->policer_index));
4506
4507   vat_json_print (vam->ofp, &node);
4508   vat_json_free (&node);
4509
4510   vam->retval = ntohl (mp->retval);
4511   vam->result_ready = 1;
4512 }
4513
4514 /* Format hex dump. */
4515 u8 *
4516 format_hex_bytes (u8 * s, va_list * va)
4517 {
4518   u8 *bytes = va_arg (*va, u8 *);
4519   int n_bytes = va_arg (*va, int);
4520   uword i;
4521
4522   /* Print short or long form depending on byte count. */
4523   uword short_form = n_bytes <= 32;
4524   uword indent = format_get_indent (s);
4525
4526   if (n_bytes == 0)
4527     return s;
4528
4529   for (i = 0; i < n_bytes; i++)
4530     {
4531       if (!short_form && (i % 32) == 0)
4532         s = format (s, "%08x: ", i);
4533       s = format (s, "%02x", bytes[i]);
4534       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4535         s = format (s, "\n%U", format_white_space, indent);
4536     }
4537
4538   return s;
4539 }
4540
4541 static void
4542 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4543                                             * mp)
4544 {
4545   vat_main_t *vam = &vat_main;
4546   i32 retval = ntohl (mp->retval);
4547   if (retval == 0)
4548     {
4549       print (vam->ofp, "classify table info :");
4550       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4551              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4552              ntohl (mp->miss_next_index));
4553       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4554              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4555              ntohl (mp->match_n_vectors));
4556       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4557              ntohl (mp->mask_length));
4558     }
4559   vam->retval = retval;
4560   vam->result_ready = 1;
4561 }
4562
4563 static void
4564   vl_api_classify_table_info_reply_t_handler_json
4565   (vl_api_classify_table_info_reply_t * mp)
4566 {
4567   vat_main_t *vam = &vat_main;
4568   vat_json_node_t node;
4569
4570   i32 retval = ntohl (mp->retval);
4571   if (retval == 0)
4572     {
4573       vat_json_init_object (&node);
4574
4575       vat_json_object_add_int (&node, "sessions",
4576                                ntohl (mp->active_sessions));
4577       vat_json_object_add_int (&node, "nexttbl",
4578                                ntohl (mp->next_table_index));
4579       vat_json_object_add_int (&node, "nextnode",
4580                                ntohl (mp->miss_next_index));
4581       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4582       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4583       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4584       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4585                       ntohl (mp->mask_length), 0);
4586       vat_json_object_add_string_copy (&node, "mask", s);
4587
4588       vat_json_print (vam->ofp, &node);
4589       vat_json_free (&node);
4590     }
4591   vam->retval = ntohl (mp->retval);
4592   vam->result_ready = 1;
4593 }
4594
4595 static void
4596 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4597                                            mp)
4598 {
4599   vat_main_t *vam = &vat_main;
4600
4601   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4602          ntohl (mp->hit_next_index), ntohl (mp->advance),
4603          ntohl (mp->opaque_index));
4604   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4605          ntohl (mp->match_length));
4606 }
4607
4608 static void
4609   vl_api_classify_session_details_t_handler_json
4610   (vl_api_classify_session_details_t * mp)
4611 {
4612   vat_main_t *vam = &vat_main;
4613   vat_json_node_t *node = NULL;
4614
4615   if (VAT_JSON_ARRAY != vam->json_tree.type)
4616     {
4617       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4618       vat_json_init_array (&vam->json_tree);
4619     }
4620   node = vat_json_array_add (&vam->json_tree);
4621
4622   vat_json_init_object (node);
4623   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4624   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4625   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4626   u8 *s =
4627     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4628             0);
4629   vat_json_object_add_string_copy (node, "match", s);
4630 }
4631
4632 static void vl_api_pg_create_interface_reply_t_handler
4633   (vl_api_pg_create_interface_reply_t * mp)
4634 {
4635   vat_main_t *vam = &vat_main;
4636
4637   vam->retval = ntohl (mp->retval);
4638   vam->result_ready = 1;
4639 }
4640
4641 static void vl_api_pg_create_interface_reply_t_handler_json
4642   (vl_api_pg_create_interface_reply_t * mp)
4643 {
4644   vat_main_t *vam = &vat_main;
4645   vat_json_node_t node;
4646
4647   i32 retval = ntohl (mp->retval);
4648   if (retval == 0)
4649     {
4650       vat_json_init_object (&node);
4651
4652       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4653
4654       vat_json_print (vam->ofp, &node);
4655       vat_json_free (&node);
4656     }
4657   vam->retval = ntohl (mp->retval);
4658   vam->result_ready = 1;
4659 }
4660
4661 static void vl_api_policer_classify_details_t_handler
4662   (vl_api_policer_classify_details_t * mp)
4663 {
4664   vat_main_t *vam = &vat_main;
4665
4666   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4667          ntohl (mp->table_index));
4668 }
4669
4670 static void vl_api_policer_classify_details_t_handler_json
4671   (vl_api_policer_classify_details_t * mp)
4672 {
4673   vat_main_t *vam = &vat_main;
4674   vat_json_node_t *node;
4675
4676   if (VAT_JSON_ARRAY != vam->json_tree.type)
4677     {
4678       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4679       vat_json_init_array (&vam->json_tree);
4680     }
4681   node = vat_json_array_add (&vam->json_tree);
4682
4683   vat_json_init_object (node);
4684   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4685   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4686 }
4687
4688 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
4689   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4690 {
4691   vat_main_t *vam = &vat_main;
4692   i32 retval = ntohl (mp->retval);
4693   if (vam->async_mode)
4694     {
4695       vam->async_errors += (retval < 0);
4696     }
4697   else
4698     {
4699       vam->retval = retval;
4700       vam->sw_if_index = ntohl (mp->sw_if_index);
4701       vam->result_ready = 1;
4702     }
4703 }
4704
4705 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
4706   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4707 {
4708   vat_main_t *vam = &vat_main;
4709   vat_json_node_t node;
4710
4711   vat_json_init_object (&node);
4712   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4713   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
4714
4715   vat_json_print (vam->ofp, &node);
4716   vat_json_free (&node);
4717
4718   vam->retval = ntohl (mp->retval);
4719   vam->result_ready = 1;
4720 }
4721
4722 static void vl_api_flow_classify_details_t_handler
4723   (vl_api_flow_classify_details_t * mp)
4724 {
4725   vat_main_t *vam = &vat_main;
4726
4727   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4728          ntohl (mp->table_index));
4729 }
4730
4731 static void vl_api_flow_classify_details_t_handler_json
4732   (vl_api_flow_classify_details_t * mp)
4733 {
4734   vat_main_t *vam = &vat_main;
4735   vat_json_node_t *node;
4736
4737   if (VAT_JSON_ARRAY != vam->json_tree.type)
4738     {
4739       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4740       vat_json_init_array (&vam->json_tree);
4741     }
4742   node = vat_json_array_add (&vam->json_tree);
4743
4744   vat_json_init_object (node);
4745   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4746   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4747 }
4748
4749 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
4750 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
4751 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
4752 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
4753 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
4754 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
4755 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
4756 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
4757 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
4758 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
4759 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
4760 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
4761 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
4762 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
4763 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
4764 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
4765 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
4766 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
4767 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
4768 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
4769 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
4770 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
4771
4772 /*
4773  * Generate boilerplate reply handlers, which
4774  * dig the return value out of the xxx_reply_t API message,
4775  * stick it into vam->retval, and set vam->result_ready
4776  *
4777  * Could also do this by pointing N message decode slots at
4778  * a single function, but that could break in subtle ways.
4779  */
4780
4781 #define foreach_standard_reply_retval_handler           \
4782 _(sw_interface_set_flags_reply)                         \
4783 _(sw_interface_add_del_address_reply)                   \
4784 _(sw_interface_set_table_reply)                         \
4785 _(sw_interface_set_mpls_enable_reply)                   \
4786 _(sw_interface_set_vpath_reply)                         \
4787 _(sw_interface_set_vxlan_bypass_reply)                  \
4788 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
4789 _(sw_interface_set_l2_bridge_reply)                     \
4790 _(bridge_domain_add_del_reply)                          \
4791 _(sw_interface_set_l2_xconnect_reply)                   \
4792 _(l2fib_add_del_reply)                                  \
4793 _(l2fib_flush_int_reply)                                \
4794 _(l2fib_flush_bd_reply)                                 \
4795 _(ip_add_del_route_reply)                               \
4796 _(ip_table_add_del_reply)                               \
4797 _(ip_mroute_add_del_reply)                              \
4798 _(mpls_route_add_del_reply)                             \
4799 _(mpls_table_add_del_reply)                             \
4800 _(mpls_ip_bind_unbind_reply)                            \
4801 _(proxy_arp_add_del_reply)                              \
4802 _(proxy_arp_intfc_enable_disable_reply)                 \
4803 _(sw_interface_set_unnumbered_reply)                    \
4804 _(ip_neighbor_add_del_reply)                            \
4805 _(reset_vrf_reply)                                      \
4806 _(oam_add_del_reply)                                    \
4807 _(reset_fib_reply)                                      \
4808 _(dhcp_proxy_config_reply)                              \
4809 _(dhcp_proxy_set_vss_reply)                             \
4810 _(dhcp_client_config_reply)                             \
4811 _(set_ip_flow_hash_reply)                               \
4812 _(sw_interface_ip6_enable_disable_reply)                \
4813 _(sw_interface_ip6_set_link_local_address_reply)        \
4814 _(ip6nd_proxy_add_del_reply)                            \
4815 _(sw_interface_ip6nd_ra_prefix_reply)                   \
4816 _(sw_interface_ip6nd_ra_config_reply)                   \
4817 _(set_arp_neighbor_limit_reply)                         \
4818 _(l2_patch_add_del_reply)                               \
4819 _(sr_policy_add_reply)                                  \
4820 _(sr_policy_mod_reply)                                  \
4821 _(sr_policy_del_reply)                                  \
4822 _(sr_localsid_add_del_reply)                            \
4823 _(sr_steering_add_del_reply)                            \
4824 _(classify_add_del_session_reply)                       \
4825 _(classify_set_interface_ip_table_reply)                \
4826 _(classify_set_interface_l2_tables_reply)               \
4827 _(l2tpv3_set_tunnel_cookies_reply)                      \
4828 _(l2tpv3_interface_enable_disable_reply)                \
4829 _(l2tpv3_set_lookup_key_reply)                          \
4830 _(l2_fib_clear_table_reply)                             \
4831 _(l2_interface_efp_filter_reply)                        \
4832 _(l2_interface_vlan_tag_rewrite_reply)                  \
4833 _(modify_vhost_user_if_reply)                           \
4834 _(delete_vhost_user_if_reply)                           \
4835 _(want_ip4_arp_events_reply)                            \
4836 _(want_ip6_nd_events_reply)                             \
4837 _(want_l2_macs_events_reply)                            \
4838 _(input_acl_set_interface_reply)                        \
4839 _(ipsec_spd_add_del_reply)                              \
4840 _(ipsec_interface_add_del_spd_reply)                    \
4841 _(ipsec_spd_add_del_entry_reply)                        \
4842 _(ipsec_sad_add_del_entry_reply)                        \
4843 _(ipsec_sa_set_key_reply)                               \
4844 _(ipsec_tunnel_if_add_del_reply)                        \
4845 _(ikev2_profile_add_del_reply)                          \
4846 _(ikev2_profile_set_auth_reply)                         \
4847 _(ikev2_profile_set_id_reply)                           \
4848 _(ikev2_profile_set_ts_reply)                           \
4849 _(ikev2_set_local_key_reply)                            \
4850 _(ikev2_set_responder_reply)                            \
4851 _(ikev2_set_ike_transforms_reply)                       \
4852 _(ikev2_set_esp_transforms_reply)                       \
4853 _(ikev2_set_sa_lifetime_reply)                          \
4854 _(ikev2_initiate_sa_init_reply)                         \
4855 _(ikev2_initiate_del_ike_sa_reply)                      \
4856 _(ikev2_initiate_del_child_sa_reply)                    \
4857 _(ikev2_initiate_rekey_child_sa_reply)                  \
4858 _(delete_loopback_reply)                                \
4859 _(bd_ip_mac_add_del_reply)                              \
4860 _(map_del_domain_reply)                                 \
4861 _(map_add_del_rule_reply)                               \
4862 _(want_interface_events_reply)                          \
4863 _(want_stats_reply)                                     \
4864 _(cop_interface_enable_disable_reply)                   \
4865 _(cop_whitelist_enable_disable_reply)                   \
4866 _(sw_interface_clear_stats_reply)                       \
4867 _(ioam_enable_reply)                              \
4868 _(ioam_disable_reply)                              \
4869 _(one_add_del_locator_reply)                            \
4870 _(one_add_del_local_eid_reply)                          \
4871 _(one_add_del_remote_mapping_reply)                     \
4872 _(one_add_del_adjacency_reply)                          \
4873 _(one_add_del_map_resolver_reply)                       \
4874 _(one_add_del_map_server_reply)                         \
4875 _(one_enable_disable_reply)                             \
4876 _(one_rloc_probe_enable_disable_reply)                  \
4877 _(one_map_register_enable_disable_reply)                \
4878 _(one_map_register_set_ttl_reply)                       \
4879 _(one_set_transport_protocol_reply)                     \
4880 _(one_map_register_fallback_threshold_reply)            \
4881 _(one_pitr_set_locator_set_reply)                       \
4882 _(one_map_request_mode_reply)                           \
4883 _(one_add_del_map_request_itr_rlocs_reply)              \
4884 _(one_eid_table_add_del_map_reply)                      \
4885 _(one_use_petr_reply)                                   \
4886 _(one_stats_enable_disable_reply)                       \
4887 _(one_add_del_l2_arp_entry_reply)                       \
4888 _(one_add_del_ndp_entry_reply)                          \
4889 _(one_stats_flush_reply)                                \
4890 _(gpe_enable_disable_reply)                             \
4891 _(gpe_set_encap_mode_reply)                             \
4892 _(gpe_add_del_iface_reply)                              \
4893 _(gpe_add_del_native_fwd_rpath_reply)                   \
4894 _(af_packet_delete_reply)                               \
4895 _(policer_classify_set_interface_reply)                 \
4896 _(netmap_create_reply)                                  \
4897 _(netmap_delete_reply)                                  \
4898 _(set_ipfix_exporter_reply)                             \
4899 _(set_ipfix_classify_stream_reply)                      \
4900 _(ipfix_classify_table_add_del_reply)                   \
4901 _(flow_classify_set_interface_reply)                    \
4902 _(sw_interface_span_enable_disable_reply)               \
4903 _(pg_capture_reply)                                     \
4904 _(pg_enable_disable_reply)                              \
4905 _(ip_source_and_port_range_check_add_del_reply)         \
4906 _(ip_source_and_port_range_check_interface_add_del_reply)\
4907 _(delete_subif_reply)                                   \
4908 _(l2_interface_pbb_tag_rewrite_reply)                   \
4909 _(punt_reply)                                           \
4910 _(feature_enable_disable_reply)                         \
4911 _(sw_interface_tag_add_del_reply)                       \
4912 _(sw_interface_set_mtu_reply)                           \
4913 _(p2p_ethernet_add_reply)                               \
4914 _(p2p_ethernet_del_reply)                               \
4915 _(lldp_config_reply)                                    \
4916 _(sw_interface_set_lldp_reply)                          \
4917 _(tcp_configure_src_addresses_reply)
4918
4919 #define _(n)                                    \
4920     static void vl_api_##n##_t_handler          \
4921     (vl_api_##n##_t * mp)                       \
4922     {                                           \
4923         vat_main_t * vam = &vat_main;           \
4924         i32 retval = ntohl(mp->retval);         \
4925         if (vam->async_mode) {                  \
4926             vam->async_errors += (retval < 0);  \
4927         } else {                                \
4928             vam->retval = retval;               \
4929             vam->result_ready = 1;              \
4930         }                                       \
4931     }
4932 foreach_standard_reply_retval_handler;
4933 #undef _
4934
4935 #define _(n)                                    \
4936     static void vl_api_##n##_t_handler_json     \
4937     (vl_api_##n##_t * mp)                       \
4938     {                                           \
4939         vat_main_t * vam = &vat_main;           \
4940         vat_json_node_t node;                   \
4941         vat_json_init_object(&node);            \
4942         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
4943         vat_json_print(vam->ofp, &node);        \
4944         vam->retval = ntohl(mp->retval);        \
4945         vam->result_ready = 1;                  \
4946     }
4947 foreach_standard_reply_retval_handler;
4948 #undef _
4949
4950 /*
4951  * Table of message reply handlers, must include boilerplate handlers
4952  * we just generated
4953  */
4954
4955 #define foreach_vpe_api_reply_msg                                       \
4956 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
4957 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
4958 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
4959 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
4960 _(CONTROL_PING_REPLY, control_ping_reply)                               \
4961 _(CLI_REPLY, cli_reply)                                                 \
4962 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
4963 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
4964   sw_interface_add_del_address_reply)                                   \
4965 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
4966 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
4967 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
4968 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
4969 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
4970 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
4971   sw_interface_set_l2_xconnect_reply)                                   \
4972 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
4973   sw_interface_set_l2_bridge_reply)                                     \
4974 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
4975 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
4976 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
4977 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
4978 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
4979 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
4980 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
4981 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
4982 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
4983 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
4984 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
4985 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
4986 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
4987 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
4988 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
4989 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
4990 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
4991 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
4992 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
4993 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
4994   proxy_arp_intfc_enable_disable_reply)                                 \
4995 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
4996 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
4997   sw_interface_set_unnumbered_reply)                                    \
4998 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
4999 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
5000 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5001 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5002 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5003 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5004 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5005 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5006 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5007 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5008 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5009 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5010   sw_interface_ip6_enable_disable_reply)                                \
5011 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5012   sw_interface_ip6_set_link_local_address_reply)                        \
5013 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5014 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5015 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5016   sw_interface_ip6nd_ra_prefix_reply)                                   \
5017 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5018   sw_interface_ip6nd_ra_config_reply)                                   \
5019 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5020 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5021 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5022 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5023 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5024 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5025 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5026 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5027 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5028 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5029 classify_set_interface_ip_table_reply)                                  \
5030 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5031   classify_set_interface_l2_tables_reply)                               \
5032 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5033 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5034 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5035 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5036 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5037   l2tpv3_interface_enable_disable_reply)                                \
5038 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5039 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5040 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5041 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5042 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5043 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5044 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5045 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5046 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5047 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5048 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5049 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5050 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5051 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5052 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5053 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
5054 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5055 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5056 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5057 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5058 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5059 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5060 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5061 _(L2_MACS_EVENT, l2_macs_event)                                         \
5062 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5063 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5064 _(IP_DETAILS, ip_details)                                               \
5065 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5066 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5067 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5068 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5069 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5070 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5071 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5072 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5073 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5074 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5075 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5076 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5077 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5078 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5079 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5080 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5081 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5082 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5083 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5084 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5085 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5086 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5087 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
5088 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
5089 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
5090 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
5091 _(MAP_RULE_DETAILS, map_rule_details)                                   \
5092 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5093 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5094 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5095 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5096 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5097 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5098 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5099 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5100 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5101 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5102 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5103 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5104 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5105 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5106 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5107 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5108 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5109 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5110   one_map_register_enable_disable_reply)                                \
5111 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5112 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5113 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5114 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5115   one_map_register_fallback_threshold_reply)                            \
5116 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5117   one_rloc_probe_enable_disable_reply)                                  \
5118 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5119 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5120 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5121 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5122 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5123 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5124 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5125 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5126 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5127 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5128 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5129 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5130 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5131 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5132 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5133 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5134   show_one_stats_enable_disable_reply)                                  \
5135 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5136 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5137 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5138 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5139 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5140 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5141 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5142 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5143 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5144 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5145 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5146 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5147 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5148 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5149 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5150   gpe_add_del_native_fwd_rpath_reply)                                   \
5151 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5152   gpe_fwd_entry_path_details)                                           \
5153 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5154 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5155   one_add_del_map_request_itr_rlocs_reply)                              \
5156 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5157   one_get_map_request_itr_rlocs_reply)                                  \
5158 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5159 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5160 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5161 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5162 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5163 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5164   show_one_map_register_state_reply)                                    \
5165 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5166 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5167   show_one_map_register_fallback_threshold_reply)                       \
5168 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5169 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5170 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5171 _(POLICER_DETAILS, policer_details)                                     \
5172 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5173 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5174 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5175 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5176 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5177 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5178 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5179 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5180 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5181 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5182 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5183 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5184 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5185 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5186 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5187 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5188 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5189 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5190 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5191 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5192 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5193 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5194 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5195 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5196 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5197  ip_source_and_port_range_check_add_del_reply)                          \
5198 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5199  ip_source_and_port_range_check_interface_add_del_reply)                \
5200 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5201 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5202 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5203 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5204 _(PUNT_REPLY, punt_reply)                                               \
5205 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5206 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5207 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5208 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5209 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5210 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5211 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5212 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5213 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5214 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5215 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5216 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5217 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply)
5218
5219 #define foreach_standalone_reply_msg                                    \
5220 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5221 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5222 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5223 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5224 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5225 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5226 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
5227
5228 typedef struct
5229 {
5230   u8 *name;
5231   u32 value;
5232 } name_sort_t;
5233
5234
5235 #define STR_VTR_OP_CASE(op)     \
5236     case L2_VTR_ ## op:         \
5237         return "" # op;
5238
5239 static const char *
5240 str_vtr_op (u32 vtr_op)
5241 {
5242   switch (vtr_op)
5243     {
5244       STR_VTR_OP_CASE (DISABLED);
5245       STR_VTR_OP_CASE (PUSH_1);
5246       STR_VTR_OP_CASE (PUSH_2);
5247       STR_VTR_OP_CASE (POP_1);
5248       STR_VTR_OP_CASE (POP_2);
5249       STR_VTR_OP_CASE (TRANSLATE_1_1);
5250       STR_VTR_OP_CASE (TRANSLATE_1_2);
5251       STR_VTR_OP_CASE (TRANSLATE_2_1);
5252       STR_VTR_OP_CASE (TRANSLATE_2_2);
5253     }
5254
5255   return "UNKNOWN";
5256 }
5257
5258 static int
5259 dump_sub_interface_table (vat_main_t * vam)
5260 {
5261   const sw_interface_subif_t *sub = NULL;
5262
5263   if (vam->json_output)
5264     {
5265       clib_warning
5266         ("JSON output supported only for VPE API calls and dump_stats_table");
5267       return -99;
5268     }
5269
5270   print (vam->ofp,
5271          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5272          "Interface", "sw_if_index",
5273          "sub id", "dot1ad", "tags", "outer id",
5274          "inner id", "exact", "default", "outer any", "inner any");
5275
5276   vec_foreach (sub, vam->sw_if_subif_table)
5277   {
5278     print (vam->ofp,
5279            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5280            sub->interface_name,
5281            sub->sw_if_index,
5282            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5283            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5284            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5285            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5286     if (sub->vtr_op != L2_VTR_DISABLED)
5287       {
5288         print (vam->ofp,
5289                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5290                "tag1: %d tag2: %d ]",
5291                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5292                sub->vtr_tag1, sub->vtr_tag2);
5293       }
5294   }
5295
5296   return 0;
5297 }
5298
5299 static int
5300 name_sort_cmp (void *a1, void *a2)
5301 {
5302   name_sort_t *n1 = a1;
5303   name_sort_t *n2 = a2;
5304
5305   return strcmp ((char *) n1->name, (char *) n2->name);
5306 }
5307
5308 static int
5309 dump_interface_table (vat_main_t * vam)
5310 {
5311   hash_pair_t *p;
5312   name_sort_t *nses = 0, *ns;
5313
5314   if (vam->json_output)
5315     {
5316       clib_warning
5317         ("JSON output supported only for VPE API calls and dump_stats_table");
5318       return -99;
5319     }
5320
5321   /* *INDENT-OFF* */
5322   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5323   ({
5324     vec_add2 (nses, ns, 1);
5325     ns->name = (u8 *)(p->key);
5326     ns->value = (u32) p->value[0];
5327   }));
5328   /* *INDENT-ON* */
5329
5330   vec_sort_with_function (nses, name_sort_cmp);
5331
5332   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5333   vec_foreach (ns, nses)
5334   {
5335     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5336   }
5337   vec_free (nses);
5338   return 0;
5339 }
5340
5341 static int
5342 dump_ip_table (vat_main_t * vam, int is_ipv6)
5343 {
5344   const ip_details_t *det = NULL;
5345   const ip_address_details_t *address = NULL;
5346   u32 i = ~0;
5347
5348   print (vam->ofp, "%-12s", "sw_if_index");
5349
5350   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5351   {
5352     i++;
5353     if (!det->present)
5354       {
5355         continue;
5356       }
5357     print (vam->ofp, "%-12d", i);
5358     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5359     if (!det->addr)
5360       {
5361         continue;
5362       }
5363     vec_foreach (address, det->addr)
5364     {
5365       print (vam->ofp,
5366              "            %-30U%-13d",
5367              is_ipv6 ? format_ip6_address : format_ip4_address,
5368              address->ip, address->prefix_length);
5369     }
5370   }
5371
5372   return 0;
5373 }
5374
5375 static int
5376 dump_ipv4_table (vat_main_t * vam)
5377 {
5378   if (vam->json_output)
5379     {
5380       clib_warning
5381         ("JSON output supported only for VPE API calls and dump_stats_table");
5382       return -99;
5383     }
5384
5385   return dump_ip_table (vam, 0);
5386 }
5387
5388 static int
5389 dump_ipv6_table (vat_main_t * vam)
5390 {
5391   if (vam->json_output)
5392     {
5393       clib_warning
5394         ("JSON output supported only for VPE API calls and dump_stats_table");
5395       return -99;
5396     }
5397
5398   return dump_ip_table (vam, 1);
5399 }
5400
5401 static char *
5402 counter_type_to_str (u8 counter_type, u8 is_combined)
5403 {
5404   if (!is_combined)
5405     {
5406       switch (counter_type)
5407         {
5408         case VNET_INTERFACE_COUNTER_DROP:
5409           return "drop";
5410         case VNET_INTERFACE_COUNTER_PUNT:
5411           return "punt";
5412         case VNET_INTERFACE_COUNTER_IP4:
5413           return "ip4";
5414         case VNET_INTERFACE_COUNTER_IP6:
5415           return "ip6";
5416         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
5417           return "rx-no-buf";
5418         case VNET_INTERFACE_COUNTER_RX_MISS:
5419           return "rx-miss";
5420         case VNET_INTERFACE_COUNTER_RX_ERROR:
5421           return "rx-error";
5422         case VNET_INTERFACE_COUNTER_TX_ERROR:
5423           return "tx-error";
5424         default:
5425           return "INVALID-COUNTER-TYPE";
5426         }
5427     }
5428   else
5429     {
5430       switch (counter_type)
5431         {
5432         case VNET_INTERFACE_COUNTER_RX:
5433           return "rx";
5434         case VNET_INTERFACE_COUNTER_TX:
5435           return "tx";
5436         default:
5437           return "INVALID-COUNTER-TYPE";
5438         }
5439     }
5440 }
5441
5442 static int
5443 dump_stats_table (vat_main_t * vam)
5444 {
5445   vat_json_node_t node;
5446   vat_json_node_t *msg_array;
5447   vat_json_node_t *msg;
5448   vat_json_node_t *counter_array;
5449   vat_json_node_t *counter;
5450   interface_counter_t c;
5451   u64 packets;
5452   ip4_fib_counter_t *c4;
5453   ip6_fib_counter_t *c6;
5454   ip4_nbr_counter_t *n4;
5455   ip6_nbr_counter_t *n6;
5456   int i, j;
5457
5458   if (!vam->json_output)
5459     {
5460       clib_warning ("dump_stats_table supported only in JSON format");
5461       return -99;
5462     }
5463
5464   vat_json_init_object (&node);
5465
5466   /* interface counters */
5467   msg_array = vat_json_object_add (&node, "interface_counters");
5468   vat_json_init_array (msg_array);
5469   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
5470     {
5471       msg = vat_json_array_add (msg_array);
5472       vat_json_init_object (msg);
5473       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5474                                        (u8 *) counter_type_to_str (i, 0));
5475       vat_json_object_add_int (msg, "is_combined", 0);
5476       counter_array = vat_json_object_add (msg, "data");
5477       vat_json_init_array (counter_array);
5478       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
5479         {
5480           packets = vam->simple_interface_counters[i][j];
5481           vat_json_array_add_uint (counter_array, packets);
5482         }
5483     }
5484   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
5485     {
5486       msg = vat_json_array_add (msg_array);
5487       vat_json_init_object (msg);
5488       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5489                                        (u8 *) counter_type_to_str (i, 1));
5490       vat_json_object_add_int (msg, "is_combined", 1);
5491       counter_array = vat_json_object_add (msg, "data");
5492       vat_json_init_array (counter_array);
5493       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
5494         {
5495           c = vam->combined_interface_counters[i][j];
5496           counter = vat_json_array_add (counter_array);
5497           vat_json_init_object (counter);
5498           vat_json_object_add_uint (counter, "packets", c.packets);
5499           vat_json_object_add_uint (counter, "bytes", c.bytes);
5500         }
5501     }
5502
5503   /* ip4 fib counters */
5504   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
5505   vat_json_init_array (msg_array);
5506   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
5507     {
5508       msg = vat_json_array_add (msg_array);
5509       vat_json_init_object (msg);
5510       vat_json_object_add_uint (msg, "vrf_id",
5511                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
5512       counter_array = vat_json_object_add (msg, "c");
5513       vat_json_init_array (counter_array);
5514       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
5515         {
5516           counter = vat_json_array_add (counter_array);
5517           vat_json_init_object (counter);
5518           c4 = &vam->ip4_fib_counters[i][j];
5519           vat_json_object_add_ip4 (counter, "address", c4->address);
5520           vat_json_object_add_uint (counter, "address_length",
5521                                     c4->address_length);
5522           vat_json_object_add_uint (counter, "packets", c4->packets);
5523           vat_json_object_add_uint (counter, "bytes", c4->bytes);
5524         }
5525     }
5526
5527   /* ip6 fib counters */
5528   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
5529   vat_json_init_array (msg_array);
5530   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
5531     {
5532       msg = vat_json_array_add (msg_array);
5533       vat_json_init_object (msg);
5534       vat_json_object_add_uint (msg, "vrf_id",
5535                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
5536       counter_array = vat_json_object_add (msg, "c");
5537       vat_json_init_array (counter_array);
5538       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
5539         {
5540           counter = vat_json_array_add (counter_array);
5541           vat_json_init_object (counter);
5542           c6 = &vam->ip6_fib_counters[i][j];
5543           vat_json_object_add_ip6 (counter, "address", c6->address);
5544           vat_json_object_add_uint (counter, "address_length",
5545                                     c6->address_length);
5546           vat_json_object_add_uint (counter, "packets", c6->packets);
5547           vat_json_object_add_uint (counter, "bytes", c6->bytes);
5548         }
5549     }
5550
5551   /* ip4 nbr counters */
5552   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
5553   vat_json_init_array (msg_array);
5554   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
5555     {
5556       msg = vat_json_array_add (msg_array);
5557       vat_json_init_object (msg);
5558       vat_json_object_add_uint (msg, "sw_if_index", i);
5559       counter_array = vat_json_object_add (msg, "c");
5560       vat_json_init_array (counter_array);
5561       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
5562         {
5563           counter = vat_json_array_add (counter_array);
5564           vat_json_init_object (counter);
5565           n4 = &vam->ip4_nbr_counters[i][j];
5566           vat_json_object_add_ip4 (counter, "address", n4->address);
5567           vat_json_object_add_uint (counter, "link-type", n4->linkt);
5568           vat_json_object_add_uint (counter, "packets", n4->packets);
5569           vat_json_object_add_uint (counter, "bytes", n4->bytes);
5570         }
5571     }
5572
5573   /* ip6 nbr counters */
5574   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
5575   vat_json_init_array (msg_array);
5576   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
5577     {
5578       msg = vat_json_array_add (msg_array);
5579       vat_json_init_object (msg);
5580       vat_json_object_add_uint (msg, "sw_if_index", i);
5581       counter_array = vat_json_object_add (msg, "c");
5582       vat_json_init_array (counter_array);
5583       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
5584         {
5585           counter = vat_json_array_add (counter_array);
5586           vat_json_init_object (counter);
5587           n6 = &vam->ip6_nbr_counters[i][j];
5588           vat_json_object_add_ip6 (counter, "address", n6->address);
5589           vat_json_object_add_uint (counter, "packets", n6->packets);
5590           vat_json_object_add_uint (counter, "bytes", n6->bytes);
5591         }
5592     }
5593
5594   vat_json_print (vam->ofp, &node);
5595   vat_json_free (&node);
5596
5597   return 0;
5598 }
5599
5600 int
5601 exec (vat_main_t * vam)
5602 {
5603   api_main_t *am = &api_main;
5604   vl_api_cli_t *mp;
5605   f64 timeout;
5606   void *oldheap;
5607   u8 *cmd = 0;
5608   unformat_input_t *i = vam->input;
5609
5610   if (vec_len (i->buffer) == 0)
5611     return -1;
5612
5613   if (vam->exec_mode == 0 && unformat (i, "mode"))
5614     {
5615       vam->exec_mode = 1;
5616       return 0;
5617     }
5618   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5619     {
5620       vam->exec_mode = 0;
5621       return 0;
5622     }
5623
5624
5625   M (CLI, mp);
5626
5627   /*
5628    * Copy cmd into shared memory.
5629    * In order for the CLI command to work, it
5630    * must be a vector ending in \n, not a C-string ending
5631    * in \n\0.
5632    */
5633   pthread_mutex_lock (&am->vlib_rp->mutex);
5634   oldheap = svm_push_data_heap (am->vlib_rp);
5635
5636   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
5637   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
5638
5639   svm_pop_heap (oldheap);
5640   pthread_mutex_unlock (&am->vlib_rp->mutex);
5641
5642   mp->cmd_in_shmem = pointer_to_uword (cmd);
5643   S (mp);
5644   timeout = vat_time_now (vam) + 10.0;
5645
5646   while (vat_time_now (vam) < timeout)
5647     {
5648       if (vam->result_ready == 1)
5649         {
5650           u8 *free_me;
5651           if (vam->shmem_result != NULL)
5652             print (vam->ofp, "%s", vam->shmem_result);
5653           pthread_mutex_lock (&am->vlib_rp->mutex);
5654           oldheap = svm_push_data_heap (am->vlib_rp);
5655
5656           free_me = (u8 *) vam->shmem_result;
5657           vec_free (free_me);
5658
5659           svm_pop_heap (oldheap);
5660           pthread_mutex_unlock (&am->vlib_rp->mutex);
5661           return 0;
5662         }
5663     }
5664   return -99;
5665 }
5666
5667 /*
5668  * Future replacement of exec() that passes CLI buffers directly in
5669  * the API messages instead of an additional shared memory area.
5670  */
5671 static int
5672 exec_inband (vat_main_t * vam)
5673 {
5674   vl_api_cli_inband_t *mp;
5675   unformat_input_t *i = vam->input;
5676   int ret;
5677
5678   if (vec_len (i->buffer) == 0)
5679     return -1;
5680
5681   if (vam->exec_mode == 0 && unformat (i, "mode"))
5682     {
5683       vam->exec_mode = 1;
5684       return 0;
5685     }
5686   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5687     {
5688       vam->exec_mode = 0;
5689       return 0;
5690     }
5691
5692   /*
5693    * In order for the CLI command to work, it
5694    * must be a vector ending in \n, not a C-string ending
5695    * in \n\0.
5696    */
5697   u32 len = vec_len (vam->input->buffer);
5698   M2 (CLI_INBAND, mp, len);
5699   clib_memcpy (mp->cmd, vam->input->buffer, len);
5700   mp->length = htonl (len);
5701
5702   S (mp);
5703   W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
5704   return ret;
5705 }
5706
5707 static int
5708 api_create_loopback (vat_main_t * vam)
5709 {
5710   unformat_input_t *i = vam->input;
5711   vl_api_create_loopback_t *mp;
5712   vl_api_create_loopback_instance_t *mp_lbi;
5713   u8 mac_address[6];
5714   u8 mac_set = 0;
5715   u8 is_specified = 0;
5716   u32 user_instance = 0;
5717   int ret;
5718
5719   memset (mac_address, 0, sizeof (mac_address));
5720
5721   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5722     {
5723       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5724         mac_set = 1;
5725       if (unformat (i, "instance %d", &user_instance))
5726         is_specified = 1;
5727       else
5728         break;
5729     }
5730
5731   if (is_specified)
5732     {
5733       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5734       mp_lbi->is_specified = is_specified;
5735       if (is_specified)
5736         mp_lbi->user_instance = htonl (user_instance);
5737       if (mac_set)
5738         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5739       S (mp_lbi);
5740     }
5741   else
5742     {
5743       /* Construct the API message */
5744       M (CREATE_LOOPBACK, mp);
5745       if (mac_set)
5746         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5747       S (mp);
5748     }
5749
5750   W (ret);
5751   return ret;
5752 }
5753
5754 static int
5755 api_delete_loopback (vat_main_t * vam)
5756 {
5757   unformat_input_t *i = vam->input;
5758   vl_api_delete_loopback_t *mp;
5759   u32 sw_if_index = ~0;
5760   int ret;
5761
5762   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5763     {
5764       if (unformat (i, "sw_if_index %d", &sw_if_index))
5765         ;
5766       else
5767         break;
5768     }
5769
5770   if (sw_if_index == ~0)
5771     {
5772       errmsg ("missing sw_if_index");
5773       return -99;
5774     }
5775
5776   /* Construct the API message */
5777   M (DELETE_LOOPBACK, mp);
5778   mp->sw_if_index = ntohl (sw_if_index);
5779
5780   S (mp);
5781   W (ret);
5782   return ret;
5783 }
5784
5785 static int
5786 api_want_stats (vat_main_t * vam)
5787 {
5788   unformat_input_t *i = vam->input;
5789   vl_api_want_stats_t *mp;
5790   int enable = -1;
5791   int ret;
5792
5793   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5794     {
5795       if (unformat (i, "enable"))
5796         enable = 1;
5797       else if (unformat (i, "disable"))
5798         enable = 0;
5799       else
5800         break;
5801     }
5802
5803   if (enable == -1)
5804     {
5805       errmsg ("missing enable|disable");
5806       return -99;
5807     }
5808
5809   M (WANT_STATS, mp);
5810   mp->enable_disable = enable;
5811
5812   S (mp);
5813   W (ret);
5814   return ret;
5815 }
5816
5817 static int
5818 api_want_interface_events (vat_main_t * vam)
5819 {
5820   unformat_input_t *i = vam->input;
5821   vl_api_want_interface_events_t *mp;
5822   int enable = -1;
5823   int ret;
5824
5825   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5826     {
5827       if (unformat (i, "enable"))
5828         enable = 1;
5829       else if (unformat (i, "disable"))
5830         enable = 0;
5831       else
5832         break;
5833     }
5834
5835   if (enable == -1)
5836     {
5837       errmsg ("missing enable|disable");
5838       return -99;
5839     }
5840
5841   M (WANT_INTERFACE_EVENTS, mp);
5842   mp->enable_disable = enable;
5843
5844   vam->interface_event_display = enable;
5845
5846   S (mp);
5847   W (ret);
5848   return ret;
5849 }
5850
5851
5852 /* Note: non-static, called once to set up the initial intfc table */
5853 int
5854 api_sw_interface_dump (vat_main_t * vam)
5855 {
5856   vl_api_sw_interface_dump_t *mp;
5857   vl_api_control_ping_t *mp_ping;
5858   hash_pair_t *p;
5859   name_sort_t *nses = 0, *ns;
5860   sw_interface_subif_t *sub = NULL;
5861   int ret;
5862
5863   /* Toss the old name table */
5864   /* *INDENT-OFF* */
5865   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5866   ({
5867     vec_add2 (nses, ns, 1);
5868     ns->name = (u8 *)(p->key);
5869     ns->value = (u32) p->value[0];
5870   }));
5871   /* *INDENT-ON* */
5872
5873   hash_free (vam->sw_if_index_by_interface_name);
5874
5875   vec_foreach (ns, nses) vec_free (ns->name);
5876
5877   vec_free (nses);
5878
5879   vec_foreach (sub, vam->sw_if_subif_table)
5880   {
5881     vec_free (sub->interface_name);
5882   }
5883   vec_free (vam->sw_if_subif_table);
5884
5885   /* recreate the interface name hash table */
5886   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5887
5888   /* Get list of ethernets */
5889   M (SW_INTERFACE_DUMP, mp);
5890   mp->name_filter_valid = 1;
5891   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
5892   S (mp);
5893
5894   /* and local / loopback interfaces */
5895   M (SW_INTERFACE_DUMP, mp);
5896   mp->name_filter_valid = 1;
5897   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
5898   S (mp);
5899
5900   /* and packet-generator interfaces */
5901   M (SW_INTERFACE_DUMP, mp);
5902   mp->name_filter_valid = 1;
5903   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
5904   S (mp);
5905
5906   /* and vxlan-gpe tunnel interfaces */
5907   M (SW_INTERFACE_DUMP, mp);
5908   mp->name_filter_valid = 1;
5909   strncpy ((char *) mp->name_filter, "vxlan_gpe",
5910            sizeof (mp->name_filter) - 1);
5911   S (mp);
5912
5913   /* and vxlan tunnel interfaces */
5914   M (SW_INTERFACE_DUMP, mp);
5915   mp->name_filter_valid = 1;
5916   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
5917   S (mp);
5918
5919   /* and host (af_packet) interfaces */
5920   M (SW_INTERFACE_DUMP, mp);
5921   mp->name_filter_valid = 1;
5922   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
5923   S (mp);
5924
5925   /* and l2tpv3 tunnel interfaces */
5926   M (SW_INTERFACE_DUMP, mp);
5927   mp->name_filter_valid = 1;
5928   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
5929            sizeof (mp->name_filter) - 1);
5930   S (mp);
5931
5932   /* and GRE tunnel interfaces */
5933   M (SW_INTERFACE_DUMP, mp);
5934   mp->name_filter_valid = 1;
5935   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
5936   S (mp);
5937
5938   /* and LISP-GPE interfaces */
5939   M (SW_INTERFACE_DUMP, mp);
5940   mp->name_filter_valid = 1;
5941   strncpy ((char *) mp->name_filter, "lisp_gpe",
5942            sizeof (mp->name_filter) - 1);
5943   S (mp);
5944
5945   /* and IPSEC tunnel interfaces */
5946   M (SW_INTERFACE_DUMP, mp);
5947   mp->name_filter_valid = 1;
5948   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
5949   S (mp);
5950
5951   /* Use a control ping for synchronization */
5952   M (CONTROL_PING, mp_ping);
5953   S (mp_ping);
5954
5955   W (ret);
5956   return ret;
5957 }
5958
5959 static int
5960 api_sw_interface_set_flags (vat_main_t * vam)
5961 {
5962   unformat_input_t *i = vam->input;
5963   vl_api_sw_interface_set_flags_t *mp;
5964   u32 sw_if_index;
5965   u8 sw_if_index_set = 0;
5966   u8 admin_up = 0;
5967   int ret;
5968
5969   /* Parse args required to build the message */
5970   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5971     {
5972       if (unformat (i, "admin-up"))
5973         admin_up = 1;
5974       else if (unformat (i, "admin-down"))
5975         admin_up = 0;
5976       else
5977         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5978         sw_if_index_set = 1;
5979       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5980         sw_if_index_set = 1;
5981       else
5982         break;
5983     }
5984
5985   if (sw_if_index_set == 0)
5986     {
5987       errmsg ("missing interface name or sw_if_index");
5988       return -99;
5989     }
5990
5991   /* Construct the API message */
5992   M (SW_INTERFACE_SET_FLAGS, mp);
5993   mp->sw_if_index = ntohl (sw_if_index);
5994   mp->admin_up_down = admin_up;
5995
5996   /* send it... */
5997   S (mp);
5998
5999   /* Wait for a reply, return the good/bad news... */
6000   W (ret);
6001   return ret;
6002 }
6003
6004 static int
6005 api_sw_interface_clear_stats (vat_main_t * vam)
6006 {
6007   unformat_input_t *i = vam->input;
6008   vl_api_sw_interface_clear_stats_t *mp;
6009   u32 sw_if_index;
6010   u8 sw_if_index_set = 0;
6011   int ret;
6012
6013   /* Parse args required to build the message */
6014   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6015     {
6016       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6017         sw_if_index_set = 1;
6018       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6019         sw_if_index_set = 1;
6020       else
6021         break;
6022     }
6023
6024   /* Construct the API message */
6025   M (SW_INTERFACE_CLEAR_STATS, mp);
6026
6027   if (sw_if_index_set == 1)
6028     mp->sw_if_index = ntohl (sw_if_index);
6029   else
6030     mp->sw_if_index = ~0;
6031
6032   /* send it... */
6033   S (mp);
6034
6035   /* Wait for a reply, return the good/bad news... */
6036   W (ret);
6037   return ret;
6038 }
6039
6040 static int
6041 api_sw_interface_add_del_address (vat_main_t * vam)
6042 {
6043   unformat_input_t *i = vam->input;
6044   vl_api_sw_interface_add_del_address_t *mp;
6045   u32 sw_if_index;
6046   u8 sw_if_index_set = 0;
6047   u8 is_add = 1, del_all = 0;
6048   u32 address_length = 0;
6049   u8 v4_address_set = 0;
6050   u8 v6_address_set = 0;
6051   ip4_address_t v4address;
6052   ip6_address_t v6address;
6053   int ret;
6054
6055   /* Parse args required to build the message */
6056   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6057     {
6058       if (unformat (i, "del-all"))
6059         del_all = 1;
6060       else if (unformat (i, "del"))
6061         is_add = 0;
6062       else
6063         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6064         sw_if_index_set = 1;
6065       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6066         sw_if_index_set = 1;
6067       else if (unformat (i, "%U/%d",
6068                          unformat_ip4_address, &v4address, &address_length))
6069         v4_address_set = 1;
6070       else if (unformat (i, "%U/%d",
6071                          unformat_ip6_address, &v6address, &address_length))
6072         v6_address_set = 1;
6073       else
6074         break;
6075     }
6076
6077   if (sw_if_index_set == 0)
6078     {
6079       errmsg ("missing interface name or sw_if_index");
6080       return -99;
6081     }
6082   if (v4_address_set && v6_address_set)
6083     {
6084       errmsg ("both v4 and v6 addresses set");
6085       return -99;
6086     }
6087   if (!v4_address_set && !v6_address_set && !del_all)
6088     {
6089       errmsg ("no addresses set");
6090       return -99;
6091     }
6092
6093   /* Construct the API message */
6094   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6095
6096   mp->sw_if_index = ntohl (sw_if_index);
6097   mp->is_add = is_add;
6098   mp->del_all = del_all;
6099   if (v6_address_set)
6100     {
6101       mp->is_ipv6 = 1;
6102       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6103     }
6104   else
6105     {
6106       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6107     }
6108   mp->address_length = address_length;
6109
6110   /* send it... */
6111   S (mp);
6112
6113   /* Wait for a reply, return good/bad news  */
6114   W (ret);
6115   return ret;
6116 }
6117
6118 static int
6119 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6120 {
6121   unformat_input_t *i = vam->input;
6122   vl_api_sw_interface_set_mpls_enable_t *mp;
6123   u32 sw_if_index;
6124   u8 sw_if_index_set = 0;
6125   u8 enable = 1;
6126   int ret;
6127
6128   /* Parse args required to build the message */
6129   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6130     {
6131       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6132         sw_if_index_set = 1;
6133       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6134         sw_if_index_set = 1;
6135       else if (unformat (i, "disable"))
6136         enable = 0;
6137       else if (unformat (i, "dis"))
6138         enable = 0;
6139       else
6140         break;
6141     }
6142
6143   if (sw_if_index_set == 0)
6144     {
6145       errmsg ("missing interface name or sw_if_index");
6146       return -99;
6147     }
6148
6149   /* Construct the API message */
6150   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6151
6152   mp->sw_if_index = ntohl (sw_if_index);
6153   mp->enable = enable;
6154
6155   /* send it... */
6156   S (mp);
6157
6158   /* Wait for a reply... */
6159   W (ret);
6160   return ret;
6161 }
6162
6163 static int
6164 api_sw_interface_set_table (vat_main_t * vam)
6165 {
6166   unformat_input_t *i = vam->input;
6167   vl_api_sw_interface_set_table_t *mp;
6168   u32 sw_if_index, vrf_id = 0;
6169   u8 sw_if_index_set = 0;
6170   u8 is_ipv6 = 0;
6171   int ret;
6172
6173   /* Parse args required to build the message */
6174   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6175     {
6176       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6177         sw_if_index_set = 1;
6178       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6179         sw_if_index_set = 1;
6180       else if (unformat (i, "vrf %d", &vrf_id))
6181         ;
6182       else if (unformat (i, "ipv6"))
6183         is_ipv6 = 1;
6184       else
6185         break;
6186     }
6187
6188   if (sw_if_index_set == 0)
6189     {
6190       errmsg ("missing interface name or sw_if_index");
6191       return -99;
6192     }
6193
6194   /* Construct the API message */
6195   M (SW_INTERFACE_SET_TABLE, mp);
6196
6197   mp->sw_if_index = ntohl (sw_if_index);
6198   mp->is_ipv6 = is_ipv6;
6199   mp->vrf_id = ntohl (vrf_id);
6200
6201   /* send it... */
6202   S (mp);
6203
6204   /* Wait for a reply... */
6205   W (ret);
6206   return ret;
6207 }
6208
6209 static void vl_api_sw_interface_get_table_reply_t_handler
6210   (vl_api_sw_interface_get_table_reply_t * mp)
6211 {
6212   vat_main_t *vam = &vat_main;
6213
6214   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6215
6216   vam->retval = ntohl (mp->retval);
6217   vam->result_ready = 1;
6218
6219 }
6220
6221 static void vl_api_sw_interface_get_table_reply_t_handler_json
6222   (vl_api_sw_interface_get_table_reply_t * mp)
6223 {
6224   vat_main_t *vam = &vat_main;
6225   vat_json_node_t node;
6226
6227   vat_json_init_object (&node);
6228   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6229   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6230
6231   vat_json_print (vam->ofp, &node);
6232   vat_json_free (&node);
6233
6234   vam->retval = ntohl (mp->retval);
6235   vam->result_ready = 1;
6236 }
6237
6238 static int
6239 api_sw_interface_get_table (vat_main_t * vam)
6240 {
6241   unformat_input_t *i = vam->input;
6242   vl_api_sw_interface_get_table_t *mp;
6243   u32 sw_if_index;
6244   u8 sw_if_index_set = 0;
6245   u8 is_ipv6 = 0;
6246   int ret;
6247
6248   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6249     {
6250       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6251         sw_if_index_set = 1;
6252       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6253         sw_if_index_set = 1;
6254       else if (unformat (i, "ipv6"))
6255         is_ipv6 = 1;
6256       else
6257         break;
6258     }
6259
6260   if (sw_if_index_set == 0)
6261     {
6262       errmsg ("missing interface name or sw_if_index");
6263       return -99;
6264     }
6265
6266   M (SW_INTERFACE_GET_TABLE, mp);
6267   mp->sw_if_index = htonl (sw_if_index);
6268   mp->is_ipv6 = is_ipv6;
6269
6270   S (mp);
6271   W (ret);
6272   return ret;
6273 }
6274
6275 static int
6276 api_sw_interface_set_vpath (vat_main_t * vam)
6277 {
6278   unformat_input_t *i = vam->input;
6279   vl_api_sw_interface_set_vpath_t *mp;
6280   u32 sw_if_index = 0;
6281   u8 sw_if_index_set = 0;
6282   u8 is_enable = 0;
6283   int ret;
6284
6285   /* Parse args required to build the message */
6286   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6287     {
6288       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6289         sw_if_index_set = 1;
6290       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6291         sw_if_index_set = 1;
6292       else if (unformat (i, "enable"))
6293         is_enable = 1;
6294       else if (unformat (i, "disable"))
6295         is_enable = 0;
6296       else
6297         break;
6298     }
6299
6300   if (sw_if_index_set == 0)
6301     {
6302       errmsg ("missing interface name or sw_if_index");
6303       return -99;
6304     }
6305
6306   /* Construct the API message */
6307   M (SW_INTERFACE_SET_VPATH, mp);
6308
6309   mp->sw_if_index = ntohl (sw_if_index);
6310   mp->enable = is_enable;
6311
6312   /* send it... */
6313   S (mp);
6314
6315   /* Wait for a reply... */
6316   W (ret);
6317   return ret;
6318 }
6319
6320 static int
6321 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6322 {
6323   unformat_input_t *i = vam->input;
6324   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6325   u32 sw_if_index = 0;
6326   u8 sw_if_index_set = 0;
6327   u8 is_enable = 1;
6328   u8 is_ipv6 = 0;
6329   int ret;
6330
6331   /* Parse args required to build the message */
6332   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6333     {
6334       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6335         sw_if_index_set = 1;
6336       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6337         sw_if_index_set = 1;
6338       else if (unformat (i, "enable"))
6339         is_enable = 1;
6340       else if (unformat (i, "disable"))
6341         is_enable = 0;
6342       else if (unformat (i, "ip4"))
6343         is_ipv6 = 0;
6344       else if (unformat (i, "ip6"))
6345         is_ipv6 = 1;
6346       else
6347         break;
6348     }
6349
6350   if (sw_if_index_set == 0)
6351     {
6352       errmsg ("missing interface name or sw_if_index");
6353       return -99;
6354     }
6355
6356   /* Construct the API message */
6357   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6358
6359   mp->sw_if_index = ntohl (sw_if_index);
6360   mp->enable = is_enable;
6361   mp->is_ipv6 = is_ipv6;
6362
6363   /* send it... */
6364   S (mp);
6365
6366   /* Wait for a reply... */
6367   W (ret);
6368   return ret;
6369 }
6370
6371
6372 static int
6373 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6374 {
6375   unformat_input_t *i = vam->input;
6376   vl_api_sw_interface_set_l2_xconnect_t *mp;
6377   u32 rx_sw_if_index;
6378   u8 rx_sw_if_index_set = 0;
6379   u32 tx_sw_if_index;
6380   u8 tx_sw_if_index_set = 0;
6381   u8 enable = 1;
6382   int ret;
6383
6384   /* Parse args required to build the message */
6385   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6386     {
6387       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6388         rx_sw_if_index_set = 1;
6389       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6390         tx_sw_if_index_set = 1;
6391       else if (unformat (i, "rx"))
6392         {
6393           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6394             {
6395               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6396                             &rx_sw_if_index))
6397                 rx_sw_if_index_set = 1;
6398             }
6399           else
6400             break;
6401         }
6402       else if (unformat (i, "tx"))
6403         {
6404           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6405             {
6406               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6407                             &tx_sw_if_index))
6408                 tx_sw_if_index_set = 1;
6409             }
6410           else
6411             break;
6412         }
6413       else if (unformat (i, "enable"))
6414         enable = 1;
6415       else if (unformat (i, "disable"))
6416         enable = 0;
6417       else
6418         break;
6419     }
6420
6421   if (rx_sw_if_index_set == 0)
6422     {
6423       errmsg ("missing rx interface name or rx_sw_if_index");
6424       return -99;
6425     }
6426
6427   if (enable && (tx_sw_if_index_set == 0))
6428     {
6429       errmsg ("missing tx interface name or tx_sw_if_index");
6430       return -99;
6431     }
6432
6433   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6434
6435   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6436   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6437   mp->enable = enable;
6438
6439   S (mp);
6440   W (ret);
6441   return ret;
6442 }
6443
6444 static int
6445 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6446 {
6447   unformat_input_t *i = vam->input;
6448   vl_api_sw_interface_set_l2_bridge_t *mp;
6449   u32 rx_sw_if_index;
6450   u8 rx_sw_if_index_set = 0;
6451   u32 bd_id;
6452   u8 bd_id_set = 0;
6453   u8 bvi = 0;
6454   u32 shg = 0;
6455   u8 enable = 1;
6456   int ret;
6457
6458   /* Parse args required to build the message */
6459   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6460     {
6461       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6462         rx_sw_if_index_set = 1;
6463       else if (unformat (i, "bd_id %d", &bd_id))
6464         bd_id_set = 1;
6465       else
6466         if (unformat
6467             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6468         rx_sw_if_index_set = 1;
6469       else if (unformat (i, "shg %d", &shg))
6470         ;
6471       else if (unformat (i, "bvi"))
6472         bvi = 1;
6473       else if (unformat (i, "enable"))
6474         enable = 1;
6475       else if (unformat (i, "disable"))
6476         enable = 0;
6477       else
6478         break;
6479     }
6480
6481   if (rx_sw_if_index_set == 0)
6482     {
6483       errmsg ("missing rx interface name or sw_if_index");
6484       return -99;
6485     }
6486
6487   if (enable && (bd_id_set == 0))
6488     {
6489       errmsg ("missing bridge domain");
6490       return -99;
6491     }
6492
6493   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6494
6495   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6496   mp->bd_id = ntohl (bd_id);
6497   mp->shg = (u8) shg;
6498   mp->bvi = bvi;
6499   mp->enable = enable;
6500
6501   S (mp);
6502   W (ret);
6503   return ret;
6504 }
6505
6506 static int
6507 api_bridge_domain_dump (vat_main_t * vam)
6508 {
6509   unformat_input_t *i = vam->input;
6510   vl_api_bridge_domain_dump_t *mp;
6511   vl_api_control_ping_t *mp_ping;
6512   u32 bd_id = ~0;
6513   int ret;
6514
6515   /* Parse args required to build the message */
6516   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6517     {
6518       if (unformat (i, "bd_id %d", &bd_id))
6519         ;
6520       else
6521         break;
6522     }
6523
6524   M (BRIDGE_DOMAIN_DUMP, mp);
6525   mp->bd_id = ntohl (bd_id);
6526   S (mp);
6527
6528   /* Use a control ping for synchronization */
6529   M (CONTROL_PING, mp_ping);
6530   S (mp_ping);
6531
6532   W (ret);
6533   return ret;
6534 }
6535
6536 static int
6537 api_bridge_domain_add_del (vat_main_t * vam)
6538 {
6539   unformat_input_t *i = vam->input;
6540   vl_api_bridge_domain_add_del_t *mp;
6541   u32 bd_id = ~0;
6542   u8 is_add = 1;
6543   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6544   u8 *bd_tag = NULL;
6545   u32 mac_age = 0;
6546   int ret;
6547
6548   /* Parse args required to build the message */
6549   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6550     {
6551       if (unformat (i, "bd_id %d", &bd_id))
6552         ;
6553       else if (unformat (i, "flood %d", &flood))
6554         ;
6555       else if (unformat (i, "uu-flood %d", &uu_flood))
6556         ;
6557       else if (unformat (i, "forward %d", &forward))
6558         ;
6559       else if (unformat (i, "learn %d", &learn))
6560         ;
6561       else if (unformat (i, "arp-term %d", &arp_term))
6562         ;
6563       else if (unformat (i, "mac-age %d", &mac_age))
6564         ;
6565       else if (unformat (i, "bd-tag %s", &bd_tag))
6566         ;
6567       else if (unformat (i, "del"))
6568         {
6569           is_add = 0;
6570           flood = uu_flood = forward = learn = 0;
6571         }
6572       else
6573         break;
6574     }
6575
6576   if (bd_id == ~0)
6577     {
6578       errmsg ("missing bridge domain");
6579       ret = -99;
6580       goto done;
6581     }
6582
6583   if (mac_age > 255)
6584     {
6585       errmsg ("mac age must be less than 256 ");
6586       ret = -99;
6587       goto done;
6588     }
6589
6590   if ((bd_tag) && (strlen ((char *) bd_tag) > 63))
6591     {
6592       errmsg ("bd-tag cannot be longer than 63");
6593       ret = -99;
6594       goto done;
6595     }
6596
6597   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6598
6599   mp->bd_id = ntohl (bd_id);
6600   mp->flood = flood;
6601   mp->uu_flood = uu_flood;
6602   mp->forward = forward;
6603   mp->learn = learn;
6604   mp->arp_term = arp_term;
6605   mp->is_add = is_add;
6606   mp->mac_age = (u8) mac_age;
6607   if (bd_tag)
6608     strcpy ((char *) mp->bd_tag, (char *) bd_tag);
6609
6610   S (mp);
6611   W (ret);
6612
6613 done:
6614   vec_free (bd_tag);
6615   return ret;
6616 }
6617
6618 static int
6619 api_l2fib_flush_bd (vat_main_t * vam)
6620 {
6621   unformat_input_t *i = vam->input;
6622   vl_api_l2fib_flush_bd_t *mp;
6623   u32 bd_id = ~0;
6624   int ret;
6625
6626   /* Parse args required to build the message */
6627   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6628     {
6629       if (unformat (i, "bd_id %d", &bd_id));
6630       else
6631         break;
6632     }
6633
6634   if (bd_id == ~0)
6635     {
6636       errmsg ("missing bridge domain");
6637       return -99;
6638     }
6639
6640   M (L2FIB_FLUSH_BD, mp);
6641
6642   mp->bd_id = htonl (bd_id);
6643
6644   S (mp);
6645   W (ret);
6646   return ret;
6647 }
6648
6649 static int
6650 api_l2fib_flush_int (vat_main_t * vam)
6651 {
6652   unformat_input_t *i = vam->input;
6653   vl_api_l2fib_flush_int_t *mp;
6654   u32 sw_if_index = ~0;
6655   int ret;
6656
6657   /* Parse args required to build the message */
6658   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6659     {
6660       if (unformat (i, "sw_if_index %d", &sw_if_index));
6661       else
6662         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6663       else
6664         break;
6665     }
6666
6667   if (sw_if_index == ~0)
6668     {
6669       errmsg ("missing interface name or sw_if_index");
6670       return -99;
6671     }
6672
6673   M (L2FIB_FLUSH_INT, mp);
6674
6675   mp->sw_if_index = ntohl (sw_if_index);
6676
6677   S (mp);
6678   W (ret);
6679   return ret;
6680 }
6681
6682 static int
6683 api_l2fib_add_del (vat_main_t * vam)
6684 {
6685   unformat_input_t *i = vam->input;
6686   vl_api_l2fib_add_del_t *mp;
6687   f64 timeout;
6688   u64 mac = 0;
6689   u8 mac_set = 0;
6690   u32 bd_id;
6691   u8 bd_id_set = 0;
6692   u32 sw_if_index = ~0;
6693   u8 sw_if_index_set = 0;
6694   u8 is_add = 1;
6695   u8 static_mac = 0;
6696   u8 filter_mac = 0;
6697   u8 bvi_mac = 0;
6698   int count = 1;
6699   f64 before = 0;
6700   int j;
6701
6702   /* Parse args required to build the message */
6703   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6704     {
6705       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
6706         mac_set = 1;
6707       else if (unformat (i, "bd_id %d", &bd_id))
6708         bd_id_set = 1;
6709       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6710         sw_if_index_set = 1;
6711       else if (unformat (i, "sw_if"))
6712         {
6713           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6714             {
6715               if (unformat
6716                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6717                 sw_if_index_set = 1;
6718             }
6719           else
6720             break;
6721         }
6722       else if (unformat (i, "static"))
6723         static_mac = 1;
6724       else if (unformat (i, "filter"))
6725         {
6726           filter_mac = 1;
6727           static_mac = 1;
6728         }
6729       else if (unformat (i, "bvi"))
6730         {
6731           bvi_mac = 1;
6732           static_mac = 1;
6733         }
6734       else if (unformat (i, "del"))
6735         is_add = 0;
6736       else if (unformat (i, "count %d", &count))
6737         ;
6738       else
6739         break;
6740     }
6741
6742   if (mac_set == 0)
6743     {
6744       errmsg ("missing mac address");
6745       return -99;
6746     }
6747
6748   if (bd_id_set == 0)
6749     {
6750       errmsg ("missing bridge domain");
6751       return -99;
6752     }
6753
6754   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6755     {
6756       errmsg ("missing interface name or sw_if_index");
6757       return -99;
6758     }
6759
6760   if (count > 1)
6761     {
6762       /* Turn on async mode */
6763       vam->async_mode = 1;
6764       vam->async_errors = 0;
6765       before = vat_time_now (vam);
6766     }
6767
6768   for (j = 0; j < count; j++)
6769     {
6770       M (L2FIB_ADD_DEL, mp);
6771
6772       mp->mac = mac;
6773       mp->bd_id = ntohl (bd_id);
6774       mp->is_add = is_add;
6775
6776       if (is_add)
6777         {
6778           mp->sw_if_index = ntohl (sw_if_index);
6779           mp->static_mac = static_mac;
6780           mp->filter_mac = filter_mac;
6781           mp->bvi_mac = bvi_mac;
6782         }
6783       increment_mac_address (&mac);
6784       /* send it... */
6785       S (mp);
6786     }
6787
6788   if (count > 1)
6789     {
6790       vl_api_control_ping_t *mp_ping;
6791       f64 after;
6792
6793       /* Shut off async mode */
6794       vam->async_mode = 0;
6795
6796       M (CONTROL_PING, mp_ping);
6797       S (mp_ping);
6798
6799       timeout = vat_time_now (vam) + 1.0;
6800       while (vat_time_now (vam) < timeout)
6801         if (vam->result_ready == 1)
6802           goto out;
6803       vam->retval = -99;
6804
6805     out:
6806       if (vam->retval == -99)
6807         errmsg ("timeout");
6808
6809       if (vam->async_errors > 0)
6810         {
6811           errmsg ("%d asynchronous errors", vam->async_errors);
6812           vam->retval = -98;
6813         }
6814       vam->async_errors = 0;
6815       after = vat_time_now (vam);
6816
6817       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6818              count, after - before, count / (after - before));
6819     }
6820   else
6821     {
6822       int ret;
6823
6824       /* Wait for a reply... */
6825       W (ret);
6826       return ret;
6827     }
6828   /* Return the good/bad news */
6829   return (vam->retval);
6830 }
6831
6832 static int
6833 api_bridge_domain_set_mac_age (vat_main_t * vam)
6834 {
6835   unformat_input_t *i = vam->input;
6836   vl_api_bridge_domain_set_mac_age_t *mp;
6837   u32 bd_id = ~0;
6838   u32 mac_age = 0;
6839   int ret;
6840
6841   /* Parse args required to build the message */
6842   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6843     {
6844       if (unformat (i, "bd_id %d", &bd_id));
6845       else if (unformat (i, "mac-age %d", &mac_age));
6846       else
6847         break;
6848     }
6849
6850   if (bd_id == ~0)
6851     {
6852       errmsg ("missing bridge domain");
6853       return -99;
6854     }
6855
6856   if (mac_age > 255)
6857     {
6858       errmsg ("mac age must be less than 256 ");
6859       return -99;
6860     }
6861
6862   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6863
6864   mp->bd_id = htonl (bd_id);
6865   mp->mac_age = (u8) mac_age;
6866
6867   S (mp);
6868   W (ret);
6869   return ret;
6870 }
6871
6872 static int
6873 api_l2_flags (vat_main_t * vam)
6874 {
6875   unformat_input_t *i = vam->input;
6876   vl_api_l2_flags_t *mp;
6877   u32 sw_if_index;
6878   u32 flags = 0;
6879   u8 sw_if_index_set = 0;
6880   u8 is_set = 0;
6881   int ret;
6882
6883   /* Parse args required to build the message */
6884   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6885     {
6886       if (unformat (i, "sw_if_index %d", &sw_if_index))
6887         sw_if_index_set = 1;
6888       else if (unformat (i, "sw_if"))
6889         {
6890           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6891             {
6892               if (unformat
6893                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6894                 sw_if_index_set = 1;
6895             }
6896           else
6897             break;
6898         }
6899       else if (unformat (i, "learn"))
6900         flags |= L2_LEARN;
6901       else if (unformat (i, "forward"))
6902         flags |= L2_FWD;
6903       else if (unformat (i, "flood"))
6904         flags |= L2_FLOOD;
6905       else if (unformat (i, "uu-flood"))
6906         flags |= L2_UU_FLOOD;
6907       else if (unformat (i, "arp-term"))
6908         flags |= L2_ARP_TERM;
6909       else if (unformat (i, "off"))
6910         is_set = 0;
6911       else if (unformat (i, "disable"))
6912         is_set = 0;
6913       else
6914         break;
6915     }
6916
6917   if (sw_if_index_set == 0)
6918     {
6919       errmsg ("missing interface name or sw_if_index");
6920       return -99;
6921     }
6922
6923   M (L2_FLAGS, mp);
6924
6925   mp->sw_if_index = ntohl (sw_if_index);
6926   mp->feature_bitmap = ntohl (flags);
6927   mp->is_set = is_set;
6928
6929   S (mp);
6930   W (ret);
6931   return ret;
6932 }
6933
6934 static int
6935 api_bridge_flags (vat_main_t * vam)
6936 {
6937   unformat_input_t *i = vam->input;
6938   vl_api_bridge_flags_t *mp;
6939   u32 bd_id;
6940   u8 bd_id_set = 0;
6941   u8 is_set = 1;
6942   u32 flags = 0;
6943   int ret;
6944
6945   /* Parse args required to build the message */
6946   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6947     {
6948       if (unformat (i, "bd_id %d", &bd_id))
6949         bd_id_set = 1;
6950       else if (unformat (i, "learn"))
6951         flags |= L2_LEARN;
6952       else if (unformat (i, "forward"))
6953         flags |= L2_FWD;
6954       else if (unformat (i, "flood"))
6955         flags |= L2_FLOOD;
6956       else if (unformat (i, "uu-flood"))
6957         flags |= L2_UU_FLOOD;
6958       else if (unformat (i, "arp-term"))
6959         flags |= L2_ARP_TERM;
6960       else if (unformat (i, "off"))
6961         is_set = 0;
6962       else if (unformat (i, "disable"))
6963         is_set = 0;
6964       else
6965         break;
6966     }
6967
6968   if (bd_id_set == 0)
6969     {
6970       errmsg ("missing bridge domain");
6971       return -99;
6972     }
6973
6974   M (BRIDGE_FLAGS, mp);
6975
6976   mp->bd_id = ntohl (bd_id);
6977   mp->feature_bitmap = ntohl (flags);
6978   mp->is_set = is_set;
6979
6980   S (mp);
6981   W (ret);
6982   return ret;
6983 }
6984
6985 static int
6986 api_bd_ip_mac_add_del (vat_main_t * vam)
6987 {
6988   unformat_input_t *i = vam->input;
6989   vl_api_bd_ip_mac_add_del_t *mp;
6990   u32 bd_id;
6991   u8 is_ipv6 = 0;
6992   u8 is_add = 1;
6993   u8 bd_id_set = 0;
6994   u8 ip_set = 0;
6995   u8 mac_set = 0;
6996   ip4_address_t v4addr;
6997   ip6_address_t v6addr;
6998   u8 macaddr[6];
6999   int ret;
7000
7001
7002   /* Parse args required to build the message */
7003   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7004     {
7005       if (unformat (i, "bd_id %d", &bd_id))
7006         {
7007           bd_id_set++;
7008         }
7009       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7010         {
7011           ip_set++;
7012         }
7013       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7014         {
7015           ip_set++;
7016           is_ipv6++;
7017         }
7018       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7019         {
7020           mac_set++;
7021         }
7022       else if (unformat (i, "del"))
7023         is_add = 0;
7024       else
7025         break;
7026     }
7027
7028   if (bd_id_set == 0)
7029     {
7030       errmsg ("missing bridge domain");
7031       return -99;
7032     }
7033   else if (ip_set == 0)
7034     {
7035       errmsg ("missing IP address");
7036       return -99;
7037     }
7038   else if (mac_set == 0)
7039     {
7040       errmsg ("missing MAC address");
7041       return -99;
7042     }
7043
7044   M (BD_IP_MAC_ADD_DEL, mp);
7045
7046   mp->bd_id = ntohl (bd_id);
7047   mp->is_ipv6 = is_ipv6;
7048   mp->is_add = is_add;
7049   if (is_ipv6)
7050     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7051   else
7052     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7053   clib_memcpy (mp->mac_address, macaddr, 6);
7054   S (mp);
7055   W (ret);
7056   return ret;
7057 }
7058
7059 static int
7060 api_tap_connect (vat_main_t * vam)
7061 {
7062   unformat_input_t *i = vam->input;
7063   vl_api_tap_connect_t *mp;
7064   u8 mac_address[6];
7065   u8 random_mac = 1;
7066   u8 name_set = 0;
7067   u8 *tap_name;
7068   u8 *tag = 0;
7069   ip4_address_t ip4_address;
7070   u32 ip4_mask_width;
7071   int ip4_address_set = 0;
7072   ip6_address_t ip6_address;
7073   u32 ip6_mask_width;
7074   int ip6_address_set = 0;
7075   int ret;
7076
7077   memset (mac_address, 0, sizeof (mac_address));
7078
7079   /* Parse args required to build the message */
7080   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7081     {
7082       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7083         {
7084           random_mac = 0;
7085         }
7086       else if (unformat (i, "random-mac"))
7087         random_mac = 1;
7088       else if (unformat (i, "tapname %s", &tap_name))
7089         name_set = 1;
7090       else if (unformat (i, "tag %s", &tag))
7091         ;
7092       else if (unformat (i, "address %U/%d",
7093                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7094         ip4_address_set = 1;
7095       else if (unformat (i, "address %U/%d",
7096                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7097         ip6_address_set = 1;
7098       else
7099         break;
7100     }
7101
7102   if (name_set == 0)
7103     {
7104       errmsg ("missing tap name");
7105       return -99;
7106     }
7107   if (vec_len (tap_name) > 63)
7108     {
7109       errmsg ("tap name too long");
7110       return -99;
7111     }
7112   vec_add1 (tap_name, 0);
7113
7114   if (vec_len (tag) > 63)
7115     {
7116       errmsg ("tag too long");
7117       return -99;
7118     }
7119
7120   /* Construct the API message */
7121   M (TAP_CONNECT, mp);
7122
7123   mp->use_random_mac = random_mac;
7124   clib_memcpy (mp->mac_address, mac_address, 6);
7125   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7126   if (tag)
7127     clib_memcpy (mp->tag, tag, vec_len (tag));
7128
7129   if (ip4_address_set)
7130     {
7131       mp->ip4_address_set = 1;
7132       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7133       mp->ip4_mask_width = ip4_mask_width;
7134     }
7135   if (ip6_address_set)
7136     {
7137       mp->ip6_address_set = 1;
7138       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7139       mp->ip6_mask_width = ip6_mask_width;
7140     }
7141
7142   vec_free (tap_name);
7143   vec_free (tag);
7144
7145   /* send it... */
7146   S (mp);
7147
7148   /* Wait for a reply... */
7149   W (ret);
7150   return ret;
7151 }
7152
7153 static int
7154 api_tap_modify (vat_main_t * vam)
7155 {
7156   unformat_input_t *i = vam->input;
7157   vl_api_tap_modify_t *mp;
7158   u8 mac_address[6];
7159   u8 random_mac = 1;
7160   u8 name_set = 0;
7161   u8 *tap_name;
7162   u32 sw_if_index = ~0;
7163   u8 sw_if_index_set = 0;
7164   int ret;
7165
7166   memset (mac_address, 0, sizeof (mac_address));
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 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7176         {
7177           random_mac = 0;
7178         }
7179       else if (unformat (i, "random-mac"))
7180         random_mac = 1;
7181       else if (unformat (i, "tapname %s", &tap_name))
7182         name_set = 1;
7183       else
7184         break;
7185     }
7186
7187   if (sw_if_index_set == 0)
7188     {
7189       errmsg ("missing vpp interface name");
7190       return -99;
7191     }
7192   if (name_set == 0)
7193     {
7194       errmsg ("missing tap name");
7195       return -99;
7196     }
7197   if (vec_len (tap_name) > 63)
7198     {
7199       errmsg ("tap name too long");
7200     }
7201   vec_add1 (tap_name, 0);
7202
7203   /* Construct the API message */
7204   M (TAP_MODIFY, mp);
7205
7206   mp->use_random_mac = random_mac;
7207   mp->sw_if_index = ntohl (sw_if_index);
7208   clib_memcpy (mp->mac_address, mac_address, 6);
7209   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7210   vec_free (tap_name);
7211
7212   /* send it... */
7213   S (mp);
7214
7215   /* Wait for a reply... */
7216   W (ret);
7217   return ret;
7218 }
7219
7220 static int
7221 api_tap_delete (vat_main_t * vam)
7222 {
7223   unformat_input_t *i = vam->input;
7224   vl_api_tap_delete_t *mp;
7225   u32 sw_if_index = ~0;
7226   u8 sw_if_index_set = 0;
7227   int ret;
7228
7229   /* Parse args required to build the message */
7230   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7231     {
7232       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7233         sw_if_index_set = 1;
7234       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7235         sw_if_index_set = 1;
7236       else
7237         break;
7238     }
7239
7240   if (sw_if_index_set == 0)
7241     {
7242       errmsg ("missing vpp interface name");
7243       return -99;
7244     }
7245
7246   /* Construct the API message */
7247   M (TAP_DELETE, mp);
7248
7249   mp->sw_if_index = ntohl (sw_if_index);
7250
7251   /* send it... */
7252   S (mp);
7253
7254   /* Wait for a reply... */
7255   W (ret);
7256   return ret;
7257 }
7258
7259 static int
7260 api_ip_table_add_del (vat_main_t * vam)
7261 {
7262   unformat_input_t *i = vam->input;
7263   vl_api_ip_table_add_del_t *mp;
7264   u32 table_id = ~0;
7265   u8 is_ipv6 = 0;
7266   u8 is_add = 1;
7267   int ret = 0;
7268
7269   /* Parse args required to build the message */
7270   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7271     {
7272       if (unformat (i, "ipv6"))
7273         is_ipv6 = 1;
7274       else if (unformat (i, "del"))
7275         is_add = 0;
7276       else if (unformat (i, "add"))
7277         is_add = 1;
7278       else if (unformat (i, "table %d", &table_id))
7279         ;
7280       else
7281         {
7282           clib_warning ("parse error '%U'", format_unformat_error, i);
7283           return -99;
7284         }
7285     }
7286
7287   if (~0 == table_id)
7288     {
7289       errmsg ("missing table-ID");
7290       return -99;
7291     }
7292
7293   /* Construct the API message */
7294   M (IP_TABLE_ADD_DEL, mp);
7295
7296   mp->table_id = ntohl (table_id);
7297   mp->is_ipv6 = is_ipv6;
7298   mp->is_add = is_add;
7299
7300   /* send it... */
7301   S (mp);
7302
7303   /* Wait for a reply... */
7304   W (ret);
7305
7306   return ret;
7307 }
7308
7309 static int
7310 api_ip_add_del_route (vat_main_t * vam)
7311 {
7312   unformat_input_t *i = vam->input;
7313   vl_api_ip_add_del_route_t *mp;
7314   u32 sw_if_index = ~0, vrf_id = 0;
7315   u8 is_ipv6 = 0;
7316   u8 is_local = 0, is_drop = 0;
7317   u8 is_unreach = 0, is_prohibit = 0;
7318   u8 create_vrf_if_needed = 0;
7319   u8 is_add = 1;
7320   u32 next_hop_weight = 1;
7321   u8 not_last = 0;
7322   u8 is_multipath = 0;
7323   u8 address_set = 0;
7324   u8 address_length_set = 0;
7325   u32 next_hop_table_id = 0;
7326   u32 resolve_attempts = 0;
7327   u32 dst_address_length = 0;
7328   u8 next_hop_set = 0;
7329   ip4_address_t v4_dst_address, v4_next_hop_address;
7330   ip6_address_t v6_dst_address, v6_next_hop_address;
7331   int count = 1;
7332   int j;
7333   f64 before = 0;
7334   u32 random_add_del = 0;
7335   u32 *random_vector = 0;
7336   uword *random_hash;
7337   u32 random_seed = 0xdeaddabe;
7338   u32 classify_table_index = ~0;
7339   u8 is_classify = 0;
7340   u8 resolve_host = 0, resolve_attached = 0;
7341   mpls_label_t *next_hop_out_label_stack = NULL;
7342   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7343   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7344
7345   /* Parse args required to build the message */
7346   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7347     {
7348       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7349         ;
7350       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7351         ;
7352       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
7353         {
7354           address_set = 1;
7355           is_ipv6 = 0;
7356         }
7357       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
7358         {
7359           address_set = 1;
7360           is_ipv6 = 1;
7361         }
7362       else if (unformat (i, "/%d", &dst_address_length))
7363         {
7364           address_length_set = 1;
7365         }
7366
7367       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
7368                                          &v4_next_hop_address))
7369         {
7370           next_hop_set = 1;
7371         }
7372       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
7373                                          &v6_next_hop_address))
7374         {
7375           next_hop_set = 1;
7376         }
7377       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
7378         ;
7379       else if (unformat (i, "weight %d", &next_hop_weight))
7380         ;
7381       else if (unformat (i, "drop"))
7382         {
7383           is_drop = 1;
7384         }
7385       else if (unformat (i, "null-send-unreach"))
7386         {
7387           is_unreach = 1;
7388         }
7389       else if (unformat (i, "null-send-prohibit"))
7390         {
7391           is_prohibit = 1;
7392         }
7393       else if (unformat (i, "local"))
7394         {
7395           is_local = 1;
7396         }
7397       else if (unformat (i, "classify %d", &classify_table_index))
7398         {
7399           is_classify = 1;
7400         }
7401       else if (unformat (i, "del"))
7402         is_add = 0;
7403       else if (unformat (i, "add"))
7404         is_add = 1;
7405       else if (unformat (i, "not-last"))
7406         not_last = 1;
7407       else if (unformat (i, "resolve-via-host"))
7408         resolve_host = 1;
7409       else if (unformat (i, "resolve-via-attached"))
7410         resolve_attached = 1;
7411       else if (unformat (i, "multipath"))
7412         is_multipath = 1;
7413       else if (unformat (i, "vrf %d", &vrf_id))
7414         ;
7415       else if (unformat (i, "create-vrf"))
7416         create_vrf_if_needed = 1;
7417       else if (unformat (i, "count %d", &count))
7418         ;
7419       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
7420         ;
7421       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7422         ;
7423       else if (unformat (i, "out-label %d", &next_hop_out_label))
7424         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7425       else if (unformat (i, "via-label %d", &next_hop_via_label))
7426         ;
7427       else if (unformat (i, "random"))
7428         random_add_del = 1;
7429       else if (unformat (i, "seed %d", &random_seed))
7430         ;
7431       else
7432         {
7433           clib_warning ("parse error '%U'", format_unformat_error, i);
7434           return -99;
7435         }
7436     }
7437
7438   if (!next_hop_set && !is_drop && !is_local &&
7439       !is_classify && !is_unreach && !is_prohibit &&
7440       MPLS_LABEL_INVALID == next_hop_via_label)
7441     {
7442       errmsg
7443         ("next hop / local / drop / unreach / prohibit / classify not set");
7444       return -99;
7445     }
7446
7447   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
7448     {
7449       errmsg ("next hop and next-hop via label set");
7450       return -99;
7451     }
7452   if (address_set == 0)
7453     {
7454       errmsg ("missing addresses");
7455       return -99;
7456     }
7457
7458   if (address_length_set == 0)
7459     {
7460       errmsg ("missing address length");
7461       return -99;
7462     }
7463
7464   /* Generate a pile of unique, random routes */
7465   if (random_add_del)
7466     {
7467       u32 this_random_address;
7468       random_hash = hash_create (count, sizeof (uword));
7469
7470       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
7471       for (j = 0; j <= count; j++)
7472         {
7473           do
7474             {
7475               this_random_address = random_u32 (&random_seed);
7476               this_random_address =
7477                 clib_host_to_net_u32 (this_random_address);
7478             }
7479           while (hash_get (random_hash, this_random_address));
7480           vec_add1 (random_vector, this_random_address);
7481           hash_set (random_hash, this_random_address, 1);
7482         }
7483       hash_free (random_hash);
7484       v4_dst_address.as_u32 = random_vector[0];
7485     }
7486
7487   if (count > 1)
7488     {
7489       /* Turn on async mode */
7490       vam->async_mode = 1;
7491       vam->async_errors = 0;
7492       before = vat_time_now (vam);
7493     }
7494
7495   for (j = 0; j < count; j++)
7496     {
7497       /* Construct the API message */
7498       M2 (IP_ADD_DEL_ROUTE, mp,
7499           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7500
7501       mp->next_hop_sw_if_index = ntohl (sw_if_index);
7502       mp->table_id = ntohl (vrf_id);
7503       mp->create_vrf_if_needed = create_vrf_if_needed;
7504
7505       mp->is_add = is_add;
7506       mp->is_drop = is_drop;
7507       mp->is_unreach = is_unreach;
7508       mp->is_prohibit = is_prohibit;
7509       mp->is_ipv6 = is_ipv6;
7510       mp->is_local = is_local;
7511       mp->is_classify = is_classify;
7512       mp->is_multipath = is_multipath;
7513       mp->is_resolve_host = resolve_host;
7514       mp->is_resolve_attached = resolve_attached;
7515       mp->not_last = not_last;
7516       mp->next_hop_weight = next_hop_weight;
7517       mp->dst_address_length = dst_address_length;
7518       mp->next_hop_table_id = ntohl (next_hop_table_id);
7519       mp->classify_table_index = ntohl (classify_table_index);
7520       mp->next_hop_via_label = ntohl (next_hop_via_label);
7521       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7522       if (0 != mp->next_hop_n_out_labels)
7523         {
7524           memcpy (mp->next_hop_out_label_stack,
7525                   next_hop_out_label_stack,
7526                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7527           vec_free (next_hop_out_label_stack);
7528         }
7529
7530       if (is_ipv6)
7531         {
7532           clib_memcpy (mp->dst_address, &v6_dst_address,
7533                        sizeof (v6_dst_address));
7534           if (next_hop_set)
7535             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
7536                          sizeof (v6_next_hop_address));
7537           increment_v6_address (&v6_dst_address);
7538         }
7539       else
7540         {
7541           clib_memcpy (mp->dst_address, &v4_dst_address,
7542                        sizeof (v4_dst_address));
7543           if (next_hop_set)
7544             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
7545                          sizeof (v4_next_hop_address));
7546           if (random_add_del)
7547             v4_dst_address.as_u32 = random_vector[j + 1];
7548           else
7549             increment_v4_address (&v4_dst_address);
7550         }
7551       /* send it... */
7552       S (mp);
7553       /* If we receive SIGTERM, stop now... */
7554       if (vam->do_exit)
7555         break;
7556     }
7557
7558   /* When testing multiple add/del ops, use a control-ping to sync */
7559   if (count > 1)
7560     {
7561       vl_api_control_ping_t *mp_ping;
7562       f64 after;
7563       f64 timeout;
7564
7565       /* Shut off async mode */
7566       vam->async_mode = 0;
7567
7568       M (CONTROL_PING, mp_ping);
7569       S (mp_ping);
7570
7571       timeout = vat_time_now (vam) + 1.0;
7572       while (vat_time_now (vam) < timeout)
7573         if (vam->result_ready == 1)
7574           goto out;
7575       vam->retval = -99;
7576
7577     out:
7578       if (vam->retval == -99)
7579         errmsg ("timeout");
7580
7581       if (vam->async_errors > 0)
7582         {
7583           errmsg ("%d asynchronous errors", vam->async_errors);
7584           vam->retval = -98;
7585         }
7586       vam->async_errors = 0;
7587       after = vat_time_now (vam);
7588
7589       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7590       if (j > 0)
7591         count = j;
7592
7593       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7594              count, after - before, count / (after - before));
7595     }
7596   else
7597     {
7598       int ret;
7599
7600       /* Wait for a reply... */
7601       W (ret);
7602       return ret;
7603     }
7604
7605   /* Return the good/bad news */
7606   return (vam->retval);
7607 }
7608
7609 static int
7610 api_ip_mroute_add_del (vat_main_t * vam)
7611 {
7612   unformat_input_t *i = vam->input;
7613   vl_api_ip_mroute_add_del_t *mp;
7614   u32 sw_if_index = ~0, vrf_id = 0;
7615   u8 is_ipv6 = 0;
7616   u8 is_local = 0;
7617   u8 create_vrf_if_needed = 0;
7618   u8 is_add = 1;
7619   u8 address_set = 0;
7620   u32 grp_address_length = 0;
7621   ip4_address_t v4_grp_address, v4_src_address;
7622   ip6_address_t v6_grp_address, v6_src_address;
7623   mfib_itf_flags_t iflags = 0;
7624   mfib_entry_flags_t eflags = 0;
7625   int ret;
7626
7627   /* Parse args required to build the message */
7628   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7629     {
7630       if (unformat (i, "sw_if_index %d", &sw_if_index))
7631         ;
7632       else if (unformat (i, "%U %U",
7633                          unformat_ip4_address, &v4_src_address,
7634                          unformat_ip4_address, &v4_grp_address))
7635         {
7636           grp_address_length = 64;
7637           address_set = 1;
7638           is_ipv6 = 0;
7639         }
7640       else if (unformat (i, "%U %U",
7641                          unformat_ip6_address, &v6_src_address,
7642                          unformat_ip6_address, &v6_grp_address))
7643         {
7644           grp_address_length = 256;
7645           address_set = 1;
7646           is_ipv6 = 1;
7647         }
7648       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
7649         {
7650           memset (&v4_src_address, 0, sizeof (v4_src_address));
7651           grp_address_length = 32;
7652           address_set = 1;
7653           is_ipv6 = 0;
7654         }
7655       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
7656         {
7657           memset (&v6_src_address, 0, sizeof (v6_src_address));
7658           grp_address_length = 128;
7659           address_set = 1;
7660           is_ipv6 = 1;
7661         }
7662       else if (unformat (i, "/%d", &grp_address_length))
7663         ;
7664       else if (unformat (i, "local"))
7665         {
7666           is_local = 1;
7667         }
7668       else if (unformat (i, "del"))
7669         is_add = 0;
7670       else if (unformat (i, "add"))
7671         is_add = 1;
7672       else if (unformat (i, "vrf %d", &vrf_id))
7673         ;
7674       else if (unformat (i, "create-vrf"))
7675         create_vrf_if_needed = 1;
7676       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
7677         ;
7678       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
7679         ;
7680       else
7681         {
7682           clib_warning ("parse error '%U'", format_unformat_error, i);
7683           return -99;
7684         }
7685     }
7686
7687   if (address_set == 0)
7688     {
7689       errmsg ("missing addresses\n");
7690       return -99;
7691     }
7692
7693   /* Construct the API message */
7694   M (IP_MROUTE_ADD_DEL, mp);
7695
7696   mp->next_hop_sw_if_index = ntohl (sw_if_index);
7697   mp->table_id = ntohl (vrf_id);
7698   mp->create_vrf_if_needed = create_vrf_if_needed;
7699
7700   mp->is_add = is_add;
7701   mp->is_ipv6 = is_ipv6;
7702   mp->is_local = is_local;
7703   mp->itf_flags = ntohl (iflags);
7704   mp->entry_flags = ntohl (eflags);
7705   mp->grp_address_length = grp_address_length;
7706   mp->grp_address_length = ntohs (mp->grp_address_length);
7707
7708   if (is_ipv6)
7709     {
7710       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
7711       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
7712     }
7713   else
7714     {
7715       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
7716       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
7717
7718     }
7719
7720   /* send it... */
7721   S (mp);
7722   /* Wait for a reply... */
7723   W (ret);
7724   return ret;
7725 }
7726
7727 static int
7728 api_mpls_table_add_del (vat_main_t * vam)
7729 {
7730   unformat_input_t *i = vam->input;
7731   vl_api_mpls_table_add_del_t *mp;
7732   u32 table_id = ~0;
7733   u8 is_add = 1;
7734   int ret = 0;
7735
7736   /* Parse args required to build the message */
7737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7738     {
7739       if (unformat (i, "table %d", &table_id))
7740         ;
7741       else if (unformat (i, "del"))
7742         is_add = 0;
7743       else if (unformat (i, "add"))
7744         is_add = 1;
7745       else
7746         {
7747           clib_warning ("parse error '%U'", format_unformat_error, i);
7748           return -99;
7749         }
7750     }
7751
7752   if (~0 == table_id)
7753     {
7754       errmsg ("missing table-ID");
7755       return -99;
7756     }
7757
7758   /* Construct the API message */
7759   M (MPLS_TABLE_ADD_DEL, mp);
7760
7761   mp->mt_table_id = ntohl (table_id);
7762   mp->mt_is_add = is_add;
7763
7764   /* send it... */
7765   S (mp);
7766
7767   /* Wait for a reply... */
7768   W (ret);
7769
7770   return ret;
7771 }
7772
7773 static int
7774 api_mpls_route_add_del (vat_main_t * vam)
7775 {
7776   unformat_input_t *i = vam->input;
7777   vl_api_mpls_route_add_del_t *mp;
7778   u32 sw_if_index = ~0, table_id = 0;
7779   u8 create_table_if_needed = 0;
7780   u8 is_add = 1;
7781   u32 next_hop_weight = 1;
7782   u8 is_multipath = 0;
7783   u32 next_hop_table_id = 0;
7784   u8 next_hop_set = 0;
7785   ip4_address_t v4_next_hop_address = {
7786     .as_u32 = 0,
7787   };
7788   ip6_address_t v6_next_hop_address = { {0} };
7789   int count = 1;
7790   int j;
7791   f64 before = 0;
7792   u32 classify_table_index = ~0;
7793   u8 is_classify = 0;
7794   u8 resolve_host = 0, resolve_attached = 0;
7795   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7796   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7797   mpls_label_t *next_hop_out_label_stack = NULL;
7798   mpls_label_t local_label = MPLS_LABEL_INVALID;
7799   u8 is_eos = 0;
7800   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
7801
7802   /* Parse args required to build the message */
7803   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7804     {
7805       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7806         ;
7807       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7808         ;
7809       else if (unformat (i, "%d", &local_label))
7810         ;
7811       else if (unformat (i, "eos"))
7812         is_eos = 1;
7813       else if (unformat (i, "non-eos"))
7814         is_eos = 0;
7815       else if (unformat (i, "via %U", unformat_ip4_address,
7816                          &v4_next_hop_address))
7817         {
7818           next_hop_set = 1;
7819           next_hop_proto = DPO_PROTO_IP4;
7820         }
7821       else if (unformat (i, "via %U", unformat_ip6_address,
7822                          &v6_next_hop_address))
7823         {
7824           next_hop_set = 1;
7825           next_hop_proto = DPO_PROTO_IP6;
7826         }
7827       else if (unformat (i, "weight %d", &next_hop_weight))
7828         ;
7829       else if (unformat (i, "create-table"))
7830         create_table_if_needed = 1;
7831       else if (unformat (i, "classify %d", &classify_table_index))
7832         {
7833           is_classify = 1;
7834         }
7835       else if (unformat (i, "del"))
7836         is_add = 0;
7837       else if (unformat (i, "add"))
7838         is_add = 1;
7839       else if (unformat (i, "resolve-via-host"))
7840         resolve_host = 1;
7841       else if (unformat (i, "resolve-via-attached"))
7842         resolve_attached = 1;
7843       else if (unformat (i, "multipath"))
7844         is_multipath = 1;
7845       else if (unformat (i, "count %d", &count))
7846         ;
7847       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
7848         {
7849           next_hop_set = 1;
7850           next_hop_proto = DPO_PROTO_IP4;
7851         }
7852       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
7853         {
7854           next_hop_set = 1;
7855           next_hop_proto = DPO_PROTO_IP6;
7856         }
7857       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7858         ;
7859       else if (unformat (i, "via-label %d", &next_hop_via_label))
7860         ;
7861       else if (unformat (i, "out-label %d", &next_hop_out_label))
7862         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7863       else
7864         {
7865           clib_warning ("parse error '%U'", format_unformat_error, i);
7866           return -99;
7867         }
7868     }
7869
7870   if (!next_hop_set && !is_classify)
7871     {
7872       errmsg ("next hop / classify not set");
7873       return -99;
7874     }
7875
7876   if (MPLS_LABEL_INVALID == local_label)
7877     {
7878       errmsg ("missing label");
7879       return -99;
7880     }
7881
7882   if (count > 1)
7883     {
7884       /* Turn on async mode */
7885       vam->async_mode = 1;
7886       vam->async_errors = 0;
7887       before = vat_time_now (vam);
7888     }
7889
7890   for (j = 0; j < count; j++)
7891     {
7892       /* Construct the API message */
7893       M2 (MPLS_ROUTE_ADD_DEL, mp,
7894           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7895
7896       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
7897       mp->mr_table_id = ntohl (table_id);
7898       mp->mr_create_table_if_needed = create_table_if_needed;
7899
7900       mp->mr_is_add = is_add;
7901       mp->mr_next_hop_proto = next_hop_proto;
7902       mp->mr_is_classify = is_classify;
7903       mp->mr_is_multipath = is_multipath;
7904       mp->mr_is_resolve_host = resolve_host;
7905       mp->mr_is_resolve_attached = resolve_attached;
7906       mp->mr_next_hop_weight = next_hop_weight;
7907       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
7908       mp->mr_classify_table_index = ntohl (classify_table_index);
7909       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
7910       mp->mr_label = ntohl (local_label);
7911       mp->mr_eos = is_eos;
7912
7913       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7914       if (0 != mp->mr_next_hop_n_out_labels)
7915         {
7916           memcpy (mp->mr_next_hop_out_label_stack,
7917                   next_hop_out_label_stack,
7918                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7919           vec_free (next_hop_out_label_stack);
7920         }
7921
7922       if (next_hop_set)
7923         {
7924           if (DPO_PROTO_IP4 == next_hop_proto)
7925             {
7926               clib_memcpy (mp->mr_next_hop,
7927                            &v4_next_hop_address,
7928                            sizeof (v4_next_hop_address));
7929             }
7930           else if (DPO_PROTO_IP6 == next_hop_proto)
7931
7932             {
7933               clib_memcpy (mp->mr_next_hop,
7934                            &v6_next_hop_address,
7935                            sizeof (v6_next_hop_address));
7936             }
7937         }
7938       local_label++;
7939
7940       /* send it... */
7941       S (mp);
7942       /* If we receive SIGTERM, stop now... */
7943       if (vam->do_exit)
7944         break;
7945     }
7946
7947   /* When testing multiple add/del ops, use a control-ping to sync */
7948   if (count > 1)
7949     {
7950       vl_api_control_ping_t *mp_ping;
7951       f64 after;
7952       f64 timeout;
7953
7954       /* Shut off async mode */
7955       vam->async_mode = 0;
7956
7957       M (CONTROL_PING, mp_ping);
7958       S (mp_ping);
7959
7960       timeout = vat_time_now (vam) + 1.0;
7961       while (vat_time_now (vam) < timeout)
7962         if (vam->result_ready == 1)
7963           goto out;
7964       vam->retval = -99;
7965
7966     out:
7967       if (vam->retval == -99)
7968         errmsg ("timeout");
7969
7970       if (vam->async_errors > 0)
7971         {
7972           errmsg ("%d asynchronous errors", vam->async_errors);
7973           vam->retval = -98;
7974         }
7975       vam->async_errors = 0;
7976       after = vat_time_now (vam);
7977
7978       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7979       if (j > 0)
7980         count = j;
7981
7982       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7983              count, after - before, count / (after - before));
7984     }
7985   else
7986     {
7987       int ret;
7988
7989       /* Wait for a reply... */
7990       W (ret);
7991       return ret;
7992     }
7993
7994   /* Return the good/bad news */
7995   return (vam->retval);
7996 }
7997
7998 static int
7999 api_mpls_ip_bind_unbind (vat_main_t * vam)
8000 {
8001   unformat_input_t *i = vam->input;
8002   vl_api_mpls_ip_bind_unbind_t *mp;
8003   u32 ip_table_id = 0;
8004   u8 create_table_if_needed = 0;
8005   u8 is_bind = 1;
8006   u8 is_ip4 = 1;
8007   ip4_address_t v4_address;
8008   ip6_address_t v6_address;
8009   u32 address_length;
8010   u8 address_set = 0;
8011   mpls_label_t local_label = MPLS_LABEL_INVALID;
8012   int ret;
8013
8014   /* Parse args required to build the message */
8015   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8016     {
8017       if (unformat (i, "%U/%d", unformat_ip4_address,
8018                     &v4_address, &address_length))
8019         {
8020           is_ip4 = 1;
8021           address_set = 1;
8022         }
8023       else if (unformat (i, "%U/%d", unformat_ip6_address,
8024                          &v6_address, &address_length))
8025         {
8026           is_ip4 = 0;
8027           address_set = 1;
8028         }
8029       else if (unformat (i, "%d", &local_label))
8030         ;
8031       else if (unformat (i, "create-table"))
8032         create_table_if_needed = 1;
8033       else if (unformat (i, "table-id %d", &ip_table_id))
8034         ;
8035       else if (unformat (i, "unbind"))
8036         is_bind = 0;
8037       else if (unformat (i, "bind"))
8038         is_bind = 1;
8039       else
8040         {
8041           clib_warning ("parse error '%U'", format_unformat_error, i);
8042           return -99;
8043         }
8044     }
8045
8046   if (!address_set)
8047     {
8048       errmsg ("IP addres not set");
8049       return -99;
8050     }
8051
8052   if (MPLS_LABEL_INVALID == local_label)
8053     {
8054       errmsg ("missing label");
8055       return -99;
8056     }
8057
8058   /* Construct the API message */
8059   M (MPLS_IP_BIND_UNBIND, mp);
8060
8061   mp->mb_create_table_if_needed = create_table_if_needed;
8062   mp->mb_is_bind = is_bind;
8063   mp->mb_is_ip4 = is_ip4;
8064   mp->mb_ip_table_id = ntohl (ip_table_id);
8065   mp->mb_mpls_table_id = 0;
8066   mp->mb_label = ntohl (local_label);
8067   mp->mb_address_length = address_length;
8068
8069   if (is_ip4)
8070     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8071   else
8072     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8073
8074   /* send it... */
8075   S (mp);
8076
8077   /* Wait for a reply... */
8078   W (ret);
8079   return ret;
8080 }
8081
8082 static int
8083 api_proxy_arp_add_del (vat_main_t * vam)
8084 {
8085   unformat_input_t *i = vam->input;
8086   vl_api_proxy_arp_add_del_t *mp;
8087   u32 vrf_id = 0;
8088   u8 is_add = 1;
8089   ip4_address_t lo, hi;
8090   u8 range_set = 0;
8091   int ret;
8092
8093   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8094     {
8095       if (unformat (i, "vrf %d", &vrf_id))
8096         ;
8097       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
8098                          unformat_ip4_address, &hi))
8099         range_set = 1;
8100       else if (unformat (i, "del"))
8101         is_add = 0;
8102       else
8103         {
8104           clib_warning ("parse error '%U'", format_unformat_error, i);
8105           return -99;
8106         }
8107     }
8108
8109   if (range_set == 0)
8110     {
8111       errmsg ("address range not set");
8112       return -99;
8113     }
8114
8115   M (PROXY_ARP_ADD_DEL, mp);
8116
8117   mp->vrf_id = ntohl (vrf_id);
8118   mp->is_add = is_add;
8119   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
8120   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
8121
8122   S (mp);
8123   W (ret);
8124   return ret;
8125 }
8126
8127 static int
8128 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8129 {
8130   unformat_input_t *i = vam->input;
8131   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8132   u32 sw_if_index;
8133   u8 enable = 1;
8134   u8 sw_if_index_set = 0;
8135   int ret;
8136
8137   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8138     {
8139       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8140         sw_if_index_set = 1;
8141       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8142         sw_if_index_set = 1;
8143       else if (unformat (i, "enable"))
8144         enable = 1;
8145       else if (unformat (i, "disable"))
8146         enable = 0;
8147       else
8148         {
8149           clib_warning ("parse error '%U'", format_unformat_error, i);
8150           return -99;
8151         }
8152     }
8153
8154   if (sw_if_index_set == 0)
8155     {
8156       errmsg ("missing interface name or sw_if_index");
8157       return -99;
8158     }
8159
8160   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8161
8162   mp->sw_if_index = ntohl (sw_if_index);
8163   mp->enable_disable = enable;
8164
8165   S (mp);
8166   W (ret);
8167   return ret;
8168 }
8169
8170 static int
8171 api_mpls_tunnel_add_del (vat_main_t * vam)
8172 {
8173   unformat_input_t *i = vam->input;
8174   vl_api_mpls_tunnel_add_del_t *mp;
8175
8176   u8 is_add = 1;
8177   u8 l2_only = 0;
8178   u32 sw_if_index = ~0;
8179   u32 next_hop_sw_if_index = ~0;
8180   u32 next_hop_proto_is_ip4 = 1;
8181
8182   u32 next_hop_table_id = 0;
8183   ip4_address_t v4_next_hop_address = {
8184     .as_u32 = 0,
8185   };
8186   ip6_address_t v6_next_hop_address = { {0} };
8187   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
8188   int ret;
8189
8190   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8191     {
8192       if (unformat (i, "add"))
8193         is_add = 1;
8194       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8195         is_add = 0;
8196       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
8197         ;
8198       else if (unformat (i, "via %U",
8199                          unformat_ip4_address, &v4_next_hop_address))
8200         {
8201           next_hop_proto_is_ip4 = 1;
8202         }
8203       else if (unformat (i, "via %U",
8204                          unformat_ip6_address, &v6_next_hop_address))
8205         {
8206           next_hop_proto_is_ip4 = 0;
8207         }
8208       else if (unformat (i, "l2-only"))
8209         l2_only = 1;
8210       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8211         ;
8212       else if (unformat (i, "out-label %d", &next_hop_out_label))
8213         vec_add1 (labels, ntohl (next_hop_out_label));
8214       else
8215         {
8216           clib_warning ("parse error '%U'", format_unformat_error, i);
8217           return -99;
8218         }
8219     }
8220
8221   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
8222
8223   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
8224   mp->mt_sw_if_index = ntohl (sw_if_index);
8225   mp->mt_is_add = is_add;
8226   mp->mt_l2_only = l2_only;
8227   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
8228   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
8229
8230   mp->mt_next_hop_n_out_labels = vec_len (labels);
8231
8232   if (0 != mp->mt_next_hop_n_out_labels)
8233     {
8234       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
8235                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
8236       vec_free (labels);
8237     }
8238
8239   if (next_hop_proto_is_ip4)
8240     {
8241       clib_memcpy (mp->mt_next_hop,
8242                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8243     }
8244   else
8245     {
8246       clib_memcpy (mp->mt_next_hop,
8247                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8248     }
8249
8250   S (mp);
8251   W (ret);
8252   return ret;
8253 }
8254
8255 static int
8256 api_sw_interface_set_unnumbered (vat_main_t * vam)
8257 {
8258   unformat_input_t *i = vam->input;
8259   vl_api_sw_interface_set_unnumbered_t *mp;
8260   u32 sw_if_index;
8261   u32 unnum_sw_index = ~0;
8262   u8 is_add = 1;
8263   u8 sw_if_index_set = 0;
8264   int ret;
8265
8266   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8267     {
8268       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8269         sw_if_index_set = 1;
8270       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8271         sw_if_index_set = 1;
8272       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8273         ;
8274       else if (unformat (i, "del"))
8275         is_add = 0;
8276       else
8277         {
8278           clib_warning ("parse error '%U'", format_unformat_error, i);
8279           return -99;
8280         }
8281     }
8282
8283   if (sw_if_index_set == 0)
8284     {
8285       errmsg ("missing interface name or sw_if_index");
8286       return -99;
8287     }
8288
8289   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8290
8291   mp->sw_if_index = ntohl (sw_if_index);
8292   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8293   mp->is_add = is_add;
8294
8295   S (mp);
8296   W (ret);
8297   return ret;
8298 }
8299
8300 static int
8301 api_ip_neighbor_add_del (vat_main_t * vam)
8302 {
8303   unformat_input_t *i = vam->input;
8304   vl_api_ip_neighbor_add_del_t *mp;
8305   u32 sw_if_index;
8306   u8 sw_if_index_set = 0;
8307   u8 is_add = 1;
8308   u8 is_static = 0;
8309   u8 is_no_fib_entry = 0;
8310   u8 mac_address[6];
8311   u8 mac_set = 0;
8312   u8 v4_address_set = 0;
8313   u8 v6_address_set = 0;
8314   ip4_address_t v4address;
8315   ip6_address_t v6address;
8316   int ret;
8317
8318   memset (mac_address, 0, sizeof (mac_address));
8319
8320   /* Parse args required to build the message */
8321   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8322     {
8323       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8324         {
8325           mac_set = 1;
8326         }
8327       else if (unformat (i, "del"))
8328         is_add = 0;
8329       else
8330         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8331         sw_if_index_set = 1;
8332       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8333         sw_if_index_set = 1;
8334       else if (unformat (i, "is_static"))
8335         is_static = 1;
8336       else if (unformat (i, "no-fib-entry"))
8337         is_no_fib_entry = 1;
8338       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
8339         v4_address_set = 1;
8340       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
8341         v6_address_set = 1;
8342       else
8343         {
8344           clib_warning ("parse error '%U'", format_unformat_error, i);
8345           return -99;
8346         }
8347     }
8348
8349   if (sw_if_index_set == 0)
8350     {
8351       errmsg ("missing interface name or sw_if_index");
8352       return -99;
8353     }
8354   if (v4_address_set && v6_address_set)
8355     {
8356       errmsg ("both v4 and v6 addresses set");
8357       return -99;
8358     }
8359   if (!v4_address_set && !v6_address_set)
8360     {
8361       errmsg ("no address set");
8362       return -99;
8363     }
8364
8365   /* Construct the API message */
8366   M (IP_NEIGHBOR_ADD_DEL, mp);
8367
8368   mp->sw_if_index = ntohl (sw_if_index);
8369   mp->is_add = is_add;
8370   mp->is_static = is_static;
8371   mp->is_no_adj_fib = is_no_fib_entry;
8372   if (mac_set)
8373     clib_memcpy (mp->mac_address, mac_address, 6);
8374   if (v6_address_set)
8375     {
8376       mp->is_ipv6 = 1;
8377       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
8378     }
8379   else
8380     {
8381       /* mp->is_ipv6 = 0; via memset in M macro above */
8382       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
8383     }
8384
8385   /* send it... */
8386   S (mp);
8387
8388   /* Wait for a reply, return good/bad news  */
8389   W (ret);
8390   return ret;
8391 }
8392
8393 static int
8394 api_reset_vrf (vat_main_t * vam)
8395 {
8396   unformat_input_t *i = vam->input;
8397   vl_api_reset_vrf_t *mp;
8398   u32 vrf_id = 0;
8399   u8 is_ipv6 = 0;
8400   u8 vrf_id_set = 0;
8401   int ret;
8402
8403   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8404     {
8405       if (unformat (i, "vrf %d", &vrf_id))
8406         vrf_id_set = 1;
8407       else if (unformat (i, "ipv6"))
8408         is_ipv6 = 1;
8409       else
8410         {
8411           clib_warning ("parse error '%U'", format_unformat_error, i);
8412           return -99;
8413         }
8414     }
8415
8416   if (vrf_id_set == 0)
8417     {
8418       errmsg ("missing vrf id");
8419       return -99;
8420     }
8421
8422   M (RESET_VRF, mp);
8423
8424   mp->vrf_id = ntohl (vrf_id);
8425   mp->is_ipv6 = is_ipv6;
8426
8427   S (mp);
8428   W (ret);
8429   return ret;
8430 }
8431
8432 static int
8433 api_create_vlan_subif (vat_main_t * vam)
8434 {
8435   unformat_input_t *i = vam->input;
8436   vl_api_create_vlan_subif_t *mp;
8437   u32 sw_if_index;
8438   u8 sw_if_index_set = 0;
8439   u32 vlan_id;
8440   u8 vlan_id_set = 0;
8441   int ret;
8442
8443   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8444     {
8445       if (unformat (i, "sw_if_index %d", &sw_if_index))
8446         sw_if_index_set = 1;
8447       else
8448         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8449         sw_if_index_set = 1;
8450       else if (unformat (i, "vlan %d", &vlan_id))
8451         vlan_id_set = 1;
8452       else
8453         {
8454           clib_warning ("parse error '%U'", format_unformat_error, i);
8455           return -99;
8456         }
8457     }
8458
8459   if (sw_if_index_set == 0)
8460     {
8461       errmsg ("missing interface name or sw_if_index");
8462       return -99;
8463     }
8464
8465   if (vlan_id_set == 0)
8466     {
8467       errmsg ("missing vlan_id");
8468       return -99;
8469     }
8470   M (CREATE_VLAN_SUBIF, mp);
8471
8472   mp->sw_if_index = ntohl (sw_if_index);
8473   mp->vlan_id = ntohl (vlan_id);
8474
8475   S (mp);
8476   W (ret);
8477   return ret;
8478 }
8479
8480 #define foreach_create_subif_bit                \
8481 _(no_tags)                                      \
8482 _(one_tag)                                      \
8483 _(two_tags)                                     \
8484 _(dot1ad)                                       \
8485 _(exact_match)                                  \
8486 _(default_sub)                                  \
8487 _(outer_vlan_id_any)                            \
8488 _(inner_vlan_id_any)
8489
8490 static int
8491 api_create_subif (vat_main_t * vam)
8492 {
8493   unformat_input_t *i = vam->input;
8494   vl_api_create_subif_t *mp;
8495   u32 sw_if_index;
8496   u8 sw_if_index_set = 0;
8497   u32 sub_id;
8498   u8 sub_id_set = 0;
8499   u32 no_tags = 0;
8500   u32 one_tag = 0;
8501   u32 two_tags = 0;
8502   u32 dot1ad = 0;
8503   u32 exact_match = 0;
8504   u32 default_sub = 0;
8505   u32 outer_vlan_id_any = 0;
8506   u32 inner_vlan_id_any = 0;
8507   u32 tmp;
8508   u16 outer_vlan_id = 0;
8509   u16 inner_vlan_id = 0;
8510   int ret;
8511
8512   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8513     {
8514       if (unformat (i, "sw_if_index %d", &sw_if_index))
8515         sw_if_index_set = 1;
8516       else
8517         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8518         sw_if_index_set = 1;
8519       else if (unformat (i, "sub_id %d", &sub_id))
8520         sub_id_set = 1;
8521       else if (unformat (i, "outer_vlan_id %d", &tmp))
8522         outer_vlan_id = tmp;
8523       else if (unformat (i, "inner_vlan_id %d", &tmp))
8524         inner_vlan_id = tmp;
8525
8526 #define _(a) else if (unformat (i, #a)) a = 1 ;
8527       foreach_create_subif_bit
8528 #undef _
8529         else
8530         {
8531           clib_warning ("parse error '%U'", format_unformat_error, i);
8532           return -99;
8533         }
8534     }
8535
8536   if (sw_if_index_set == 0)
8537     {
8538       errmsg ("missing interface name or sw_if_index");
8539       return -99;
8540     }
8541
8542   if (sub_id_set == 0)
8543     {
8544       errmsg ("missing sub_id");
8545       return -99;
8546     }
8547   M (CREATE_SUBIF, mp);
8548
8549   mp->sw_if_index = ntohl (sw_if_index);
8550   mp->sub_id = ntohl (sub_id);
8551
8552 #define _(a) mp->a = a;
8553   foreach_create_subif_bit;
8554 #undef _
8555
8556   mp->outer_vlan_id = ntohs (outer_vlan_id);
8557   mp->inner_vlan_id = ntohs (inner_vlan_id);
8558
8559   S (mp);
8560   W (ret);
8561   return ret;
8562 }
8563
8564 static int
8565 api_oam_add_del (vat_main_t * vam)
8566 {
8567   unformat_input_t *i = vam->input;
8568   vl_api_oam_add_del_t *mp;
8569   u32 vrf_id = 0;
8570   u8 is_add = 1;
8571   ip4_address_t src, dst;
8572   u8 src_set = 0;
8573   u8 dst_set = 0;
8574   int ret;
8575
8576   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8577     {
8578       if (unformat (i, "vrf %d", &vrf_id))
8579         ;
8580       else if (unformat (i, "src %U", unformat_ip4_address, &src))
8581         src_set = 1;
8582       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
8583         dst_set = 1;
8584       else if (unformat (i, "del"))
8585         is_add = 0;
8586       else
8587         {
8588           clib_warning ("parse error '%U'", format_unformat_error, i);
8589           return -99;
8590         }
8591     }
8592
8593   if (src_set == 0)
8594     {
8595       errmsg ("missing src addr");
8596       return -99;
8597     }
8598
8599   if (dst_set == 0)
8600     {
8601       errmsg ("missing dst addr");
8602       return -99;
8603     }
8604
8605   M (OAM_ADD_DEL, mp);
8606
8607   mp->vrf_id = ntohl (vrf_id);
8608   mp->is_add = is_add;
8609   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
8610   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
8611
8612   S (mp);
8613   W (ret);
8614   return ret;
8615 }
8616
8617 static int
8618 api_reset_fib (vat_main_t * vam)
8619 {
8620   unformat_input_t *i = vam->input;
8621   vl_api_reset_fib_t *mp;
8622   u32 vrf_id = 0;
8623   u8 is_ipv6 = 0;
8624   u8 vrf_id_set = 0;
8625
8626   int ret;
8627   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8628     {
8629       if (unformat (i, "vrf %d", &vrf_id))
8630         vrf_id_set = 1;
8631       else if (unformat (i, "ipv6"))
8632         is_ipv6 = 1;
8633       else
8634         {
8635           clib_warning ("parse error '%U'", format_unformat_error, i);
8636           return -99;
8637         }
8638     }
8639
8640   if (vrf_id_set == 0)
8641     {
8642       errmsg ("missing vrf id");
8643       return -99;
8644     }
8645
8646   M (RESET_FIB, mp);
8647
8648   mp->vrf_id = ntohl (vrf_id);
8649   mp->is_ipv6 = is_ipv6;
8650
8651   S (mp);
8652   W (ret);
8653   return ret;
8654 }
8655
8656 static int
8657 api_dhcp_proxy_config (vat_main_t * vam)
8658 {
8659   unformat_input_t *i = vam->input;
8660   vl_api_dhcp_proxy_config_t *mp;
8661   u32 rx_vrf_id = 0;
8662   u32 server_vrf_id = 0;
8663   u8 is_add = 1;
8664   u8 v4_address_set = 0;
8665   u8 v6_address_set = 0;
8666   ip4_address_t v4address;
8667   ip6_address_t v6address;
8668   u8 v4_src_address_set = 0;
8669   u8 v6_src_address_set = 0;
8670   ip4_address_t v4srcaddress;
8671   ip6_address_t v6srcaddress;
8672   int ret;
8673
8674   /* Parse args required to build the message */
8675   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8676     {
8677       if (unformat (i, "del"))
8678         is_add = 0;
8679       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
8680         ;
8681       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
8682         ;
8683       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
8684         v4_address_set = 1;
8685       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
8686         v6_address_set = 1;
8687       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
8688         v4_src_address_set = 1;
8689       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
8690         v6_src_address_set = 1;
8691       else
8692         break;
8693     }
8694
8695   if (v4_address_set && v6_address_set)
8696     {
8697       errmsg ("both v4 and v6 server addresses set");
8698       return -99;
8699     }
8700   if (!v4_address_set && !v6_address_set)
8701     {
8702       errmsg ("no server addresses set");
8703       return -99;
8704     }
8705
8706   if (v4_src_address_set && v6_src_address_set)
8707     {
8708       errmsg ("both v4 and v6  src addresses set");
8709       return -99;
8710     }
8711   if (!v4_src_address_set && !v6_src_address_set)
8712     {
8713       errmsg ("no src addresses set");
8714       return -99;
8715     }
8716
8717   if (!(v4_src_address_set && v4_address_set) &&
8718       !(v6_src_address_set && v6_address_set))
8719     {
8720       errmsg ("no matching server and src addresses set");
8721       return -99;
8722     }
8723
8724   /* Construct the API message */
8725   M (DHCP_PROXY_CONFIG, mp);
8726
8727   mp->is_add = is_add;
8728   mp->rx_vrf_id = ntohl (rx_vrf_id);
8729   mp->server_vrf_id = ntohl (server_vrf_id);
8730   if (v6_address_set)
8731     {
8732       mp->is_ipv6 = 1;
8733       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
8734       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
8735     }
8736   else
8737     {
8738       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
8739       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
8740     }
8741
8742   /* send it... */
8743   S (mp);
8744
8745   /* Wait for a reply, return good/bad news  */
8746   W (ret);
8747   return ret;
8748 }
8749
8750 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
8751 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
8752
8753 static void
8754 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
8755 {
8756   vat_main_t *vam = &vat_main;
8757   u32 i, count = mp->count;
8758   vl_api_dhcp_server_t *s;
8759
8760   if (mp->is_ipv6)
8761     print (vam->ofp,
8762            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8763            ntohl (mp->rx_vrf_id),
8764            format_ip6_address, mp->dhcp_src_address,
8765            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8766   else
8767     print (vam->ofp,
8768            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8769            ntohl (mp->rx_vrf_id),
8770            format_ip4_address, mp->dhcp_src_address,
8771            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8772
8773   for (i = 0; i < count; i++)
8774     {
8775       s = &mp->servers[i];
8776
8777       if (mp->is_ipv6)
8778         print (vam->ofp,
8779                " Server Table-ID %d, Server Address %U",
8780                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
8781       else
8782         print (vam->ofp,
8783                " Server Table-ID %d, Server Address %U",
8784                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
8785     }
8786 }
8787
8788 static void vl_api_dhcp_proxy_details_t_handler_json
8789   (vl_api_dhcp_proxy_details_t * mp)
8790 {
8791   vat_main_t *vam = &vat_main;
8792   vat_json_node_t *node = NULL;
8793   u32 i, count = mp->count;
8794   struct in_addr ip4;
8795   struct in6_addr ip6;
8796   vl_api_dhcp_server_t *s;
8797
8798   if (VAT_JSON_ARRAY != vam->json_tree.type)
8799     {
8800       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8801       vat_json_init_array (&vam->json_tree);
8802     }
8803   node = vat_json_array_add (&vam->json_tree);
8804
8805   vat_json_init_object (node);
8806   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
8807   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
8808   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
8809
8810   if (mp->is_ipv6)
8811     {
8812       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
8813       vat_json_object_add_ip6 (node, "src_address", ip6);
8814     }
8815   else
8816     {
8817       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
8818       vat_json_object_add_ip4 (node, "src_address", ip4);
8819     }
8820
8821   for (i = 0; i < count; i++)
8822     {
8823       s = &mp->servers[i];
8824
8825       vat_json_object_add_uint (node, "server-table-id",
8826                                 ntohl (s->server_vrf_id));
8827
8828       if (mp->is_ipv6)
8829         {
8830           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
8831           vat_json_object_add_ip4 (node, "src_address", ip4);
8832         }
8833       else
8834         {
8835           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
8836           vat_json_object_add_ip6 (node, "server_address", ip6);
8837         }
8838     }
8839 }
8840
8841 static int
8842 api_dhcp_proxy_dump (vat_main_t * vam)
8843 {
8844   unformat_input_t *i = vam->input;
8845   vl_api_control_ping_t *mp_ping;
8846   vl_api_dhcp_proxy_dump_t *mp;
8847   u8 is_ipv6 = 0;
8848   int ret;
8849
8850   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8851     {
8852       if (unformat (i, "ipv6"))
8853         is_ipv6 = 1;
8854       else
8855         {
8856           clib_warning ("parse error '%U'", format_unformat_error, i);
8857           return -99;
8858         }
8859     }
8860
8861   M (DHCP_PROXY_DUMP, mp);
8862
8863   mp->is_ip6 = is_ipv6;
8864   S (mp);
8865
8866   /* Use a control ping for synchronization */
8867   M (CONTROL_PING, mp_ping);
8868   S (mp_ping);
8869
8870   W (ret);
8871   return ret;
8872 }
8873
8874 static int
8875 api_dhcp_proxy_set_vss (vat_main_t * vam)
8876 {
8877   unformat_input_t *i = vam->input;
8878   vl_api_dhcp_proxy_set_vss_t *mp;
8879   u8 is_ipv6 = 0;
8880   u8 is_add = 1;
8881   u32 tbl_id;
8882   u8 tbl_id_set = 0;
8883   u32 oui;
8884   u8 oui_set = 0;
8885   u32 fib_id;
8886   u8 fib_id_set = 0;
8887   int ret;
8888
8889   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8890     {
8891       if (unformat (i, "tbl_id %d", &tbl_id))
8892         tbl_id_set = 1;
8893       if (unformat (i, "fib_id %d", &fib_id))
8894         fib_id_set = 1;
8895       if (unformat (i, "oui %d", &oui))
8896         oui_set = 1;
8897       else if (unformat (i, "ipv6"))
8898         is_ipv6 = 1;
8899       else if (unformat (i, "del"))
8900         is_add = 0;
8901       else
8902         {
8903           clib_warning ("parse error '%U'", format_unformat_error, i);
8904           return -99;
8905         }
8906     }
8907
8908   if (tbl_id_set == 0)
8909     {
8910       errmsg ("missing tbl id");
8911       return -99;
8912     }
8913
8914   if (fib_id_set == 0)
8915     {
8916       errmsg ("missing fib id");
8917       return -99;
8918     }
8919   if (oui_set == 0)
8920     {
8921       errmsg ("missing oui");
8922       return -99;
8923     }
8924
8925   M (DHCP_PROXY_SET_VSS, mp);
8926   mp->tbl_id = ntohl (tbl_id);
8927   mp->fib_id = ntohl (fib_id);
8928   mp->oui = ntohl (oui);
8929   mp->is_ipv6 = is_ipv6;
8930   mp->is_add = is_add;
8931
8932   S (mp);
8933   W (ret);
8934   return ret;
8935 }
8936
8937 static int
8938 api_dhcp_client_config (vat_main_t * vam)
8939 {
8940   unformat_input_t *i = vam->input;
8941   vl_api_dhcp_client_config_t *mp;
8942   u32 sw_if_index;
8943   u8 sw_if_index_set = 0;
8944   u8 is_add = 1;
8945   u8 *hostname = 0;
8946   u8 disable_event = 0;
8947   int ret;
8948
8949   /* Parse args required to build the message */
8950   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8951     {
8952       if (unformat (i, "del"))
8953         is_add = 0;
8954       else
8955         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8956         sw_if_index_set = 1;
8957       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8958         sw_if_index_set = 1;
8959       else if (unformat (i, "hostname %s", &hostname))
8960         ;
8961       else if (unformat (i, "disable_event"))
8962         disable_event = 1;
8963       else
8964         break;
8965     }
8966
8967   if (sw_if_index_set == 0)
8968     {
8969       errmsg ("missing interface name or sw_if_index");
8970       return -99;
8971     }
8972
8973   if (vec_len (hostname) > 63)
8974     {
8975       errmsg ("hostname too long");
8976     }
8977   vec_add1 (hostname, 0);
8978
8979   /* Construct the API message */
8980   M (DHCP_CLIENT_CONFIG, mp);
8981
8982   mp->sw_if_index = htonl (sw_if_index);
8983   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
8984   vec_free (hostname);
8985   mp->is_add = is_add;
8986   mp->want_dhcp_event = disable_event ? 0 : 1;
8987   mp->pid = htonl (getpid ());
8988
8989   /* send it... */
8990   S (mp);
8991
8992   /* Wait for a reply, return good/bad news  */
8993   W (ret);
8994   return ret;
8995 }
8996
8997 static int
8998 api_set_ip_flow_hash (vat_main_t * vam)
8999 {
9000   unformat_input_t *i = vam->input;
9001   vl_api_set_ip_flow_hash_t *mp;
9002   u32 vrf_id = 0;
9003   u8 is_ipv6 = 0;
9004   u8 vrf_id_set = 0;
9005   u8 src = 0;
9006   u8 dst = 0;
9007   u8 sport = 0;
9008   u8 dport = 0;
9009   u8 proto = 0;
9010   u8 reverse = 0;
9011   int ret;
9012
9013   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9014     {
9015       if (unformat (i, "vrf %d", &vrf_id))
9016         vrf_id_set = 1;
9017       else if (unformat (i, "ipv6"))
9018         is_ipv6 = 1;
9019       else if (unformat (i, "src"))
9020         src = 1;
9021       else if (unformat (i, "dst"))
9022         dst = 1;
9023       else if (unformat (i, "sport"))
9024         sport = 1;
9025       else if (unformat (i, "dport"))
9026         dport = 1;
9027       else if (unformat (i, "proto"))
9028         proto = 1;
9029       else if (unformat (i, "reverse"))
9030         reverse = 1;
9031
9032       else
9033         {
9034           clib_warning ("parse error '%U'", format_unformat_error, i);
9035           return -99;
9036         }
9037     }
9038
9039   if (vrf_id_set == 0)
9040     {
9041       errmsg ("missing vrf id");
9042       return -99;
9043     }
9044
9045   M (SET_IP_FLOW_HASH, mp);
9046   mp->src = src;
9047   mp->dst = dst;
9048   mp->sport = sport;
9049   mp->dport = dport;
9050   mp->proto = proto;
9051   mp->reverse = reverse;
9052   mp->vrf_id = ntohl (vrf_id);
9053   mp->is_ipv6 = is_ipv6;
9054
9055   S (mp);
9056   W (ret);
9057   return ret;
9058 }
9059
9060 static int
9061 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9062 {
9063   unformat_input_t *i = vam->input;
9064   vl_api_sw_interface_ip6_enable_disable_t *mp;
9065   u32 sw_if_index;
9066   u8 sw_if_index_set = 0;
9067   u8 enable = 0;
9068   int ret;
9069
9070   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9071     {
9072       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9073         sw_if_index_set = 1;
9074       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9075         sw_if_index_set = 1;
9076       else if (unformat (i, "enable"))
9077         enable = 1;
9078       else if (unformat (i, "disable"))
9079         enable = 0;
9080       else
9081         {
9082           clib_warning ("parse error '%U'", format_unformat_error, i);
9083           return -99;
9084         }
9085     }
9086
9087   if (sw_if_index_set == 0)
9088     {
9089       errmsg ("missing interface name or sw_if_index");
9090       return -99;
9091     }
9092
9093   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9094
9095   mp->sw_if_index = ntohl (sw_if_index);
9096   mp->enable = enable;
9097
9098   S (mp);
9099   W (ret);
9100   return ret;
9101 }
9102
9103 static int
9104 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
9105 {
9106   unformat_input_t *i = vam->input;
9107   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
9108   u32 sw_if_index;
9109   u8 sw_if_index_set = 0;
9110   u8 v6_address_set = 0;
9111   ip6_address_t v6address;
9112   int ret;
9113
9114   /* Parse args required to build the message */
9115   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9116     {
9117       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9118         sw_if_index_set = 1;
9119       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9120         sw_if_index_set = 1;
9121       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9122         v6_address_set = 1;
9123       else
9124         break;
9125     }
9126
9127   if (sw_if_index_set == 0)
9128     {
9129       errmsg ("missing interface name or sw_if_index");
9130       return -99;
9131     }
9132   if (!v6_address_set)
9133     {
9134       errmsg ("no address set");
9135       return -99;
9136     }
9137
9138   /* Construct the API message */
9139   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
9140
9141   mp->sw_if_index = ntohl (sw_if_index);
9142   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9143
9144   /* send it... */
9145   S (mp);
9146
9147   /* Wait for a reply, return good/bad news  */
9148   W (ret);
9149   return ret;
9150 }
9151
9152 static int
9153 api_ip6nd_proxy_add_del (vat_main_t * vam)
9154 {
9155   unformat_input_t *i = vam->input;
9156   vl_api_ip6nd_proxy_add_del_t *mp;
9157   u32 sw_if_index = ~0;
9158   u8 v6_address_set = 0;
9159   ip6_address_t v6address;
9160   u8 is_del = 0;
9161   int ret;
9162
9163   /* Parse args required to build the message */
9164   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9165     {
9166       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9167         ;
9168       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9169         ;
9170       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9171         v6_address_set = 1;
9172       if (unformat (i, "del"))
9173         is_del = 1;
9174       else
9175         {
9176           clib_warning ("parse error '%U'", format_unformat_error, i);
9177           return -99;
9178         }
9179     }
9180
9181   if (sw_if_index == ~0)
9182     {
9183       errmsg ("missing interface name or sw_if_index");
9184       return -99;
9185     }
9186   if (!v6_address_set)
9187     {
9188       errmsg ("no address set");
9189       return -99;
9190     }
9191
9192   /* Construct the API message */
9193   M (IP6ND_PROXY_ADD_DEL, mp);
9194
9195   mp->is_del = is_del;
9196   mp->sw_if_index = ntohl (sw_if_index);
9197   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9198
9199   /* send it... */
9200   S (mp);
9201
9202   /* Wait for a reply, return good/bad news  */
9203   W (ret);
9204   return ret;
9205 }
9206
9207 static int
9208 api_ip6nd_proxy_dump (vat_main_t * vam)
9209 {
9210   vl_api_ip6nd_proxy_dump_t *mp;
9211   vl_api_control_ping_t *mp_ping;
9212   int ret;
9213
9214   M (IP6ND_PROXY_DUMP, mp);
9215
9216   S (mp);
9217
9218   /* Use a control ping for synchronization */
9219   M (CONTROL_PING, mp_ping);
9220   S (mp_ping);
9221
9222   W (ret);
9223   return ret;
9224 }
9225
9226 static void vl_api_ip6nd_proxy_details_t_handler
9227   (vl_api_ip6nd_proxy_details_t * mp)
9228 {
9229   vat_main_t *vam = &vat_main;
9230
9231   print (vam->ofp, "host %U sw_if_index %d",
9232          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
9233 }
9234
9235 static void vl_api_ip6nd_proxy_details_t_handler_json
9236   (vl_api_ip6nd_proxy_details_t * mp)
9237 {
9238   vat_main_t *vam = &vat_main;
9239   struct in6_addr ip6;
9240   vat_json_node_t *node = NULL;
9241
9242   if (VAT_JSON_ARRAY != vam->json_tree.type)
9243     {
9244       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9245       vat_json_init_array (&vam->json_tree);
9246     }
9247   node = vat_json_array_add (&vam->json_tree);
9248
9249   vat_json_init_object (node);
9250   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9251
9252   clib_memcpy (&ip6, mp->address, sizeof (ip6));
9253   vat_json_object_add_ip6 (node, "host", ip6);
9254 }
9255
9256 static int
9257 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9258 {
9259   unformat_input_t *i = vam->input;
9260   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9261   u32 sw_if_index;
9262   u8 sw_if_index_set = 0;
9263   u32 address_length = 0;
9264   u8 v6_address_set = 0;
9265   ip6_address_t v6address;
9266   u8 use_default = 0;
9267   u8 no_advertise = 0;
9268   u8 off_link = 0;
9269   u8 no_autoconfig = 0;
9270   u8 no_onlink = 0;
9271   u8 is_no = 0;
9272   u32 val_lifetime = 0;
9273   u32 pref_lifetime = 0;
9274   int ret;
9275
9276   /* Parse args required to build the message */
9277   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9278     {
9279       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9280         sw_if_index_set = 1;
9281       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9282         sw_if_index_set = 1;
9283       else if (unformat (i, "%U/%d",
9284                          unformat_ip6_address, &v6address, &address_length))
9285         v6_address_set = 1;
9286       else if (unformat (i, "val_life %d", &val_lifetime))
9287         ;
9288       else if (unformat (i, "pref_life %d", &pref_lifetime))
9289         ;
9290       else if (unformat (i, "def"))
9291         use_default = 1;
9292       else if (unformat (i, "noadv"))
9293         no_advertise = 1;
9294       else if (unformat (i, "offl"))
9295         off_link = 1;
9296       else if (unformat (i, "noauto"))
9297         no_autoconfig = 1;
9298       else if (unformat (i, "nolink"))
9299         no_onlink = 1;
9300       else if (unformat (i, "isno"))
9301         is_no = 1;
9302       else
9303         {
9304           clib_warning ("parse error '%U'", format_unformat_error, i);
9305           return -99;
9306         }
9307     }
9308
9309   if (sw_if_index_set == 0)
9310     {
9311       errmsg ("missing interface name or sw_if_index");
9312       return -99;
9313     }
9314   if (!v6_address_set)
9315     {
9316       errmsg ("no address set");
9317       return -99;
9318     }
9319
9320   /* Construct the API message */
9321   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9322
9323   mp->sw_if_index = ntohl (sw_if_index);
9324   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9325   mp->address_length = address_length;
9326   mp->use_default = use_default;
9327   mp->no_advertise = no_advertise;
9328   mp->off_link = off_link;
9329   mp->no_autoconfig = no_autoconfig;
9330   mp->no_onlink = no_onlink;
9331   mp->is_no = is_no;
9332   mp->val_lifetime = ntohl (val_lifetime);
9333   mp->pref_lifetime = ntohl (pref_lifetime);
9334
9335   /* send it... */
9336   S (mp);
9337
9338   /* Wait for a reply, return good/bad news  */
9339   W (ret);
9340   return ret;
9341 }
9342
9343 static int
9344 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9345 {
9346   unformat_input_t *i = vam->input;
9347   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9348   u32 sw_if_index;
9349   u8 sw_if_index_set = 0;
9350   u8 suppress = 0;
9351   u8 managed = 0;
9352   u8 other = 0;
9353   u8 ll_option = 0;
9354   u8 send_unicast = 0;
9355   u8 cease = 0;
9356   u8 is_no = 0;
9357   u8 default_router = 0;
9358   u32 max_interval = 0;
9359   u32 min_interval = 0;
9360   u32 lifetime = 0;
9361   u32 initial_count = 0;
9362   u32 initial_interval = 0;
9363   int ret;
9364
9365
9366   /* Parse args required to build the message */
9367   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9368     {
9369       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9370         sw_if_index_set = 1;
9371       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9372         sw_if_index_set = 1;
9373       else if (unformat (i, "maxint %d", &max_interval))
9374         ;
9375       else if (unformat (i, "minint %d", &min_interval))
9376         ;
9377       else if (unformat (i, "life %d", &lifetime))
9378         ;
9379       else if (unformat (i, "count %d", &initial_count))
9380         ;
9381       else if (unformat (i, "interval %d", &initial_interval))
9382         ;
9383       else if (unformat (i, "suppress") || unformat (i, "surpress"))
9384         suppress = 1;
9385       else if (unformat (i, "managed"))
9386         managed = 1;
9387       else if (unformat (i, "other"))
9388         other = 1;
9389       else if (unformat (i, "ll"))
9390         ll_option = 1;
9391       else if (unformat (i, "send"))
9392         send_unicast = 1;
9393       else if (unformat (i, "cease"))
9394         cease = 1;
9395       else if (unformat (i, "isno"))
9396         is_no = 1;
9397       else if (unformat (i, "def"))
9398         default_router = 1;
9399       else
9400         {
9401           clib_warning ("parse error '%U'", format_unformat_error, i);
9402           return -99;
9403         }
9404     }
9405
9406   if (sw_if_index_set == 0)
9407     {
9408       errmsg ("missing interface name or sw_if_index");
9409       return -99;
9410     }
9411
9412   /* Construct the API message */
9413   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
9414
9415   mp->sw_if_index = ntohl (sw_if_index);
9416   mp->max_interval = ntohl (max_interval);
9417   mp->min_interval = ntohl (min_interval);
9418   mp->lifetime = ntohl (lifetime);
9419   mp->initial_count = ntohl (initial_count);
9420   mp->initial_interval = ntohl (initial_interval);
9421   mp->suppress = suppress;
9422   mp->managed = managed;
9423   mp->other = other;
9424   mp->ll_option = ll_option;
9425   mp->send_unicast = send_unicast;
9426   mp->cease = cease;
9427   mp->is_no = is_no;
9428   mp->default_router = default_router;
9429
9430   /* send it... */
9431   S (mp);
9432
9433   /* Wait for a reply, return good/bad news  */
9434   W (ret);
9435   return ret;
9436 }
9437
9438 static int
9439 api_set_arp_neighbor_limit (vat_main_t * vam)
9440 {
9441   unformat_input_t *i = vam->input;
9442   vl_api_set_arp_neighbor_limit_t *mp;
9443   u32 arp_nbr_limit;
9444   u8 limit_set = 0;
9445   u8 is_ipv6 = 0;
9446   int ret;
9447
9448   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9449     {
9450       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
9451         limit_set = 1;
9452       else if (unformat (i, "ipv6"))
9453         is_ipv6 = 1;
9454       else
9455         {
9456           clib_warning ("parse error '%U'", format_unformat_error, i);
9457           return -99;
9458         }
9459     }
9460
9461   if (limit_set == 0)
9462     {
9463       errmsg ("missing limit value");
9464       return -99;
9465     }
9466
9467   M (SET_ARP_NEIGHBOR_LIMIT, mp);
9468
9469   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
9470   mp->is_ipv6 = is_ipv6;
9471
9472   S (mp);
9473   W (ret);
9474   return ret;
9475 }
9476
9477 static int
9478 api_l2_patch_add_del (vat_main_t * vam)
9479 {
9480   unformat_input_t *i = vam->input;
9481   vl_api_l2_patch_add_del_t *mp;
9482   u32 rx_sw_if_index;
9483   u8 rx_sw_if_index_set = 0;
9484   u32 tx_sw_if_index;
9485   u8 tx_sw_if_index_set = 0;
9486   u8 is_add = 1;
9487   int ret;
9488
9489   /* Parse args required to build the message */
9490   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9491     {
9492       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9493         rx_sw_if_index_set = 1;
9494       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9495         tx_sw_if_index_set = 1;
9496       else if (unformat (i, "rx"))
9497         {
9498           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9499             {
9500               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9501                             &rx_sw_if_index))
9502                 rx_sw_if_index_set = 1;
9503             }
9504           else
9505             break;
9506         }
9507       else if (unformat (i, "tx"))
9508         {
9509           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9510             {
9511               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9512                             &tx_sw_if_index))
9513                 tx_sw_if_index_set = 1;
9514             }
9515           else
9516             break;
9517         }
9518       else if (unformat (i, "del"))
9519         is_add = 0;
9520       else
9521         break;
9522     }
9523
9524   if (rx_sw_if_index_set == 0)
9525     {
9526       errmsg ("missing rx interface name or rx_sw_if_index");
9527       return -99;
9528     }
9529
9530   if (tx_sw_if_index_set == 0)
9531     {
9532       errmsg ("missing tx interface name or tx_sw_if_index");
9533       return -99;
9534     }
9535
9536   M (L2_PATCH_ADD_DEL, mp);
9537
9538   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9539   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9540   mp->is_add = is_add;
9541
9542   S (mp);
9543   W (ret);
9544   return ret;
9545 }
9546
9547 u8 is_del;
9548 u8 localsid_addr[16];
9549 u8 end_psp;
9550 u8 behavior;
9551 u32 sw_if_index;
9552 u32 vlan_index;
9553 u32 fib_table;
9554 u8 nh_addr[16];
9555
9556 static int
9557 api_sr_localsid_add_del (vat_main_t * vam)
9558 {
9559   unformat_input_t *i = vam->input;
9560   vl_api_sr_localsid_add_del_t *mp;
9561
9562   u8 is_del;
9563   ip6_address_t localsid;
9564   u8 end_psp = 0;
9565   u8 behavior = ~0;
9566   u32 sw_if_index;
9567   u32 fib_table = ~(u32) 0;
9568   ip6_address_t next_hop;
9569
9570   bool nexthop_set = 0;
9571
9572   int ret;
9573
9574   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9575     {
9576       if (unformat (i, "del"))
9577         is_del = 1;
9578       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9579       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
9580         nexthop_set = 1;
9581       else if (unformat (i, "behavior %u", &behavior));
9582       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9583       else if (unformat (i, "fib-table %u", &fib_table));
9584       else if (unformat (i, "end.psp %u", &behavior));
9585       else
9586         break;
9587     }
9588
9589   M (SR_LOCALSID_ADD_DEL, mp);
9590
9591   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
9592   if (nexthop_set)
9593     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
9594   mp->behavior = behavior;
9595   mp->sw_if_index = ntohl (sw_if_index);
9596   mp->fib_table = ntohl (fib_table);
9597   mp->end_psp = end_psp;
9598   mp->is_del = is_del;
9599
9600   S (mp);
9601   W (ret);
9602   return ret;
9603 }
9604
9605 static int
9606 api_ioam_enable (vat_main_t * vam)
9607 {
9608   unformat_input_t *input = vam->input;
9609   vl_api_ioam_enable_t *mp;
9610   u32 id = 0;
9611   int has_trace_option = 0;
9612   int has_pot_option = 0;
9613   int has_seqno_option = 0;
9614   int has_analyse_option = 0;
9615   int ret;
9616
9617   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9618     {
9619       if (unformat (input, "trace"))
9620         has_trace_option = 1;
9621       else if (unformat (input, "pot"))
9622         has_pot_option = 1;
9623       else if (unformat (input, "seqno"))
9624         has_seqno_option = 1;
9625       else if (unformat (input, "analyse"))
9626         has_analyse_option = 1;
9627       else
9628         break;
9629     }
9630   M (IOAM_ENABLE, mp);
9631   mp->id = htons (id);
9632   mp->seqno = has_seqno_option;
9633   mp->analyse = has_analyse_option;
9634   mp->pot_enable = has_pot_option;
9635   mp->trace_enable = has_trace_option;
9636
9637   S (mp);
9638   W (ret);
9639   return ret;
9640 }
9641
9642
9643 static int
9644 api_ioam_disable (vat_main_t * vam)
9645 {
9646   vl_api_ioam_disable_t *mp;
9647   int ret;
9648
9649   M (IOAM_DISABLE, mp);
9650   S (mp);
9651   W (ret);
9652   return ret;
9653 }
9654
9655 #define foreach_tcp_proto_field                 \
9656 _(src_port)                                     \
9657 _(dst_port)
9658
9659 #define foreach_udp_proto_field                 \
9660 _(src_port)                                     \
9661 _(dst_port)
9662
9663 #define foreach_ip4_proto_field                 \
9664 _(src_address)                                  \
9665 _(dst_address)                                  \
9666 _(tos)                                          \
9667 _(length)                                       \
9668 _(fragment_id)                                  \
9669 _(ttl)                                          \
9670 _(protocol)                                     \
9671 _(checksum)
9672
9673 typedef struct
9674 {
9675   u16 src_port, dst_port;
9676 } tcpudp_header_t;
9677
9678 #if VPP_API_TEST_BUILTIN == 0
9679 uword
9680 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9681 {
9682   u8 **maskp = va_arg (*args, u8 **);
9683   u8 *mask = 0;
9684   u8 found_something = 0;
9685   tcp_header_t *tcp;
9686
9687 #define _(a) u8 a=0;
9688   foreach_tcp_proto_field;
9689 #undef _
9690
9691   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9692     {
9693       if (0);
9694 #define _(a) else if (unformat (input, #a)) a=1;
9695       foreach_tcp_proto_field
9696 #undef _
9697         else
9698         break;
9699     }
9700
9701 #define _(a) found_something += a;
9702   foreach_tcp_proto_field;
9703 #undef _
9704
9705   if (found_something == 0)
9706     return 0;
9707
9708   vec_validate (mask, sizeof (*tcp) - 1);
9709
9710   tcp = (tcp_header_t *) mask;
9711
9712 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
9713   foreach_tcp_proto_field;
9714 #undef _
9715
9716   *maskp = mask;
9717   return 1;
9718 }
9719
9720 uword
9721 unformat_udp_mask (unformat_input_t * input, va_list * args)
9722 {
9723   u8 **maskp = va_arg (*args, u8 **);
9724   u8 *mask = 0;
9725   u8 found_something = 0;
9726   udp_header_t *udp;
9727
9728 #define _(a) u8 a=0;
9729   foreach_udp_proto_field;
9730 #undef _
9731
9732   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9733     {
9734       if (0);
9735 #define _(a) else if (unformat (input, #a)) a=1;
9736       foreach_udp_proto_field
9737 #undef _
9738         else
9739         break;
9740     }
9741
9742 #define _(a) found_something += a;
9743   foreach_udp_proto_field;
9744 #undef _
9745
9746   if (found_something == 0)
9747     return 0;
9748
9749   vec_validate (mask, sizeof (*udp) - 1);
9750
9751   udp = (udp_header_t *) mask;
9752
9753 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
9754   foreach_udp_proto_field;
9755 #undef _
9756
9757   *maskp = mask;
9758   return 1;
9759 }
9760
9761 uword
9762 unformat_l4_mask (unformat_input_t * input, va_list * args)
9763 {
9764   u8 **maskp = va_arg (*args, u8 **);
9765   u16 src_port = 0, dst_port = 0;
9766   tcpudp_header_t *tcpudp;
9767
9768   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9769     {
9770       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9771         return 1;
9772       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9773         return 1;
9774       else if (unformat (input, "src_port"))
9775         src_port = 0xFFFF;
9776       else if (unformat (input, "dst_port"))
9777         dst_port = 0xFFFF;
9778       else
9779         return 0;
9780     }
9781
9782   if (!src_port && !dst_port)
9783     return 0;
9784
9785   u8 *mask = 0;
9786   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9787
9788   tcpudp = (tcpudp_header_t *) mask;
9789   tcpudp->src_port = src_port;
9790   tcpudp->dst_port = dst_port;
9791
9792   *maskp = mask;
9793
9794   return 1;
9795 }
9796
9797 uword
9798 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9799 {
9800   u8 **maskp = va_arg (*args, u8 **);
9801   u8 *mask = 0;
9802   u8 found_something = 0;
9803   ip4_header_t *ip;
9804
9805 #define _(a) u8 a=0;
9806   foreach_ip4_proto_field;
9807 #undef _
9808   u8 version = 0;
9809   u8 hdr_length = 0;
9810
9811
9812   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9813     {
9814       if (unformat (input, "version"))
9815         version = 1;
9816       else if (unformat (input, "hdr_length"))
9817         hdr_length = 1;
9818       else if (unformat (input, "src"))
9819         src_address = 1;
9820       else if (unformat (input, "dst"))
9821         dst_address = 1;
9822       else if (unformat (input, "proto"))
9823         protocol = 1;
9824
9825 #define _(a) else if (unformat (input, #a)) a=1;
9826       foreach_ip4_proto_field
9827 #undef _
9828         else
9829         break;
9830     }
9831
9832 #define _(a) found_something += a;
9833   foreach_ip4_proto_field;
9834 #undef _
9835
9836   if (found_something == 0)
9837     return 0;
9838
9839   vec_validate (mask, sizeof (*ip) - 1);
9840
9841   ip = (ip4_header_t *) mask;
9842
9843 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9844   foreach_ip4_proto_field;
9845 #undef _
9846
9847   ip->ip_version_and_header_length = 0;
9848
9849   if (version)
9850     ip->ip_version_and_header_length |= 0xF0;
9851
9852   if (hdr_length)
9853     ip->ip_version_and_header_length |= 0x0F;
9854
9855   *maskp = mask;
9856   return 1;
9857 }
9858
9859 #define foreach_ip6_proto_field                 \
9860 _(src_address)                                  \
9861 _(dst_address)                                  \
9862 _(payload_length)                               \
9863 _(hop_limit)                                    \
9864 _(protocol)
9865
9866 uword
9867 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9868 {
9869   u8 **maskp = va_arg (*args, u8 **);
9870   u8 *mask = 0;
9871   u8 found_something = 0;
9872   ip6_header_t *ip;
9873   u32 ip_version_traffic_class_and_flow_label;
9874
9875 #define _(a) u8 a=0;
9876   foreach_ip6_proto_field;
9877 #undef _
9878   u8 version = 0;
9879   u8 traffic_class = 0;
9880   u8 flow_label = 0;
9881
9882   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9883     {
9884       if (unformat (input, "version"))
9885         version = 1;
9886       else if (unformat (input, "traffic-class"))
9887         traffic_class = 1;
9888       else if (unformat (input, "flow-label"))
9889         flow_label = 1;
9890       else if (unformat (input, "src"))
9891         src_address = 1;
9892       else if (unformat (input, "dst"))
9893         dst_address = 1;
9894       else if (unformat (input, "proto"))
9895         protocol = 1;
9896
9897 #define _(a) else if (unformat (input, #a)) a=1;
9898       foreach_ip6_proto_field
9899 #undef _
9900         else
9901         break;
9902     }
9903
9904 #define _(a) found_something += a;
9905   foreach_ip6_proto_field;
9906 #undef _
9907
9908   if (found_something == 0)
9909     return 0;
9910
9911   vec_validate (mask, sizeof (*ip) - 1);
9912
9913   ip = (ip6_header_t *) mask;
9914
9915 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9916   foreach_ip6_proto_field;
9917 #undef _
9918
9919   ip_version_traffic_class_and_flow_label = 0;
9920
9921   if (version)
9922     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9923
9924   if (traffic_class)
9925     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9926
9927   if (flow_label)
9928     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9929
9930   ip->ip_version_traffic_class_and_flow_label =
9931     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9932
9933   *maskp = mask;
9934   return 1;
9935 }
9936
9937 uword
9938 unformat_l3_mask (unformat_input_t * input, va_list * args)
9939 {
9940   u8 **maskp = va_arg (*args, u8 **);
9941
9942   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9943     {
9944       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9945         return 1;
9946       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9947         return 1;
9948       else
9949         break;
9950     }
9951   return 0;
9952 }
9953
9954 uword
9955 unformat_l2_mask (unformat_input_t * input, va_list * args)
9956 {
9957   u8 **maskp = va_arg (*args, u8 **);
9958   u8 *mask = 0;
9959   u8 src = 0;
9960   u8 dst = 0;
9961   u8 proto = 0;
9962   u8 tag1 = 0;
9963   u8 tag2 = 0;
9964   u8 ignore_tag1 = 0;
9965   u8 ignore_tag2 = 0;
9966   u8 cos1 = 0;
9967   u8 cos2 = 0;
9968   u8 dot1q = 0;
9969   u8 dot1ad = 0;
9970   int len = 14;
9971
9972   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9973     {
9974       if (unformat (input, "src"))
9975         src = 1;
9976       else if (unformat (input, "dst"))
9977         dst = 1;
9978       else if (unformat (input, "proto"))
9979         proto = 1;
9980       else if (unformat (input, "tag1"))
9981         tag1 = 1;
9982       else if (unformat (input, "tag2"))
9983         tag2 = 1;
9984       else if (unformat (input, "ignore-tag1"))
9985         ignore_tag1 = 1;
9986       else if (unformat (input, "ignore-tag2"))
9987         ignore_tag2 = 1;
9988       else if (unformat (input, "cos1"))
9989         cos1 = 1;
9990       else if (unformat (input, "cos2"))
9991         cos2 = 1;
9992       else if (unformat (input, "dot1q"))
9993         dot1q = 1;
9994       else if (unformat (input, "dot1ad"))
9995         dot1ad = 1;
9996       else
9997         break;
9998     }
9999   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10000        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10001     return 0;
10002
10003   if (tag1 || ignore_tag1 || cos1 || dot1q)
10004     len = 18;
10005   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10006     len = 22;
10007
10008   vec_validate (mask, len - 1);
10009
10010   if (dst)
10011     memset (mask, 0xff, 6);
10012
10013   if (src)
10014     memset (mask + 6, 0xff, 6);
10015
10016   if (tag2 || dot1ad)
10017     {
10018       /* inner vlan tag */
10019       if (tag2)
10020         {
10021           mask[19] = 0xff;
10022           mask[18] = 0x0f;
10023         }
10024       if (cos2)
10025         mask[18] |= 0xe0;
10026       if (proto)
10027         mask[21] = mask[20] = 0xff;
10028       if (tag1)
10029         {
10030           mask[15] = 0xff;
10031           mask[14] = 0x0f;
10032         }
10033       if (cos1)
10034         mask[14] |= 0xe0;
10035       *maskp = mask;
10036       return 1;
10037     }
10038   if (tag1 | dot1q)
10039     {
10040       if (tag1)
10041         {
10042           mask[15] = 0xff;
10043           mask[14] = 0x0f;
10044         }
10045       if (cos1)
10046         mask[14] |= 0xe0;
10047       if (proto)
10048         mask[16] = mask[17] = 0xff;
10049
10050       *maskp = mask;
10051       return 1;
10052     }
10053   if (cos2)
10054     mask[18] |= 0xe0;
10055   if (cos1)
10056     mask[14] |= 0xe0;
10057   if (proto)
10058     mask[12] = mask[13] = 0xff;
10059
10060   *maskp = mask;
10061   return 1;
10062 }
10063
10064 uword
10065 unformat_classify_mask (unformat_input_t * input, va_list * args)
10066 {
10067   u8 **maskp = va_arg (*args, u8 **);
10068   u32 *skipp = va_arg (*args, u32 *);
10069   u32 *matchp = va_arg (*args, u32 *);
10070   u32 match;
10071   u8 *mask = 0;
10072   u8 *l2 = 0;
10073   u8 *l3 = 0;
10074   u8 *l4 = 0;
10075   int i;
10076
10077   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10078     {
10079       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10080         ;
10081       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10082         ;
10083       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10084         ;
10085       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10086         ;
10087       else
10088         break;
10089     }
10090
10091   if (l4 && !l3)
10092     {
10093       vec_free (mask);
10094       vec_free (l2);
10095       vec_free (l4);
10096       return 0;
10097     }
10098
10099   if (mask || l2 || l3 || l4)
10100     {
10101       if (l2 || l3 || l4)
10102         {
10103           /* "With a free Ethernet header in every package" */
10104           if (l2 == 0)
10105             vec_validate (l2, 13);
10106           mask = l2;
10107           if (vec_len (l3))
10108             {
10109               vec_append (mask, l3);
10110               vec_free (l3);
10111             }
10112           if (vec_len (l4))
10113             {
10114               vec_append (mask, l4);
10115               vec_free (l4);
10116             }
10117         }
10118
10119       /* Scan forward looking for the first significant mask octet */
10120       for (i = 0; i < vec_len (mask); i++)
10121         if (mask[i])
10122           break;
10123
10124       /* compute (skip, match) params */
10125       *skipp = i / sizeof (u32x4);
10126       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10127
10128       /* Pad mask to an even multiple of the vector size */
10129       while (vec_len (mask) % sizeof (u32x4))
10130         vec_add1 (mask, 0);
10131
10132       match = vec_len (mask) / sizeof (u32x4);
10133
10134       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10135         {
10136           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10137           if (*tmp || *(tmp + 1))
10138             break;
10139           match--;
10140         }
10141       if (match == 0)
10142         clib_warning ("BUG: match 0");
10143
10144       _vec_len (mask) = match * sizeof (u32x4);
10145
10146       *matchp = match;
10147       *maskp = mask;
10148
10149       return 1;
10150     }
10151
10152   return 0;
10153 }
10154 #endif /* VPP_API_TEST_BUILTIN */
10155
10156 #define foreach_l2_next                         \
10157 _(drop, DROP)                                   \
10158 _(ethernet, ETHERNET_INPUT)                     \
10159 _(ip4, IP4_INPUT)                               \
10160 _(ip6, IP6_INPUT)
10161
10162 uword
10163 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10164 {
10165   u32 *miss_next_indexp = va_arg (*args, u32 *);
10166   u32 next_index = 0;
10167   u32 tmp;
10168
10169 #define _(n,N) \
10170   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10171   foreach_l2_next;
10172 #undef _
10173
10174   if (unformat (input, "%d", &tmp))
10175     {
10176       next_index = tmp;
10177       goto out;
10178     }
10179
10180   return 0;
10181
10182 out:
10183   *miss_next_indexp = next_index;
10184   return 1;
10185 }
10186
10187 #define foreach_ip_next                         \
10188 _(drop, DROP)                                   \
10189 _(local, LOCAL)                                 \
10190 _(rewrite, REWRITE)
10191
10192 uword
10193 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10194 {
10195   u32 *miss_next_indexp = va_arg (*args, u32 *);
10196   u32 next_index = 0;
10197   u32 tmp;
10198
10199 #define _(n,N) \
10200   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10201   foreach_ip_next;
10202 #undef _
10203
10204   if (unformat (input, "%d", &tmp))
10205     {
10206       next_index = tmp;
10207       goto out;
10208     }
10209
10210   return 0;
10211
10212 out:
10213   *miss_next_indexp = next_index;
10214   return 1;
10215 }
10216
10217 #define foreach_acl_next                        \
10218 _(deny, DENY)
10219
10220 uword
10221 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10222 {
10223   u32 *miss_next_indexp = va_arg (*args, u32 *);
10224   u32 next_index = 0;
10225   u32 tmp;
10226
10227 #define _(n,N) \
10228   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10229   foreach_acl_next;
10230 #undef _
10231
10232   if (unformat (input, "permit"))
10233     {
10234       next_index = ~0;
10235       goto out;
10236     }
10237   else if (unformat (input, "%d", &tmp))
10238     {
10239       next_index = tmp;
10240       goto out;
10241     }
10242
10243   return 0;
10244
10245 out:
10246   *miss_next_indexp = next_index;
10247   return 1;
10248 }
10249
10250 uword
10251 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10252 {
10253   u32 *r = va_arg (*args, u32 *);
10254
10255   if (unformat (input, "conform-color"))
10256     *r = POLICE_CONFORM;
10257   else if (unformat (input, "exceed-color"))
10258     *r = POLICE_EXCEED;
10259   else
10260     return 0;
10261
10262   return 1;
10263 }
10264
10265 static int
10266 api_classify_add_del_table (vat_main_t * vam)
10267 {
10268   unformat_input_t *i = vam->input;
10269   vl_api_classify_add_del_table_t *mp;
10270
10271   u32 nbuckets = 2;
10272   u32 skip = ~0;
10273   u32 match = ~0;
10274   int is_add = 1;
10275   int del_chain = 0;
10276   u32 table_index = ~0;
10277   u32 next_table_index = ~0;
10278   u32 miss_next_index = ~0;
10279   u32 memory_size = 32 << 20;
10280   u8 *mask = 0;
10281   u32 current_data_flag = 0;
10282   int current_data_offset = 0;
10283   int ret;
10284
10285   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10286     {
10287       if (unformat (i, "del"))
10288         is_add = 0;
10289       else if (unformat (i, "del-chain"))
10290         {
10291           is_add = 0;
10292           del_chain = 1;
10293         }
10294       else if (unformat (i, "buckets %d", &nbuckets))
10295         ;
10296       else if (unformat (i, "memory_size %d", &memory_size))
10297         ;
10298       else if (unformat (i, "skip %d", &skip))
10299         ;
10300       else if (unformat (i, "match %d", &match))
10301         ;
10302       else if (unformat (i, "table %d", &table_index))
10303         ;
10304       else if (unformat (i, "mask %U", unformat_classify_mask,
10305                          &mask, &skip, &match))
10306         ;
10307       else if (unformat (i, "next-table %d", &next_table_index))
10308         ;
10309       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10310                          &miss_next_index))
10311         ;
10312       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10313                          &miss_next_index))
10314         ;
10315       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10316                          &miss_next_index))
10317         ;
10318       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10319         ;
10320       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10321         ;
10322       else
10323         break;
10324     }
10325
10326   if (is_add && mask == 0)
10327     {
10328       errmsg ("Mask required");
10329       return -99;
10330     }
10331
10332   if (is_add && skip == ~0)
10333     {
10334       errmsg ("skip count required");
10335       return -99;
10336     }
10337
10338   if (is_add && match == ~0)
10339     {
10340       errmsg ("match count required");
10341       return -99;
10342     }
10343
10344   if (!is_add && table_index == ~0)
10345     {
10346       errmsg ("table index required for delete");
10347       return -99;
10348     }
10349
10350   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10351
10352   mp->is_add = is_add;
10353   mp->del_chain = del_chain;
10354   mp->table_index = ntohl (table_index);
10355   mp->nbuckets = ntohl (nbuckets);
10356   mp->memory_size = ntohl (memory_size);
10357   mp->skip_n_vectors = ntohl (skip);
10358   mp->match_n_vectors = ntohl (match);
10359   mp->next_table_index = ntohl (next_table_index);
10360   mp->miss_next_index = ntohl (miss_next_index);
10361   mp->current_data_flag = ntohl (current_data_flag);
10362   mp->current_data_offset = ntohl (current_data_offset);
10363   clib_memcpy (mp->mask, mask, vec_len (mask));
10364
10365   vec_free (mask);
10366
10367   S (mp);
10368   W (ret);
10369   return ret;
10370 }
10371
10372 #if VPP_API_TEST_BUILTIN == 0
10373 uword
10374 unformat_l4_match (unformat_input_t * input, va_list * args)
10375 {
10376   u8 **matchp = va_arg (*args, u8 **);
10377
10378   u8 *proto_header = 0;
10379   int src_port = 0;
10380   int dst_port = 0;
10381
10382   tcpudp_header_t h;
10383
10384   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10385     {
10386       if (unformat (input, "src_port %d", &src_port))
10387         ;
10388       else if (unformat (input, "dst_port %d", &dst_port))
10389         ;
10390       else
10391         return 0;
10392     }
10393
10394   h.src_port = clib_host_to_net_u16 (src_port);
10395   h.dst_port = clib_host_to_net_u16 (dst_port);
10396   vec_validate (proto_header, sizeof (h) - 1);
10397   memcpy (proto_header, &h, sizeof (h));
10398
10399   *matchp = proto_header;
10400
10401   return 1;
10402 }
10403
10404 uword
10405 unformat_ip4_match (unformat_input_t * input, va_list * args)
10406 {
10407   u8 **matchp = va_arg (*args, u8 **);
10408   u8 *match = 0;
10409   ip4_header_t *ip;
10410   int version = 0;
10411   u32 version_val;
10412   int hdr_length = 0;
10413   u32 hdr_length_val;
10414   int src = 0, dst = 0;
10415   ip4_address_t src_val, dst_val;
10416   int proto = 0;
10417   u32 proto_val;
10418   int tos = 0;
10419   u32 tos_val;
10420   int length = 0;
10421   u32 length_val;
10422   int fragment_id = 0;
10423   u32 fragment_id_val;
10424   int ttl = 0;
10425   int ttl_val;
10426   int checksum = 0;
10427   u32 checksum_val;
10428
10429   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10430     {
10431       if (unformat (input, "version %d", &version_val))
10432         version = 1;
10433       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10434         hdr_length = 1;
10435       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10436         src = 1;
10437       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10438         dst = 1;
10439       else if (unformat (input, "proto %d", &proto_val))
10440         proto = 1;
10441       else if (unformat (input, "tos %d", &tos_val))
10442         tos = 1;
10443       else if (unformat (input, "length %d", &length_val))
10444         length = 1;
10445       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10446         fragment_id = 1;
10447       else if (unformat (input, "ttl %d", &ttl_val))
10448         ttl = 1;
10449       else if (unformat (input, "checksum %d", &checksum_val))
10450         checksum = 1;
10451       else
10452         break;
10453     }
10454
10455   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10456       + ttl + checksum == 0)
10457     return 0;
10458
10459   /*
10460    * Aligned because we use the real comparison functions
10461    */
10462   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10463
10464   ip = (ip4_header_t *) match;
10465
10466   /* These are realistically matched in practice */
10467   if (src)
10468     ip->src_address.as_u32 = src_val.as_u32;
10469
10470   if (dst)
10471     ip->dst_address.as_u32 = dst_val.as_u32;
10472
10473   if (proto)
10474     ip->protocol = proto_val;
10475
10476
10477   /* These are not, but they're included for completeness */
10478   if (version)
10479     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10480
10481   if (hdr_length)
10482     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10483
10484   if (tos)
10485     ip->tos = tos_val;
10486
10487   if (length)
10488     ip->length = clib_host_to_net_u16 (length_val);
10489
10490   if (ttl)
10491     ip->ttl = ttl_val;
10492
10493   if (checksum)
10494     ip->checksum = clib_host_to_net_u16 (checksum_val);
10495
10496   *matchp = match;
10497   return 1;
10498 }
10499
10500 uword
10501 unformat_ip6_match (unformat_input_t * input, va_list * args)
10502 {
10503   u8 **matchp = va_arg (*args, u8 **);
10504   u8 *match = 0;
10505   ip6_header_t *ip;
10506   int version = 0;
10507   u32 version_val;
10508   u8 traffic_class = 0;
10509   u32 traffic_class_val = 0;
10510   u8 flow_label = 0;
10511   u8 flow_label_val;
10512   int src = 0, dst = 0;
10513   ip6_address_t src_val, dst_val;
10514   int proto = 0;
10515   u32 proto_val;
10516   int payload_length = 0;
10517   u32 payload_length_val;
10518   int hop_limit = 0;
10519   int hop_limit_val;
10520   u32 ip_version_traffic_class_and_flow_label;
10521
10522   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10523     {
10524       if (unformat (input, "version %d", &version_val))
10525         version = 1;
10526       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10527         traffic_class = 1;
10528       else if (unformat (input, "flow_label %d", &flow_label_val))
10529         flow_label = 1;
10530       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10531         src = 1;
10532       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10533         dst = 1;
10534       else if (unformat (input, "proto %d", &proto_val))
10535         proto = 1;
10536       else if (unformat (input, "payload_length %d", &payload_length_val))
10537         payload_length = 1;
10538       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10539         hop_limit = 1;
10540       else
10541         break;
10542     }
10543
10544   if (version + traffic_class + flow_label + src + dst + proto +
10545       payload_length + hop_limit == 0)
10546     return 0;
10547
10548   /*
10549    * Aligned because we use the real comparison functions
10550    */
10551   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10552
10553   ip = (ip6_header_t *) match;
10554
10555   if (src)
10556     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10557
10558   if (dst)
10559     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10560
10561   if (proto)
10562     ip->protocol = proto_val;
10563
10564   ip_version_traffic_class_and_flow_label = 0;
10565
10566   if (version)
10567     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10568
10569   if (traffic_class)
10570     ip_version_traffic_class_and_flow_label |=
10571       (traffic_class_val & 0xFF) << 20;
10572
10573   if (flow_label)
10574     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10575
10576   ip->ip_version_traffic_class_and_flow_label =
10577     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10578
10579   if (payload_length)
10580     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10581
10582   if (hop_limit)
10583     ip->hop_limit = hop_limit_val;
10584
10585   *matchp = match;
10586   return 1;
10587 }
10588
10589 uword
10590 unformat_l3_match (unformat_input_t * input, va_list * args)
10591 {
10592   u8 **matchp = va_arg (*args, u8 **);
10593
10594   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10595     {
10596       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10597         return 1;
10598       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10599         return 1;
10600       else
10601         break;
10602     }
10603   return 0;
10604 }
10605
10606 uword
10607 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10608 {
10609   u8 *tagp = va_arg (*args, u8 *);
10610   u32 tag;
10611
10612   if (unformat (input, "%d", &tag))
10613     {
10614       tagp[0] = (tag >> 8) & 0x0F;
10615       tagp[1] = tag & 0xFF;
10616       return 1;
10617     }
10618
10619   return 0;
10620 }
10621
10622 uword
10623 unformat_l2_match (unformat_input_t * input, va_list * args)
10624 {
10625   u8 **matchp = va_arg (*args, u8 **);
10626   u8 *match = 0;
10627   u8 src = 0;
10628   u8 src_val[6];
10629   u8 dst = 0;
10630   u8 dst_val[6];
10631   u8 proto = 0;
10632   u16 proto_val;
10633   u8 tag1 = 0;
10634   u8 tag1_val[2];
10635   u8 tag2 = 0;
10636   u8 tag2_val[2];
10637   int len = 14;
10638   u8 ignore_tag1 = 0;
10639   u8 ignore_tag2 = 0;
10640   u8 cos1 = 0;
10641   u8 cos2 = 0;
10642   u32 cos1_val = 0;
10643   u32 cos2_val = 0;
10644
10645   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10646     {
10647       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10648         src = 1;
10649       else
10650         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10651         dst = 1;
10652       else if (unformat (input, "proto %U",
10653                          unformat_ethernet_type_host_byte_order, &proto_val))
10654         proto = 1;
10655       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10656         tag1 = 1;
10657       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10658         tag2 = 1;
10659       else if (unformat (input, "ignore-tag1"))
10660         ignore_tag1 = 1;
10661       else if (unformat (input, "ignore-tag2"))
10662         ignore_tag2 = 1;
10663       else if (unformat (input, "cos1 %d", &cos1_val))
10664         cos1 = 1;
10665       else if (unformat (input, "cos2 %d", &cos2_val))
10666         cos2 = 1;
10667       else
10668         break;
10669     }
10670   if ((src + dst + proto + tag1 + tag2 +
10671        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10672     return 0;
10673
10674   if (tag1 || ignore_tag1 || cos1)
10675     len = 18;
10676   if (tag2 || ignore_tag2 || cos2)
10677     len = 22;
10678
10679   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10680
10681   if (dst)
10682     clib_memcpy (match, dst_val, 6);
10683
10684   if (src)
10685     clib_memcpy (match + 6, src_val, 6);
10686
10687   if (tag2)
10688     {
10689       /* inner vlan tag */
10690       match[19] = tag2_val[1];
10691       match[18] = tag2_val[0];
10692       if (cos2)
10693         match[18] |= (cos2_val & 0x7) << 5;
10694       if (proto)
10695         {
10696           match[21] = proto_val & 0xff;
10697           match[20] = proto_val >> 8;
10698         }
10699       if (tag1)
10700         {
10701           match[15] = tag1_val[1];
10702           match[14] = tag1_val[0];
10703         }
10704       if (cos1)
10705         match[14] |= (cos1_val & 0x7) << 5;
10706       *matchp = match;
10707       return 1;
10708     }
10709   if (tag1)
10710     {
10711       match[15] = tag1_val[1];
10712       match[14] = tag1_val[0];
10713       if (proto)
10714         {
10715           match[17] = proto_val & 0xff;
10716           match[16] = proto_val >> 8;
10717         }
10718       if (cos1)
10719         match[14] |= (cos1_val & 0x7) << 5;
10720
10721       *matchp = match;
10722       return 1;
10723     }
10724   if (cos2)
10725     match[18] |= (cos2_val & 0x7) << 5;
10726   if (cos1)
10727     match[14] |= (cos1_val & 0x7) << 5;
10728   if (proto)
10729     {
10730       match[13] = proto_val & 0xff;
10731       match[12] = proto_val >> 8;
10732     }
10733
10734   *matchp = match;
10735   return 1;
10736 }
10737 #endif
10738
10739 uword
10740 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10741 {
10742   u8 **matchp = va_arg (*args, u8 **);
10743   u32 skip_n_vectors = va_arg (*args, u32);
10744   u32 match_n_vectors = va_arg (*args, u32);
10745
10746   u8 *match = 0;
10747   u8 *l2 = 0;
10748   u8 *l3 = 0;
10749   u8 *l4 = 0;
10750
10751   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10752     {
10753       if (unformat (input, "hex %U", unformat_hex_string, &match))
10754         ;
10755       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10756         ;
10757       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10758         ;
10759       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10760         ;
10761       else
10762         break;
10763     }
10764
10765   if (l4 && !l3)
10766     {
10767       vec_free (match);
10768       vec_free (l2);
10769       vec_free (l4);
10770       return 0;
10771     }
10772
10773   if (match || l2 || l3 || l4)
10774     {
10775       if (l2 || l3 || l4)
10776         {
10777           /* "Win a free Ethernet header in every packet" */
10778           if (l2 == 0)
10779             vec_validate_aligned (l2, 13, sizeof (u32x4));
10780           match = l2;
10781           if (vec_len (l3))
10782             {
10783               vec_append_aligned (match, l3, sizeof (u32x4));
10784               vec_free (l3);
10785             }
10786           if (vec_len (l4))
10787             {
10788               vec_append_aligned (match, l4, sizeof (u32x4));
10789               vec_free (l4);
10790             }
10791         }
10792
10793       /* Make sure the vector is big enough even if key is all 0's */
10794       vec_validate_aligned
10795         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10796          sizeof (u32x4));
10797
10798       /* Set size, include skipped vectors */
10799       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10800
10801       *matchp = match;
10802
10803       return 1;
10804     }
10805
10806   return 0;
10807 }
10808
10809 static int
10810 api_classify_add_del_session (vat_main_t * vam)
10811 {
10812   unformat_input_t *i = vam->input;
10813   vl_api_classify_add_del_session_t *mp;
10814   int is_add = 1;
10815   u32 table_index = ~0;
10816   u32 hit_next_index = ~0;
10817   u32 opaque_index = ~0;
10818   u8 *match = 0;
10819   i32 advance = 0;
10820   u32 skip_n_vectors = 0;
10821   u32 match_n_vectors = 0;
10822   u32 action = 0;
10823   u32 metadata = 0;
10824   int ret;
10825
10826   /*
10827    * Warning: you have to supply skip_n and match_n
10828    * because the API client cant simply look at the classify
10829    * table object.
10830    */
10831
10832   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10833     {
10834       if (unformat (i, "del"))
10835         is_add = 0;
10836       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10837                          &hit_next_index))
10838         ;
10839       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10840                          &hit_next_index))
10841         ;
10842       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10843                          &hit_next_index))
10844         ;
10845       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10846         ;
10847       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10848         ;
10849       else if (unformat (i, "opaque-index %d", &opaque_index))
10850         ;
10851       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10852         ;
10853       else if (unformat (i, "match_n %d", &match_n_vectors))
10854         ;
10855       else if (unformat (i, "match %U", api_unformat_classify_match,
10856                          &match, skip_n_vectors, match_n_vectors))
10857         ;
10858       else if (unformat (i, "advance %d", &advance))
10859         ;
10860       else if (unformat (i, "table-index %d", &table_index))
10861         ;
10862       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10863         action = 1;
10864       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10865         action = 2;
10866       else if (unformat (i, "action %d", &action))
10867         ;
10868       else if (unformat (i, "metadata %d", &metadata))
10869         ;
10870       else
10871         break;
10872     }
10873
10874   if (table_index == ~0)
10875     {
10876       errmsg ("Table index required");
10877       return -99;
10878     }
10879
10880   if (is_add && match == 0)
10881     {
10882       errmsg ("Match value required");
10883       return -99;
10884     }
10885
10886   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10887
10888   mp->is_add = is_add;
10889   mp->table_index = ntohl (table_index);
10890   mp->hit_next_index = ntohl (hit_next_index);
10891   mp->opaque_index = ntohl (opaque_index);
10892   mp->advance = ntohl (advance);
10893   mp->action = action;
10894   mp->metadata = ntohl (metadata);
10895   clib_memcpy (mp->match, match, vec_len (match));
10896   vec_free (match);
10897
10898   S (mp);
10899   W (ret);
10900   return ret;
10901 }
10902
10903 static int
10904 api_classify_set_interface_ip_table (vat_main_t * vam)
10905 {
10906   unformat_input_t *i = vam->input;
10907   vl_api_classify_set_interface_ip_table_t *mp;
10908   u32 sw_if_index;
10909   int sw_if_index_set;
10910   u32 table_index = ~0;
10911   u8 is_ipv6 = 0;
10912   int ret;
10913
10914   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10915     {
10916       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10917         sw_if_index_set = 1;
10918       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10919         sw_if_index_set = 1;
10920       else if (unformat (i, "table %d", &table_index))
10921         ;
10922       else
10923         {
10924           clib_warning ("parse error '%U'", format_unformat_error, i);
10925           return -99;
10926         }
10927     }
10928
10929   if (sw_if_index_set == 0)
10930     {
10931       errmsg ("missing interface name or sw_if_index");
10932       return -99;
10933     }
10934
10935
10936   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10937
10938   mp->sw_if_index = ntohl (sw_if_index);
10939   mp->table_index = ntohl (table_index);
10940   mp->is_ipv6 = is_ipv6;
10941
10942   S (mp);
10943   W (ret);
10944   return ret;
10945 }
10946
10947 static int
10948 api_classify_set_interface_l2_tables (vat_main_t * vam)
10949 {
10950   unformat_input_t *i = vam->input;
10951   vl_api_classify_set_interface_l2_tables_t *mp;
10952   u32 sw_if_index;
10953   int sw_if_index_set;
10954   u32 ip4_table_index = ~0;
10955   u32 ip6_table_index = ~0;
10956   u32 other_table_index = ~0;
10957   u32 is_input = 1;
10958   int ret;
10959
10960   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10961     {
10962       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10963         sw_if_index_set = 1;
10964       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10965         sw_if_index_set = 1;
10966       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10967         ;
10968       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10969         ;
10970       else if (unformat (i, "other-table %d", &other_table_index))
10971         ;
10972       else if (unformat (i, "is-input %d", &is_input))
10973         ;
10974       else
10975         {
10976           clib_warning ("parse error '%U'", format_unformat_error, i);
10977           return -99;
10978         }
10979     }
10980
10981   if (sw_if_index_set == 0)
10982     {
10983       errmsg ("missing interface name or sw_if_index");
10984       return -99;
10985     }
10986
10987
10988   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10989
10990   mp->sw_if_index = ntohl (sw_if_index);
10991   mp->ip4_table_index = ntohl (ip4_table_index);
10992   mp->ip6_table_index = ntohl (ip6_table_index);
10993   mp->other_table_index = ntohl (other_table_index);
10994   mp->is_input = (u8) is_input;
10995
10996   S (mp);
10997   W (ret);
10998   return ret;
10999 }
11000
11001 static int
11002 api_set_ipfix_exporter (vat_main_t * vam)
11003 {
11004   unformat_input_t *i = vam->input;
11005   vl_api_set_ipfix_exporter_t *mp;
11006   ip4_address_t collector_address;
11007   u8 collector_address_set = 0;
11008   u32 collector_port = ~0;
11009   ip4_address_t src_address;
11010   u8 src_address_set = 0;
11011   u32 vrf_id = ~0;
11012   u32 path_mtu = ~0;
11013   u32 template_interval = ~0;
11014   u8 udp_checksum = 0;
11015   int ret;
11016
11017   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11018     {
11019       if (unformat (i, "collector_address %U", unformat_ip4_address,
11020                     &collector_address))
11021         collector_address_set = 1;
11022       else if (unformat (i, "collector_port %d", &collector_port))
11023         ;
11024       else if (unformat (i, "src_address %U", unformat_ip4_address,
11025                          &src_address))
11026         src_address_set = 1;
11027       else if (unformat (i, "vrf_id %d", &vrf_id))
11028         ;
11029       else if (unformat (i, "path_mtu %d", &path_mtu))
11030         ;
11031       else if (unformat (i, "template_interval %d", &template_interval))
11032         ;
11033       else if (unformat (i, "udp_checksum"))
11034         udp_checksum = 1;
11035       else
11036         break;
11037     }
11038
11039   if (collector_address_set == 0)
11040     {
11041       errmsg ("collector_address required");
11042       return -99;
11043     }
11044
11045   if (src_address_set == 0)
11046     {
11047       errmsg ("src_address required");
11048       return -99;
11049     }
11050
11051   M (SET_IPFIX_EXPORTER, mp);
11052
11053   memcpy (mp->collector_address, collector_address.data,
11054           sizeof (collector_address.data));
11055   mp->collector_port = htons ((u16) collector_port);
11056   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11057   mp->vrf_id = htonl (vrf_id);
11058   mp->path_mtu = htonl (path_mtu);
11059   mp->template_interval = htonl (template_interval);
11060   mp->udp_checksum = udp_checksum;
11061
11062   S (mp);
11063   W (ret);
11064   return ret;
11065 }
11066
11067 static int
11068 api_set_ipfix_classify_stream (vat_main_t * vam)
11069 {
11070   unformat_input_t *i = vam->input;
11071   vl_api_set_ipfix_classify_stream_t *mp;
11072   u32 domain_id = 0;
11073   u32 src_port = UDP_DST_PORT_ipfix;
11074   int ret;
11075
11076   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11077     {
11078       if (unformat (i, "domain %d", &domain_id))
11079         ;
11080       else if (unformat (i, "src_port %d", &src_port))
11081         ;
11082       else
11083         {
11084           errmsg ("unknown input `%U'", format_unformat_error, i);
11085           return -99;
11086         }
11087     }
11088
11089   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11090
11091   mp->domain_id = htonl (domain_id);
11092   mp->src_port = htons ((u16) src_port);
11093
11094   S (mp);
11095   W (ret);
11096   return ret;
11097 }
11098
11099 static int
11100 api_ipfix_classify_table_add_del (vat_main_t * vam)
11101 {
11102   unformat_input_t *i = vam->input;
11103   vl_api_ipfix_classify_table_add_del_t *mp;
11104   int is_add = -1;
11105   u32 classify_table_index = ~0;
11106   u8 ip_version = 0;
11107   u8 transport_protocol = 255;
11108   int ret;
11109
11110   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11111     {
11112       if (unformat (i, "add"))
11113         is_add = 1;
11114       else if (unformat (i, "del"))
11115         is_add = 0;
11116       else if (unformat (i, "table %d", &classify_table_index))
11117         ;
11118       else if (unformat (i, "ip4"))
11119         ip_version = 4;
11120       else if (unformat (i, "ip6"))
11121         ip_version = 6;
11122       else if (unformat (i, "tcp"))
11123         transport_protocol = 6;
11124       else if (unformat (i, "udp"))
11125         transport_protocol = 17;
11126       else
11127         {
11128           errmsg ("unknown input `%U'", format_unformat_error, i);
11129           return -99;
11130         }
11131     }
11132
11133   if (is_add == -1)
11134     {
11135       errmsg ("expecting: add|del");
11136       return -99;
11137     }
11138   if (classify_table_index == ~0)
11139     {
11140       errmsg ("classifier table not specified");
11141       return -99;
11142     }
11143   if (ip_version == 0)
11144     {
11145       errmsg ("IP version not specified");
11146       return -99;
11147     }
11148
11149   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11150
11151   mp->is_add = is_add;
11152   mp->table_id = htonl (classify_table_index);
11153   mp->ip_version = ip_version;
11154   mp->transport_protocol = transport_protocol;
11155
11156   S (mp);
11157   W (ret);
11158   return ret;
11159 }
11160
11161 static int
11162 api_get_node_index (vat_main_t * vam)
11163 {
11164   unformat_input_t *i = vam->input;
11165   vl_api_get_node_index_t *mp;
11166   u8 *name = 0;
11167   int ret;
11168
11169   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11170     {
11171       if (unformat (i, "node %s", &name))
11172         ;
11173       else
11174         break;
11175     }
11176   if (name == 0)
11177     {
11178       errmsg ("node name required");
11179       return -99;
11180     }
11181   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11182     {
11183       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11184       return -99;
11185     }
11186
11187   M (GET_NODE_INDEX, mp);
11188   clib_memcpy (mp->node_name, name, vec_len (name));
11189   vec_free (name);
11190
11191   S (mp);
11192   W (ret);
11193   return ret;
11194 }
11195
11196 static int
11197 api_get_next_index (vat_main_t * vam)
11198 {
11199   unformat_input_t *i = vam->input;
11200   vl_api_get_next_index_t *mp;
11201   u8 *node_name = 0, *next_node_name = 0;
11202   int ret;
11203
11204   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11205     {
11206       if (unformat (i, "node-name %s", &node_name))
11207         ;
11208       else if (unformat (i, "next-node-name %s", &next_node_name))
11209         break;
11210     }
11211
11212   if (node_name == 0)
11213     {
11214       errmsg ("node name required");
11215       return -99;
11216     }
11217   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11218     {
11219       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11220       return -99;
11221     }
11222
11223   if (next_node_name == 0)
11224     {
11225       errmsg ("next node name required");
11226       return -99;
11227     }
11228   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11229     {
11230       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11231       return -99;
11232     }
11233
11234   M (GET_NEXT_INDEX, mp);
11235   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11236   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11237   vec_free (node_name);
11238   vec_free (next_node_name);
11239
11240   S (mp);
11241   W (ret);
11242   return ret;
11243 }
11244
11245 static int
11246 api_add_node_next (vat_main_t * vam)
11247 {
11248   unformat_input_t *i = vam->input;
11249   vl_api_add_node_next_t *mp;
11250   u8 *name = 0;
11251   u8 *next = 0;
11252   int ret;
11253
11254   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11255     {
11256       if (unformat (i, "node %s", &name))
11257         ;
11258       else if (unformat (i, "next %s", &next))
11259         ;
11260       else
11261         break;
11262     }
11263   if (name == 0)
11264     {
11265       errmsg ("node name required");
11266       return -99;
11267     }
11268   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11269     {
11270       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11271       return -99;
11272     }
11273   if (next == 0)
11274     {
11275       errmsg ("next node required");
11276       return -99;
11277     }
11278   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11279     {
11280       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11281       return -99;
11282     }
11283
11284   M (ADD_NODE_NEXT, mp);
11285   clib_memcpy (mp->node_name, name, vec_len (name));
11286   clib_memcpy (mp->next_name, next, vec_len (next));
11287   vec_free (name);
11288   vec_free (next);
11289
11290   S (mp);
11291   W (ret);
11292   return ret;
11293 }
11294
11295 static int
11296 api_l2tpv3_create_tunnel (vat_main_t * vam)
11297 {
11298   unformat_input_t *i = vam->input;
11299   ip6_address_t client_address, our_address;
11300   int client_address_set = 0;
11301   int our_address_set = 0;
11302   u32 local_session_id = 0;
11303   u32 remote_session_id = 0;
11304   u64 local_cookie = 0;
11305   u64 remote_cookie = 0;
11306   u8 l2_sublayer_present = 0;
11307   vl_api_l2tpv3_create_tunnel_t *mp;
11308   int ret;
11309
11310   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11311     {
11312       if (unformat (i, "client_address %U", unformat_ip6_address,
11313                     &client_address))
11314         client_address_set = 1;
11315       else if (unformat (i, "our_address %U", unformat_ip6_address,
11316                          &our_address))
11317         our_address_set = 1;
11318       else if (unformat (i, "local_session_id %d", &local_session_id))
11319         ;
11320       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11321         ;
11322       else if (unformat (i, "local_cookie %lld", &local_cookie))
11323         ;
11324       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11325         ;
11326       else if (unformat (i, "l2-sublayer-present"))
11327         l2_sublayer_present = 1;
11328       else
11329         break;
11330     }
11331
11332   if (client_address_set == 0)
11333     {
11334       errmsg ("client_address required");
11335       return -99;
11336     }
11337
11338   if (our_address_set == 0)
11339     {
11340       errmsg ("our_address required");
11341       return -99;
11342     }
11343
11344   M (L2TPV3_CREATE_TUNNEL, mp);
11345
11346   clib_memcpy (mp->client_address, client_address.as_u8,
11347                sizeof (mp->client_address));
11348
11349   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
11350
11351   mp->local_session_id = ntohl (local_session_id);
11352   mp->remote_session_id = ntohl (remote_session_id);
11353   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11354   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11355   mp->l2_sublayer_present = l2_sublayer_present;
11356   mp->is_ipv6 = 1;
11357
11358   S (mp);
11359   W (ret);
11360   return ret;
11361 }
11362
11363 static int
11364 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11365 {
11366   unformat_input_t *i = vam->input;
11367   u32 sw_if_index;
11368   u8 sw_if_index_set = 0;
11369   u64 new_local_cookie = 0;
11370   u64 new_remote_cookie = 0;
11371   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11372   int ret;
11373
11374   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11375     {
11376       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11377         sw_if_index_set = 1;
11378       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11379         sw_if_index_set = 1;
11380       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11381         ;
11382       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11383         ;
11384       else
11385         break;
11386     }
11387
11388   if (sw_if_index_set == 0)
11389     {
11390       errmsg ("missing interface name or sw_if_index");
11391       return -99;
11392     }
11393
11394   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11395
11396   mp->sw_if_index = ntohl (sw_if_index);
11397   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11398   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11399
11400   S (mp);
11401   W (ret);
11402   return ret;
11403 }
11404
11405 static int
11406 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11407 {
11408   unformat_input_t *i = vam->input;
11409   vl_api_l2tpv3_interface_enable_disable_t *mp;
11410   u32 sw_if_index;
11411   u8 sw_if_index_set = 0;
11412   u8 enable_disable = 1;
11413   int ret;
11414
11415   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11416     {
11417       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11418         sw_if_index_set = 1;
11419       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11420         sw_if_index_set = 1;
11421       else if (unformat (i, "enable"))
11422         enable_disable = 1;
11423       else if (unformat (i, "disable"))
11424         enable_disable = 0;
11425       else
11426         break;
11427     }
11428
11429   if (sw_if_index_set == 0)
11430     {
11431       errmsg ("missing interface name or sw_if_index");
11432       return -99;
11433     }
11434
11435   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11436
11437   mp->sw_if_index = ntohl (sw_if_index);
11438   mp->enable_disable = enable_disable;
11439
11440   S (mp);
11441   W (ret);
11442   return ret;
11443 }
11444
11445 static int
11446 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11447 {
11448   unformat_input_t *i = vam->input;
11449   vl_api_l2tpv3_set_lookup_key_t *mp;
11450   u8 key = ~0;
11451   int ret;
11452
11453   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11454     {
11455       if (unformat (i, "lookup_v6_src"))
11456         key = L2T_LOOKUP_SRC_ADDRESS;
11457       else if (unformat (i, "lookup_v6_dst"))
11458         key = L2T_LOOKUP_DST_ADDRESS;
11459       else if (unformat (i, "lookup_session_id"))
11460         key = L2T_LOOKUP_SESSION_ID;
11461       else
11462         break;
11463     }
11464
11465   if (key == (u8) ~ 0)
11466     {
11467       errmsg ("l2tp session lookup key unset");
11468       return -99;
11469     }
11470
11471   M (L2TPV3_SET_LOOKUP_KEY, mp);
11472
11473   mp->key = key;
11474
11475   S (mp);
11476   W (ret);
11477   return ret;
11478 }
11479
11480 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11481   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11482 {
11483   vat_main_t *vam = &vat_main;
11484
11485   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11486          format_ip6_address, mp->our_address,
11487          format_ip6_address, mp->client_address,
11488          clib_net_to_host_u32 (mp->sw_if_index));
11489
11490   print (vam->ofp,
11491          "   local cookies %016llx %016llx remote cookie %016llx",
11492          clib_net_to_host_u64 (mp->local_cookie[0]),
11493          clib_net_to_host_u64 (mp->local_cookie[1]),
11494          clib_net_to_host_u64 (mp->remote_cookie));
11495
11496   print (vam->ofp, "   local session-id %d remote session-id %d",
11497          clib_net_to_host_u32 (mp->local_session_id),
11498          clib_net_to_host_u32 (mp->remote_session_id));
11499
11500   print (vam->ofp, "   l2 specific sublayer %s\n",
11501          mp->l2_sublayer_present ? "preset" : "absent");
11502
11503 }
11504
11505 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11506   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11507 {
11508   vat_main_t *vam = &vat_main;
11509   vat_json_node_t *node = NULL;
11510   struct in6_addr addr;
11511
11512   if (VAT_JSON_ARRAY != vam->json_tree.type)
11513     {
11514       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11515       vat_json_init_array (&vam->json_tree);
11516     }
11517   node = vat_json_array_add (&vam->json_tree);
11518
11519   vat_json_init_object (node);
11520
11521   clib_memcpy (&addr, mp->our_address, sizeof (addr));
11522   vat_json_object_add_ip6 (node, "our_address", addr);
11523   clib_memcpy (&addr, mp->client_address, sizeof (addr));
11524   vat_json_object_add_ip6 (node, "client_address", addr);
11525
11526   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11527   vat_json_init_array (lc);
11528   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11529   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11530   vat_json_object_add_uint (node, "remote_cookie",
11531                             clib_net_to_host_u64 (mp->remote_cookie));
11532
11533   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11534   vat_json_object_add_uint (node, "local_session_id",
11535                             clib_net_to_host_u32 (mp->local_session_id));
11536   vat_json_object_add_uint (node, "remote_session_id",
11537                             clib_net_to_host_u32 (mp->remote_session_id));
11538   vat_json_object_add_string_copy (node, "l2_sublayer",
11539                                    mp->l2_sublayer_present ? (u8 *) "present"
11540                                    : (u8 *) "absent");
11541 }
11542
11543 static int
11544 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11545 {
11546   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11547   vl_api_control_ping_t *mp_ping;
11548   int ret;
11549
11550   /* Get list of l2tpv3-tunnel interfaces */
11551   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11552   S (mp);
11553
11554   /* Use a control ping for synchronization */
11555   M (CONTROL_PING, mp_ping);
11556   S (mp_ping);
11557
11558   W (ret);
11559   return ret;
11560 }
11561
11562
11563 static void vl_api_sw_interface_tap_details_t_handler
11564   (vl_api_sw_interface_tap_details_t * mp)
11565 {
11566   vat_main_t *vam = &vat_main;
11567
11568   print (vam->ofp, "%-16s %d",
11569          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
11570 }
11571
11572 static void vl_api_sw_interface_tap_details_t_handler_json
11573   (vl_api_sw_interface_tap_details_t * mp)
11574 {
11575   vat_main_t *vam = &vat_main;
11576   vat_json_node_t *node = NULL;
11577
11578   if (VAT_JSON_ARRAY != vam->json_tree.type)
11579     {
11580       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11581       vat_json_init_array (&vam->json_tree);
11582     }
11583   node = vat_json_array_add (&vam->json_tree);
11584
11585   vat_json_init_object (node);
11586   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11587   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11588 }
11589
11590 static int
11591 api_sw_interface_tap_dump (vat_main_t * vam)
11592 {
11593   vl_api_sw_interface_tap_dump_t *mp;
11594   vl_api_control_ping_t *mp_ping;
11595   int ret;
11596
11597   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
11598   /* Get list of tap interfaces */
11599   M (SW_INTERFACE_TAP_DUMP, mp);
11600   S (mp);
11601
11602   /* Use a control ping for synchronization */
11603   M (CONTROL_PING, mp_ping);
11604   S (mp_ping);
11605
11606   W (ret);
11607   return ret;
11608 }
11609
11610 static uword unformat_vxlan_decap_next
11611   (unformat_input_t * input, va_list * args)
11612 {
11613   u32 *result = va_arg (*args, u32 *);
11614   u32 tmp;
11615
11616   if (unformat (input, "l2"))
11617     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11618   else if (unformat (input, "%d", &tmp))
11619     *result = tmp;
11620   else
11621     return 0;
11622   return 1;
11623 }
11624
11625 static int
11626 api_vxlan_add_del_tunnel (vat_main_t * vam)
11627 {
11628   unformat_input_t *line_input = vam->input;
11629   vl_api_vxlan_add_del_tunnel_t *mp;
11630   ip46_address_t src, dst;
11631   u8 is_add = 1;
11632   u8 ipv4_set = 0, ipv6_set = 0;
11633   u8 src_set = 0;
11634   u8 dst_set = 0;
11635   u8 grp_set = 0;
11636   u32 mcast_sw_if_index = ~0;
11637   u32 encap_vrf_id = 0;
11638   u32 decap_next_index = ~0;
11639   u32 vni = 0;
11640   int ret;
11641
11642   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11643   memset (&src, 0, sizeof src);
11644   memset (&dst, 0, sizeof dst);
11645
11646   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11647     {
11648       if (unformat (line_input, "del"))
11649         is_add = 0;
11650       else
11651         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11652         {
11653           ipv4_set = 1;
11654           src_set = 1;
11655         }
11656       else
11657         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11658         {
11659           ipv4_set = 1;
11660           dst_set = 1;
11661         }
11662       else
11663         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11664         {
11665           ipv6_set = 1;
11666           src_set = 1;
11667         }
11668       else
11669         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11670         {
11671           ipv6_set = 1;
11672           dst_set = 1;
11673         }
11674       else if (unformat (line_input, "group %U %U",
11675                          unformat_ip4_address, &dst.ip4,
11676                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11677         {
11678           grp_set = dst_set = 1;
11679           ipv4_set = 1;
11680         }
11681       else if (unformat (line_input, "group %U",
11682                          unformat_ip4_address, &dst.ip4))
11683         {
11684           grp_set = dst_set = 1;
11685           ipv4_set = 1;
11686         }
11687       else if (unformat (line_input, "group %U %U",
11688                          unformat_ip6_address, &dst.ip6,
11689                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11690         {
11691           grp_set = dst_set = 1;
11692           ipv6_set = 1;
11693         }
11694       else if (unformat (line_input, "group %U",
11695                          unformat_ip6_address, &dst.ip6))
11696         {
11697           grp_set = dst_set = 1;
11698           ipv6_set = 1;
11699         }
11700       else
11701         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11702         ;
11703       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11704         ;
11705       else if (unformat (line_input, "decap-next %U",
11706                          unformat_vxlan_decap_next, &decap_next_index))
11707         ;
11708       else if (unformat (line_input, "vni %d", &vni))
11709         ;
11710       else
11711         {
11712           errmsg ("parse error '%U'", format_unformat_error, line_input);
11713           return -99;
11714         }
11715     }
11716
11717   if (src_set == 0)
11718     {
11719       errmsg ("tunnel src address not specified");
11720       return -99;
11721     }
11722   if (dst_set == 0)
11723     {
11724       errmsg ("tunnel dst address not specified");
11725       return -99;
11726     }
11727
11728   if (grp_set && !ip46_address_is_multicast (&dst))
11729     {
11730       errmsg ("tunnel group address not multicast");
11731       return -99;
11732     }
11733   if (grp_set && mcast_sw_if_index == ~0)
11734     {
11735       errmsg ("tunnel nonexistent multicast device");
11736       return -99;
11737     }
11738   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11739     {
11740       errmsg ("tunnel dst address must be unicast");
11741       return -99;
11742     }
11743
11744
11745   if (ipv4_set && ipv6_set)
11746     {
11747       errmsg ("both IPv4 and IPv6 addresses specified");
11748       return -99;
11749     }
11750
11751   if ((vni == 0) || (vni >> 24))
11752     {
11753       errmsg ("vni not specified or out of range");
11754       return -99;
11755     }
11756
11757   M (VXLAN_ADD_DEL_TUNNEL, mp);
11758
11759   if (ipv6_set)
11760     {
11761       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
11762       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
11763     }
11764   else
11765     {
11766       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
11767       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
11768     }
11769   mp->encap_vrf_id = ntohl (encap_vrf_id);
11770   mp->decap_next_index = ntohl (decap_next_index);
11771   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11772   mp->vni = ntohl (vni);
11773   mp->is_add = is_add;
11774   mp->is_ipv6 = ipv6_set;
11775
11776   S (mp);
11777   W (ret);
11778   return ret;
11779 }
11780
11781 static void vl_api_vxlan_tunnel_details_t_handler
11782   (vl_api_vxlan_tunnel_details_t * mp)
11783 {
11784   vat_main_t *vam = &vat_main;
11785   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
11786   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
11787
11788   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
11789          ntohl (mp->sw_if_index),
11790          format_ip46_address, &src, IP46_TYPE_ANY,
11791          format_ip46_address, &dst, IP46_TYPE_ANY,
11792          ntohl (mp->encap_vrf_id),
11793          ntohl (mp->decap_next_index), ntohl (mp->vni),
11794          ntohl (mp->mcast_sw_if_index));
11795 }
11796
11797 static void vl_api_vxlan_tunnel_details_t_handler_json
11798   (vl_api_vxlan_tunnel_details_t * mp)
11799 {
11800   vat_main_t *vam = &vat_main;
11801   vat_json_node_t *node = NULL;
11802
11803   if (VAT_JSON_ARRAY != vam->json_tree.type)
11804     {
11805       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11806       vat_json_init_array (&vam->json_tree);
11807     }
11808   node = vat_json_array_add (&vam->json_tree);
11809
11810   vat_json_init_object (node);
11811   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11812   if (mp->is_ipv6)
11813     {
11814       struct in6_addr ip6;
11815
11816       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
11817       vat_json_object_add_ip6 (node, "src_address", ip6);
11818       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
11819       vat_json_object_add_ip6 (node, "dst_address", ip6);
11820     }
11821   else
11822     {
11823       struct in_addr ip4;
11824
11825       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
11826       vat_json_object_add_ip4 (node, "src_address", ip4);
11827       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
11828       vat_json_object_add_ip4 (node, "dst_address", ip4);
11829     }
11830   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11831   vat_json_object_add_uint (node, "decap_next_index",
11832                             ntohl (mp->decap_next_index));
11833   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11834   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11835   vat_json_object_add_uint (node, "mcast_sw_if_index",
11836                             ntohl (mp->mcast_sw_if_index));
11837 }
11838
11839 static int
11840 api_vxlan_tunnel_dump (vat_main_t * vam)
11841 {
11842   unformat_input_t *i = vam->input;
11843   vl_api_vxlan_tunnel_dump_t *mp;
11844   vl_api_control_ping_t *mp_ping;
11845   u32 sw_if_index;
11846   u8 sw_if_index_set = 0;
11847   int ret;
11848
11849   /* Parse args required to build the message */
11850   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11851     {
11852       if (unformat (i, "sw_if_index %d", &sw_if_index))
11853         sw_if_index_set = 1;
11854       else
11855         break;
11856     }
11857
11858   if (sw_if_index_set == 0)
11859     {
11860       sw_if_index = ~0;
11861     }
11862
11863   if (!vam->json_output)
11864     {
11865       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
11866              "sw_if_index", "src_address", "dst_address",
11867              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11868     }
11869
11870   /* Get list of vxlan-tunnel interfaces */
11871   M (VXLAN_TUNNEL_DUMP, mp);
11872
11873   mp->sw_if_index = htonl (sw_if_index);
11874
11875   S (mp);
11876
11877   /* Use a control ping for synchronization */
11878   M (CONTROL_PING, mp_ping);
11879   S (mp_ping);
11880
11881   W (ret);
11882   return ret;
11883 }
11884
11885 static int
11886 api_gre_add_del_tunnel (vat_main_t * vam)
11887 {
11888   unformat_input_t *line_input = vam->input;
11889   vl_api_gre_add_del_tunnel_t *mp;
11890   ip4_address_t src4, dst4;
11891   ip6_address_t src6, dst6;
11892   u8 is_add = 1;
11893   u8 ipv4_set = 0;
11894   u8 ipv6_set = 0;
11895   u8 teb = 0;
11896   u8 src_set = 0;
11897   u8 dst_set = 0;
11898   u32 outer_fib_id = 0;
11899   int ret;
11900
11901   memset (&src4, 0, sizeof src4);
11902   memset (&dst4, 0, sizeof dst4);
11903   memset (&src6, 0, sizeof src6);
11904   memset (&dst6, 0, sizeof dst6);
11905
11906   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11907     {
11908       if (unformat (line_input, "del"))
11909         is_add = 0;
11910       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
11911         {
11912           src_set = 1;
11913           ipv4_set = 1;
11914         }
11915       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
11916         {
11917           dst_set = 1;
11918           ipv4_set = 1;
11919         }
11920       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
11921         {
11922           src_set = 1;
11923           ipv6_set = 1;
11924         }
11925       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
11926         {
11927           dst_set = 1;
11928           ipv6_set = 1;
11929         }
11930       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
11931         ;
11932       else if (unformat (line_input, "teb"))
11933         teb = 1;
11934       else
11935         {
11936           errmsg ("parse error '%U'", format_unformat_error, line_input);
11937           return -99;
11938         }
11939     }
11940
11941   if (src_set == 0)
11942     {
11943       errmsg ("tunnel src address not specified");
11944       return -99;
11945     }
11946   if (dst_set == 0)
11947     {
11948       errmsg ("tunnel dst address not specified");
11949       return -99;
11950     }
11951   if (ipv4_set && ipv6_set)
11952     {
11953       errmsg ("both IPv4 and IPv6 addresses specified");
11954       return -99;
11955     }
11956
11957
11958   M (GRE_ADD_DEL_TUNNEL, mp);
11959
11960   if (ipv4_set)
11961     {
11962       clib_memcpy (&mp->src_address, &src4, 4);
11963       clib_memcpy (&mp->dst_address, &dst4, 4);
11964     }
11965   else
11966     {
11967       clib_memcpy (&mp->src_address, &src6, 16);
11968       clib_memcpy (&mp->dst_address, &dst6, 16);
11969     }
11970   mp->outer_fib_id = ntohl (outer_fib_id);
11971   mp->is_add = is_add;
11972   mp->teb = teb;
11973   mp->is_ipv6 = ipv6_set;
11974
11975   S (mp);
11976   W (ret);
11977   return ret;
11978 }
11979
11980 static void vl_api_gre_tunnel_details_t_handler
11981   (vl_api_gre_tunnel_details_t * mp)
11982 {
11983   vat_main_t *vam = &vat_main;
11984   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
11985   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
11986
11987   print (vam->ofp, "%11d%24U%24U%6d%14d",
11988          ntohl (mp->sw_if_index),
11989          format_ip46_address, &src, IP46_TYPE_ANY,
11990          format_ip46_address, &dst, IP46_TYPE_ANY,
11991          mp->teb, ntohl (mp->outer_fib_id));
11992 }
11993
11994 static void vl_api_gre_tunnel_details_t_handler_json
11995   (vl_api_gre_tunnel_details_t * mp)
11996 {
11997   vat_main_t *vam = &vat_main;
11998   vat_json_node_t *node = NULL;
11999   struct in_addr ip4;
12000   struct in6_addr ip6;
12001
12002   if (VAT_JSON_ARRAY != vam->json_tree.type)
12003     {
12004       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12005       vat_json_init_array (&vam->json_tree);
12006     }
12007   node = vat_json_array_add (&vam->json_tree);
12008
12009   vat_json_init_object (node);
12010   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12011   if (!mp->is_ipv6)
12012     {
12013       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
12014       vat_json_object_add_ip4 (node, "src_address", ip4);
12015       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
12016       vat_json_object_add_ip4 (node, "dst_address", ip4);
12017     }
12018   else
12019     {
12020       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
12021       vat_json_object_add_ip6 (node, "src_address", ip6);
12022       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
12023       vat_json_object_add_ip6 (node, "dst_address", ip6);
12024     }
12025   vat_json_object_add_uint (node, "teb", mp->teb);
12026   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
12027   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
12028 }
12029
12030 static int
12031 api_gre_tunnel_dump (vat_main_t * vam)
12032 {
12033   unformat_input_t *i = vam->input;
12034   vl_api_gre_tunnel_dump_t *mp;
12035   vl_api_control_ping_t *mp_ping;
12036   u32 sw_if_index;
12037   u8 sw_if_index_set = 0;
12038   int ret;
12039
12040   /* Parse args required to build the message */
12041   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12042     {
12043       if (unformat (i, "sw_if_index %d", &sw_if_index))
12044         sw_if_index_set = 1;
12045       else
12046         break;
12047     }
12048
12049   if (sw_if_index_set == 0)
12050     {
12051       sw_if_index = ~0;
12052     }
12053
12054   if (!vam->json_output)
12055     {
12056       print (vam->ofp, "%11s%24s%24s%6s%14s",
12057              "sw_if_index", "src_address", "dst_address", "teb",
12058              "outer_fib_id");
12059     }
12060
12061   /* Get list of gre-tunnel interfaces */
12062   M (GRE_TUNNEL_DUMP, mp);
12063
12064   mp->sw_if_index = htonl (sw_if_index);
12065
12066   S (mp);
12067
12068   /* Use a control ping for synchronization */
12069   M (CONTROL_PING, mp_ping);
12070   S (mp_ping);
12071
12072   W (ret);
12073   return ret;
12074 }
12075
12076 static int
12077 api_l2_fib_clear_table (vat_main_t * vam)
12078 {
12079 //  unformat_input_t * i = vam->input;
12080   vl_api_l2_fib_clear_table_t *mp;
12081   int ret;
12082
12083   M (L2_FIB_CLEAR_TABLE, mp);
12084
12085   S (mp);
12086   W (ret);
12087   return ret;
12088 }
12089
12090 static int
12091 api_l2_interface_efp_filter (vat_main_t * vam)
12092 {
12093   unformat_input_t *i = vam->input;
12094   vl_api_l2_interface_efp_filter_t *mp;
12095   u32 sw_if_index;
12096   u8 enable = 1;
12097   u8 sw_if_index_set = 0;
12098   int ret;
12099
12100   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12101     {
12102       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12103         sw_if_index_set = 1;
12104       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12105         sw_if_index_set = 1;
12106       else if (unformat (i, "enable"))
12107         enable = 1;
12108       else if (unformat (i, "disable"))
12109         enable = 0;
12110       else
12111         {
12112           clib_warning ("parse error '%U'", format_unformat_error, i);
12113           return -99;
12114         }
12115     }
12116
12117   if (sw_if_index_set == 0)
12118     {
12119       errmsg ("missing sw_if_index");
12120       return -99;
12121     }
12122
12123   M (L2_INTERFACE_EFP_FILTER, mp);
12124
12125   mp->sw_if_index = ntohl (sw_if_index);
12126   mp->enable_disable = enable;
12127
12128   S (mp);
12129   W (ret);
12130   return ret;
12131 }
12132
12133 #define foreach_vtr_op                          \
12134 _("disable",  L2_VTR_DISABLED)                  \
12135 _("push-1",  L2_VTR_PUSH_1)                     \
12136 _("push-2",  L2_VTR_PUSH_2)                     \
12137 _("pop-1",  L2_VTR_POP_1)                       \
12138 _("pop-2",  L2_VTR_POP_2)                       \
12139 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12140 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12141 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12142 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12143
12144 static int
12145 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12146 {
12147   unformat_input_t *i = vam->input;
12148   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12149   u32 sw_if_index;
12150   u8 sw_if_index_set = 0;
12151   u8 vtr_op_set = 0;
12152   u32 vtr_op = 0;
12153   u32 push_dot1q = 1;
12154   u32 tag1 = ~0;
12155   u32 tag2 = ~0;
12156   int ret;
12157
12158   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12159     {
12160       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12161         sw_if_index_set = 1;
12162       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12163         sw_if_index_set = 1;
12164       else if (unformat (i, "vtr_op %d", &vtr_op))
12165         vtr_op_set = 1;
12166 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12167       foreach_vtr_op
12168 #undef _
12169         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12170         ;
12171       else if (unformat (i, "tag1 %d", &tag1))
12172         ;
12173       else if (unformat (i, "tag2 %d", &tag2))
12174         ;
12175       else
12176         {
12177           clib_warning ("parse error '%U'", format_unformat_error, i);
12178           return -99;
12179         }
12180     }
12181
12182   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12183     {
12184       errmsg ("missing vtr operation or sw_if_index");
12185       return -99;
12186     }
12187
12188   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12189   mp->sw_if_index = ntohl (sw_if_index);
12190   mp->vtr_op = ntohl (vtr_op);
12191   mp->push_dot1q = ntohl (push_dot1q);
12192   mp->tag1 = ntohl (tag1);
12193   mp->tag2 = ntohl (tag2);
12194
12195   S (mp);
12196   W (ret);
12197   return ret;
12198 }
12199
12200 static int
12201 api_create_vhost_user_if (vat_main_t * vam)
12202 {
12203   unformat_input_t *i = vam->input;
12204   vl_api_create_vhost_user_if_t *mp;
12205   u8 *file_name;
12206   u8 is_server = 0;
12207   u8 file_name_set = 0;
12208   u32 custom_dev_instance = ~0;
12209   u8 hwaddr[6];
12210   u8 use_custom_mac = 0;
12211   u8 *tag = 0;
12212   int ret;
12213
12214   /* Shut up coverity */
12215   memset (hwaddr, 0, sizeof (hwaddr));
12216
12217   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12218     {
12219       if (unformat (i, "socket %s", &file_name))
12220         {
12221           file_name_set = 1;
12222         }
12223       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12224         ;
12225       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12226         use_custom_mac = 1;
12227       else if (unformat (i, "server"))
12228         is_server = 1;
12229       else if (unformat (i, "tag %s", &tag))
12230         ;
12231       else
12232         break;
12233     }
12234
12235   if (file_name_set == 0)
12236     {
12237       errmsg ("missing socket file name");
12238       return -99;
12239     }
12240
12241   if (vec_len (file_name) > 255)
12242     {
12243       errmsg ("socket file name too long");
12244       return -99;
12245     }
12246   vec_add1 (file_name, 0);
12247
12248   M (CREATE_VHOST_USER_IF, mp);
12249
12250   mp->is_server = is_server;
12251   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12252   vec_free (file_name);
12253   if (custom_dev_instance != ~0)
12254     {
12255       mp->renumber = 1;
12256       mp->custom_dev_instance = ntohl (custom_dev_instance);
12257     }
12258   mp->use_custom_mac = use_custom_mac;
12259   clib_memcpy (mp->mac_address, hwaddr, 6);
12260   if (tag)
12261     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12262   vec_free (tag);
12263
12264   S (mp);
12265   W (ret);
12266   return ret;
12267 }
12268
12269 static int
12270 api_modify_vhost_user_if (vat_main_t * vam)
12271 {
12272   unformat_input_t *i = vam->input;
12273   vl_api_modify_vhost_user_if_t *mp;
12274   u8 *file_name;
12275   u8 is_server = 0;
12276   u8 file_name_set = 0;
12277   u32 custom_dev_instance = ~0;
12278   u8 sw_if_index_set = 0;
12279   u32 sw_if_index = (u32) ~ 0;
12280   int ret;
12281
12282   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12283     {
12284       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12285         sw_if_index_set = 1;
12286       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12287         sw_if_index_set = 1;
12288       else if (unformat (i, "socket %s", &file_name))
12289         {
12290           file_name_set = 1;
12291         }
12292       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12293         ;
12294       else if (unformat (i, "server"))
12295         is_server = 1;
12296       else
12297         break;
12298     }
12299
12300   if (sw_if_index_set == 0)
12301     {
12302       errmsg ("missing sw_if_index or interface name");
12303       return -99;
12304     }
12305
12306   if (file_name_set == 0)
12307     {
12308       errmsg ("missing socket file name");
12309       return -99;
12310     }
12311
12312   if (vec_len (file_name) > 255)
12313     {
12314       errmsg ("socket file name too long");
12315       return -99;
12316     }
12317   vec_add1 (file_name, 0);
12318
12319   M (MODIFY_VHOST_USER_IF, mp);
12320
12321   mp->sw_if_index = ntohl (sw_if_index);
12322   mp->is_server = is_server;
12323   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12324   vec_free (file_name);
12325   if (custom_dev_instance != ~0)
12326     {
12327       mp->renumber = 1;
12328       mp->custom_dev_instance = ntohl (custom_dev_instance);
12329     }
12330
12331   S (mp);
12332   W (ret);
12333   return ret;
12334 }
12335
12336 static int
12337 api_delete_vhost_user_if (vat_main_t * vam)
12338 {
12339   unformat_input_t *i = vam->input;
12340   vl_api_delete_vhost_user_if_t *mp;
12341   u32 sw_if_index = ~0;
12342   u8 sw_if_index_set = 0;
12343   int ret;
12344
12345   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12346     {
12347       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12348         sw_if_index_set = 1;
12349       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12350         sw_if_index_set = 1;
12351       else
12352         break;
12353     }
12354
12355   if (sw_if_index_set == 0)
12356     {
12357       errmsg ("missing sw_if_index or interface name");
12358       return -99;
12359     }
12360
12361
12362   M (DELETE_VHOST_USER_IF, mp);
12363
12364   mp->sw_if_index = ntohl (sw_if_index);
12365
12366   S (mp);
12367   W (ret);
12368   return ret;
12369 }
12370
12371 static void vl_api_sw_interface_vhost_user_details_t_handler
12372   (vl_api_sw_interface_vhost_user_details_t * mp)
12373 {
12374   vat_main_t *vam = &vat_main;
12375
12376   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12377          (char *) mp->interface_name,
12378          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12379          clib_net_to_host_u64 (mp->features), mp->is_server,
12380          ntohl (mp->num_regions), (char *) mp->sock_filename);
12381   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12382 }
12383
12384 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12385   (vl_api_sw_interface_vhost_user_details_t * mp)
12386 {
12387   vat_main_t *vam = &vat_main;
12388   vat_json_node_t *node = NULL;
12389
12390   if (VAT_JSON_ARRAY != vam->json_tree.type)
12391     {
12392       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12393       vat_json_init_array (&vam->json_tree);
12394     }
12395   node = vat_json_array_add (&vam->json_tree);
12396
12397   vat_json_init_object (node);
12398   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12399   vat_json_object_add_string_copy (node, "interface_name",
12400                                    mp->interface_name);
12401   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12402                             ntohl (mp->virtio_net_hdr_sz));
12403   vat_json_object_add_uint (node, "features",
12404                             clib_net_to_host_u64 (mp->features));
12405   vat_json_object_add_uint (node, "is_server", mp->is_server);
12406   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12407   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12408   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12409 }
12410
12411 static int
12412 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12413 {
12414   vl_api_sw_interface_vhost_user_dump_t *mp;
12415   vl_api_control_ping_t *mp_ping;
12416   int ret;
12417   print (vam->ofp,
12418          "Interface name            idx hdr_sz features server regions filename");
12419
12420   /* Get list of vhost-user interfaces */
12421   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12422   S (mp);
12423
12424   /* Use a control ping for synchronization */
12425   M (CONTROL_PING, mp_ping);
12426   S (mp_ping);
12427
12428   W (ret);
12429   return ret;
12430 }
12431
12432 static int
12433 api_show_version (vat_main_t * vam)
12434 {
12435   vl_api_show_version_t *mp;
12436   int ret;
12437
12438   M (SHOW_VERSION, mp);
12439
12440   S (mp);
12441   W (ret);
12442   return ret;
12443 }
12444
12445
12446 static int
12447 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12448 {
12449   unformat_input_t *line_input = vam->input;
12450   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12451   ip4_address_t local4, remote4;
12452   ip6_address_t local6, remote6;
12453   u8 is_add = 1;
12454   u8 ipv4_set = 0, ipv6_set = 0;
12455   u8 local_set = 0;
12456   u8 remote_set = 0;
12457   u8 grp_set = 0;
12458   u32 mcast_sw_if_index = ~0;
12459   u32 encap_vrf_id = 0;
12460   u32 decap_vrf_id = 0;
12461   u8 protocol = ~0;
12462   u32 vni;
12463   u8 vni_set = 0;
12464   int ret;
12465
12466   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12467   memset (&local4, 0, sizeof local4);
12468   memset (&remote4, 0, sizeof remote4);
12469   memset (&local6, 0, sizeof local6);
12470   memset (&remote6, 0, sizeof remote6);
12471
12472   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12473     {
12474       if (unformat (line_input, "del"))
12475         is_add = 0;
12476       else if (unformat (line_input, "local %U",
12477                          unformat_ip4_address, &local4))
12478         {
12479           local_set = 1;
12480           ipv4_set = 1;
12481         }
12482       else if (unformat (line_input, "remote %U",
12483                          unformat_ip4_address, &remote4))
12484         {
12485           remote_set = 1;
12486           ipv4_set = 1;
12487         }
12488       else if (unformat (line_input, "local %U",
12489                          unformat_ip6_address, &local6))
12490         {
12491           local_set = 1;
12492           ipv6_set = 1;
12493         }
12494       else if (unformat (line_input, "remote %U",
12495                          unformat_ip6_address, &remote6))
12496         {
12497           remote_set = 1;
12498           ipv6_set = 1;
12499         }
12500       else if (unformat (line_input, "group %U %U",
12501                          unformat_ip4_address, &remote4,
12502                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12503         {
12504           grp_set = remote_set = 1;
12505           ipv4_set = 1;
12506         }
12507       else if (unformat (line_input, "group %U",
12508                          unformat_ip4_address, &remote4))
12509         {
12510           grp_set = remote_set = 1;
12511           ipv4_set = 1;
12512         }
12513       else if (unformat (line_input, "group %U %U",
12514                          unformat_ip6_address, &remote6,
12515                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12516         {
12517           grp_set = remote_set = 1;
12518           ipv6_set = 1;
12519         }
12520       else if (unformat (line_input, "group %U",
12521                          unformat_ip6_address, &remote6))
12522         {
12523           grp_set = remote_set = 1;
12524           ipv6_set = 1;
12525         }
12526       else
12527         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12528         ;
12529       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12530         ;
12531       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
12532         ;
12533       else if (unformat (line_input, "vni %d", &vni))
12534         vni_set = 1;
12535       else if (unformat (line_input, "next-ip4"))
12536         protocol = 1;
12537       else if (unformat (line_input, "next-ip6"))
12538         protocol = 2;
12539       else if (unformat (line_input, "next-ethernet"))
12540         protocol = 3;
12541       else if (unformat (line_input, "next-nsh"))
12542         protocol = 4;
12543       else
12544         {
12545           errmsg ("parse error '%U'", format_unformat_error, line_input);
12546           return -99;
12547         }
12548     }
12549
12550   if (local_set == 0)
12551     {
12552       errmsg ("tunnel local address not specified");
12553       return -99;
12554     }
12555   if (remote_set == 0)
12556     {
12557       errmsg ("tunnel remote address not specified");
12558       return -99;
12559     }
12560   if (grp_set && mcast_sw_if_index == ~0)
12561     {
12562       errmsg ("tunnel nonexistent multicast device");
12563       return -99;
12564     }
12565   if (ipv4_set && ipv6_set)
12566     {
12567       errmsg ("both IPv4 and IPv6 addresses specified");
12568       return -99;
12569     }
12570
12571   if (vni_set == 0)
12572     {
12573       errmsg ("vni not specified");
12574       return -99;
12575     }
12576
12577   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
12578
12579
12580   if (ipv6_set)
12581     {
12582       clib_memcpy (&mp->local, &local6, sizeof (local6));
12583       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
12584     }
12585   else
12586     {
12587       clib_memcpy (&mp->local, &local4, sizeof (local4));
12588       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
12589     }
12590
12591   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12592   mp->encap_vrf_id = ntohl (encap_vrf_id);
12593   mp->decap_vrf_id = ntohl (decap_vrf_id);
12594   mp->protocol = protocol;
12595   mp->vni = ntohl (vni);
12596   mp->is_add = is_add;
12597   mp->is_ipv6 = ipv6_set;
12598
12599   S (mp);
12600   W (ret);
12601   return ret;
12602 }
12603
12604 static void vl_api_vxlan_gpe_tunnel_details_t_handler
12605   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12606 {
12607   vat_main_t *vam = &vat_main;
12608   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
12609   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
12610
12611   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
12612          ntohl (mp->sw_if_index),
12613          format_ip46_address, &local, IP46_TYPE_ANY,
12614          format_ip46_address, &remote, IP46_TYPE_ANY,
12615          ntohl (mp->vni), mp->protocol,
12616          ntohl (mp->mcast_sw_if_index),
12617          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
12618 }
12619
12620
12621 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
12622   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12623 {
12624   vat_main_t *vam = &vat_main;
12625   vat_json_node_t *node = NULL;
12626   struct in_addr ip4;
12627   struct in6_addr ip6;
12628
12629   if (VAT_JSON_ARRAY != vam->json_tree.type)
12630     {
12631       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12632       vat_json_init_array (&vam->json_tree);
12633     }
12634   node = vat_json_array_add (&vam->json_tree);
12635
12636   vat_json_init_object (node);
12637   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12638   if (mp->is_ipv6)
12639     {
12640       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
12641       vat_json_object_add_ip6 (node, "local", ip6);
12642       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
12643       vat_json_object_add_ip6 (node, "remote", ip6);
12644     }
12645   else
12646     {
12647       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
12648       vat_json_object_add_ip4 (node, "local", ip4);
12649       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
12650       vat_json_object_add_ip4 (node, "remote", ip4);
12651     }
12652   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12653   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
12654   vat_json_object_add_uint (node, "mcast_sw_if_index",
12655                             ntohl (mp->mcast_sw_if_index));
12656   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12657   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
12658   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12659 }
12660
12661 static int
12662 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
12663 {
12664   unformat_input_t *i = vam->input;
12665   vl_api_vxlan_gpe_tunnel_dump_t *mp;
12666   vl_api_control_ping_t *mp_ping;
12667   u32 sw_if_index;
12668   u8 sw_if_index_set = 0;
12669   int ret;
12670
12671   /* Parse args required to build the message */
12672   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12673     {
12674       if (unformat (i, "sw_if_index %d", &sw_if_index))
12675         sw_if_index_set = 1;
12676       else
12677         break;
12678     }
12679
12680   if (sw_if_index_set == 0)
12681     {
12682       sw_if_index = ~0;
12683     }
12684
12685   if (!vam->json_output)
12686     {
12687       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
12688              "sw_if_index", "local", "remote", "vni",
12689              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
12690     }
12691
12692   /* Get list of vxlan-tunnel interfaces */
12693   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12694
12695   mp->sw_if_index = htonl (sw_if_index);
12696
12697   S (mp);
12698
12699   /* Use a control ping for synchronization */
12700   M (CONTROL_PING, mp_ping);
12701   S (mp_ping);
12702
12703   W (ret);
12704   return ret;
12705 }
12706
12707
12708 u8 *
12709 format_l2_fib_mac_address (u8 * s, va_list * args)
12710 {
12711   u8 *a = va_arg (*args, u8 *);
12712
12713   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
12714                  a[2], a[3], a[4], a[5], a[6], a[7]);
12715 }
12716
12717 static void vl_api_l2_fib_table_details_t_handler
12718   (vl_api_l2_fib_table_details_t * mp)
12719 {
12720   vat_main_t *vam = &vat_main;
12721
12722   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
12723          "       %d       %d     %d",
12724          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
12725          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
12726          mp->bvi_mac);
12727 }
12728
12729 static void vl_api_l2_fib_table_details_t_handler_json
12730   (vl_api_l2_fib_table_details_t * mp)
12731 {
12732   vat_main_t *vam = &vat_main;
12733   vat_json_node_t *node = NULL;
12734
12735   if (VAT_JSON_ARRAY != vam->json_tree.type)
12736     {
12737       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12738       vat_json_init_array (&vam->json_tree);
12739     }
12740   node = vat_json_array_add (&vam->json_tree);
12741
12742   vat_json_init_object (node);
12743   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
12744   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
12745   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12746   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
12747   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
12748   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
12749 }
12750
12751 static int
12752 api_l2_fib_table_dump (vat_main_t * vam)
12753 {
12754   unformat_input_t *i = vam->input;
12755   vl_api_l2_fib_table_dump_t *mp;
12756   vl_api_control_ping_t *mp_ping;
12757   u32 bd_id;
12758   u8 bd_id_set = 0;
12759   int ret;
12760
12761   /* Parse args required to build the message */
12762   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12763     {
12764       if (unformat (i, "bd_id %d", &bd_id))
12765         bd_id_set = 1;
12766       else
12767         break;
12768     }
12769
12770   if (bd_id_set == 0)
12771     {
12772       errmsg ("missing bridge domain");
12773       return -99;
12774     }
12775
12776   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
12777
12778   /* Get list of l2 fib entries */
12779   M (L2_FIB_TABLE_DUMP, mp);
12780
12781   mp->bd_id = ntohl (bd_id);
12782   S (mp);
12783
12784   /* Use a control ping for synchronization */
12785   M (CONTROL_PING, mp_ping);
12786   S (mp_ping);
12787
12788   W (ret);
12789   return ret;
12790 }
12791
12792
12793 static int
12794 api_interface_name_renumber (vat_main_t * vam)
12795 {
12796   unformat_input_t *line_input = vam->input;
12797   vl_api_interface_name_renumber_t *mp;
12798   u32 sw_if_index = ~0;
12799   u32 new_show_dev_instance = ~0;
12800   int ret;
12801
12802   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12803     {
12804       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
12805                     &sw_if_index))
12806         ;
12807       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12808         ;
12809       else if (unformat (line_input, "new_show_dev_instance %d",
12810                          &new_show_dev_instance))
12811         ;
12812       else
12813         break;
12814     }
12815
12816   if (sw_if_index == ~0)
12817     {
12818       errmsg ("missing interface name or sw_if_index");
12819       return -99;
12820     }
12821
12822   if (new_show_dev_instance == ~0)
12823     {
12824       errmsg ("missing new_show_dev_instance");
12825       return -99;
12826     }
12827
12828   M (INTERFACE_NAME_RENUMBER, mp);
12829
12830   mp->sw_if_index = ntohl (sw_if_index);
12831   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
12832
12833   S (mp);
12834   W (ret);
12835   return ret;
12836 }
12837
12838 static int
12839 api_want_ip4_arp_events (vat_main_t * vam)
12840 {
12841   unformat_input_t *line_input = vam->input;
12842   vl_api_want_ip4_arp_events_t *mp;
12843   ip4_address_t address;
12844   int address_set = 0;
12845   u32 enable_disable = 1;
12846   int ret;
12847
12848   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12849     {
12850       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
12851         address_set = 1;
12852       else if (unformat (line_input, "del"))
12853         enable_disable = 0;
12854       else
12855         break;
12856     }
12857
12858   if (address_set == 0)
12859     {
12860       errmsg ("missing addresses");
12861       return -99;
12862     }
12863
12864   M (WANT_IP4_ARP_EVENTS, mp);
12865   mp->enable_disable = enable_disable;
12866   mp->pid = htonl (getpid ());
12867   mp->address = address.as_u32;
12868
12869   S (mp);
12870   W (ret);
12871   return ret;
12872 }
12873
12874 static int
12875 api_want_ip6_nd_events (vat_main_t * vam)
12876 {
12877   unformat_input_t *line_input = vam->input;
12878   vl_api_want_ip6_nd_events_t *mp;
12879   ip6_address_t address;
12880   int address_set = 0;
12881   u32 enable_disable = 1;
12882   int ret;
12883
12884   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12885     {
12886       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
12887         address_set = 1;
12888       else if (unformat (line_input, "del"))
12889         enable_disable = 0;
12890       else
12891         break;
12892     }
12893
12894   if (address_set == 0)
12895     {
12896       errmsg ("missing addresses");
12897       return -99;
12898     }
12899
12900   M (WANT_IP6_ND_EVENTS, mp);
12901   mp->enable_disable = enable_disable;
12902   mp->pid = htonl (getpid ());
12903   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
12904
12905   S (mp);
12906   W (ret);
12907   return ret;
12908 }
12909
12910 static int
12911 api_want_l2_macs_events (vat_main_t * vam)
12912 {
12913   unformat_input_t *line_input = vam->input;
12914   vl_api_want_l2_macs_events_t *mp;
12915   u8 enable_disable = 1;
12916   u32 scan_delay = 0;
12917   u32 max_macs_in_event = 0;
12918   u32 learn_limit = 0;
12919   int ret;
12920
12921   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12922     {
12923       if (unformat (line_input, "learn-limit %d", &learn_limit))
12924         ;
12925       else if (unformat (line_input, "scan-delay %d", &scan_delay))
12926         ;
12927       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
12928         ;
12929       else if (unformat (line_input, "disable"))
12930         enable_disable = 0;
12931       else
12932         break;
12933     }
12934
12935   M (WANT_L2_MACS_EVENTS, mp);
12936   mp->enable_disable = enable_disable;
12937   mp->pid = htonl (getpid ());
12938   mp->learn_limit = htonl (learn_limit);
12939   mp->scan_delay = (u8) scan_delay;
12940   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
12941   S (mp);
12942   W (ret);
12943   return ret;
12944 }
12945
12946 static int
12947 api_input_acl_set_interface (vat_main_t * vam)
12948 {
12949   unformat_input_t *i = vam->input;
12950   vl_api_input_acl_set_interface_t *mp;
12951   u32 sw_if_index;
12952   int sw_if_index_set;
12953   u32 ip4_table_index = ~0;
12954   u32 ip6_table_index = ~0;
12955   u32 l2_table_index = ~0;
12956   u8 is_add = 1;
12957   int ret;
12958
12959   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12960     {
12961       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12962         sw_if_index_set = 1;
12963       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12964         sw_if_index_set = 1;
12965       else if (unformat (i, "del"))
12966         is_add = 0;
12967       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12968         ;
12969       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12970         ;
12971       else if (unformat (i, "l2-table %d", &l2_table_index))
12972         ;
12973       else
12974         {
12975           clib_warning ("parse error '%U'", format_unformat_error, i);
12976           return -99;
12977         }
12978     }
12979
12980   if (sw_if_index_set == 0)
12981     {
12982       errmsg ("missing interface name or sw_if_index");
12983       return -99;
12984     }
12985
12986   M (INPUT_ACL_SET_INTERFACE, mp);
12987
12988   mp->sw_if_index = ntohl (sw_if_index);
12989   mp->ip4_table_index = ntohl (ip4_table_index);
12990   mp->ip6_table_index = ntohl (ip6_table_index);
12991   mp->l2_table_index = ntohl (l2_table_index);
12992   mp->is_add = is_add;
12993
12994   S (mp);
12995   W (ret);
12996   return ret;
12997 }
12998
12999 static int
13000 api_ip_address_dump (vat_main_t * vam)
13001 {
13002   unformat_input_t *i = vam->input;
13003   vl_api_ip_address_dump_t *mp;
13004   vl_api_control_ping_t *mp_ping;
13005   u32 sw_if_index = ~0;
13006   u8 sw_if_index_set = 0;
13007   u8 ipv4_set = 0;
13008   u8 ipv6_set = 0;
13009   int ret;
13010
13011   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13012     {
13013       if (unformat (i, "sw_if_index %d", &sw_if_index))
13014         sw_if_index_set = 1;
13015       else
13016         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13017         sw_if_index_set = 1;
13018       else if (unformat (i, "ipv4"))
13019         ipv4_set = 1;
13020       else if (unformat (i, "ipv6"))
13021         ipv6_set = 1;
13022       else
13023         break;
13024     }
13025
13026   if (ipv4_set && ipv6_set)
13027     {
13028       errmsg ("ipv4 and ipv6 flags cannot be both set");
13029       return -99;
13030     }
13031
13032   if ((!ipv4_set) && (!ipv6_set))
13033     {
13034       errmsg ("no ipv4 nor ipv6 flag set");
13035       return -99;
13036     }
13037
13038   if (sw_if_index_set == 0)
13039     {
13040       errmsg ("missing interface name or sw_if_index");
13041       return -99;
13042     }
13043
13044   vam->current_sw_if_index = sw_if_index;
13045   vam->is_ipv6 = ipv6_set;
13046
13047   M (IP_ADDRESS_DUMP, mp);
13048   mp->sw_if_index = ntohl (sw_if_index);
13049   mp->is_ipv6 = ipv6_set;
13050   S (mp);
13051
13052   /* Use a control ping for synchronization */
13053   M (CONTROL_PING, mp_ping);
13054   S (mp_ping);
13055
13056   W (ret);
13057   return ret;
13058 }
13059
13060 static int
13061 api_ip_dump (vat_main_t * vam)
13062 {
13063   vl_api_ip_dump_t *mp;
13064   vl_api_control_ping_t *mp_ping;
13065   unformat_input_t *in = vam->input;
13066   int ipv4_set = 0;
13067   int ipv6_set = 0;
13068   int is_ipv6;
13069   int i;
13070   int ret;
13071
13072   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13073     {
13074       if (unformat (in, "ipv4"))
13075         ipv4_set = 1;
13076       else if (unformat (in, "ipv6"))
13077         ipv6_set = 1;
13078       else
13079         break;
13080     }
13081
13082   if (ipv4_set && ipv6_set)
13083     {
13084       errmsg ("ipv4 and ipv6 flags cannot be both set");
13085       return -99;
13086     }
13087
13088   if ((!ipv4_set) && (!ipv6_set))
13089     {
13090       errmsg ("no ipv4 nor ipv6 flag set");
13091       return -99;
13092     }
13093
13094   is_ipv6 = ipv6_set;
13095   vam->is_ipv6 = is_ipv6;
13096
13097   /* free old data */
13098   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13099     {
13100       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13101     }
13102   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13103
13104   M (IP_DUMP, mp);
13105   mp->is_ipv6 = ipv6_set;
13106   S (mp);
13107
13108   /* Use a control ping for synchronization */
13109   M (CONTROL_PING, mp_ping);
13110   S (mp_ping);
13111
13112   W (ret);
13113   return ret;
13114 }
13115
13116 static int
13117 api_ipsec_spd_add_del (vat_main_t * vam)
13118 {
13119   unformat_input_t *i = vam->input;
13120   vl_api_ipsec_spd_add_del_t *mp;
13121   u32 spd_id = ~0;
13122   u8 is_add = 1;
13123   int ret;
13124
13125   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13126     {
13127       if (unformat (i, "spd_id %d", &spd_id))
13128         ;
13129       else if (unformat (i, "del"))
13130         is_add = 0;
13131       else
13132         {
13133           clib_warning ("parse error '%U'", format_unformat_error, i);
13134           return -99;
13135         }
13136     }
13137   if (spd_id == ~0)
13138     {
13139       errmsg ("spd_id must be set");
13140       return -99;
13141     }
13142
13143   M (IPSEC_SPD_ADD_DEL, mp);
13144
13145   mp->spd_id = ntohl (spd_id);
13146   mp->is_add = is_add;
13147
13148   S (mp);
13149   W (ret);
13150   return ret;
13151 }
13152
13153 static int
13154 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13155 {
13156   unformat_input_t *i = vam->input;
13157   vl_api_ipsec_interface_add_del_spd_t *mp;
13158   u32 sw_if_index;
13159   u8 sw_if_index_set = 0;
13160   u32 spd_id = (u32) ~ 0;
13161   u8 is_add = 1;
13162   int ret;
13163
13164   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13165     {
13166       if (unformat (i, "del"))
13167         is_add = 0;
13168       else if (unformat (i, "spd_id %d", &spd_id))
13169         ;
13170       else
13171         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13172         sw_if_index_set = 1;
13173       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13174         sw_if_index_set = 1;
13175       else
13176         {
13177           clib_warning ("parse error '%U'", format_unformat_error, i);
13178           return -99;
13179         }
13180
13181     }
13182
13183   if (spd_id == (u32) ~ 0)
13184     {
13185       errmsg ("spd_id must be set");
13186       return -99;
13187     }
13188
13189   if (sw_if_index_set == 0)
13190     {
13191       errmsg ("missing interface name or sw_if_index");
13192       return -99;
13193     }
13194
13195   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13196
13197   mp->spd_id = ntohl (spd_id);
13198   mp->sw_if_index = ntohl (sw_if_index);
13199   mp->is_add = is_add;
13200
13201   S (mp);
13202   W (ret);
13203   return ret;
13204 }
13205
13206 static int
13207 api_ipsec_spd_add_del_entry (vat_main_t * vam)
13208 {
13209   unformat_input_t *i = vam->input;
13210   vl_api_ipsec_spd_add_del_entry_t *mp;
13211   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
13212   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13213   i32 priority = 0;
13214   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13215   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13216   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
13217   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
13218   int ret;
13219
13220   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
13221   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
13222   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
13223   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
13224   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
13225   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
13226
13227   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13228     {
13229       if (unformat (i, "del"))
13230         is_add = 0;
13231       if (unformat (i, "outbound"))
13232         is_outbound = 1;
13233       if (unformat (i, "inbound"))
13234         is_outbound = 0;
13235       else if (unformat (i, "spd_id %d", &spd_id))
13236         ;
13237       else if (unformat (i, "sa_id %d", &sa_id))
13238         ;
13239       else if (unformat (i, "priority %d", &priority))
13240         ;
13241       else if (unformat (i, "protocol %d", &protocol))
13242         ;
13243       else if (unformat (i, "lport_start %d", &lport_start))
13244         ;
13245       else if (unformat (i, "lport_stop %d", &lport_stop))
13246         ;
13247       else if (unformat (i, "rport_start %d", &rport_start))
13248         ;
13249       else if (unformat (i, "rport_stop %d", &rport_stop))
13250         ;
13251       else
13252         if (unformat
13253             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
13254         {
13255           is_ipv6 = 0;
13256           is_ip_any = 0;
13257         }
13258       else
13259         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
13260         {
13261           is_ipv6 = 0;
13262           is_ip_any = 0;
13263         }
13264       else
13265         if (unformat
13266             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
13267         {
13268           is_ipv6 = 0;
13269           is_ip_any = 0;
13270         }
13271       else
13272         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
13273         {
13274           is_ipv6 = 0;
13275           is_ip_any = 0;
13276         }
13277       else
13278         if (unformat
13279             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
13280         {
13281           is_ipv6 = 1;
13282           is_ip_any = 0;
13283         }
13284       else
13285         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
13286         {
13287           is_ipv6 = 1;
13288           is_ip_any = 0;
13289         }
13290       else
13291         if (unformat
13292             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
13293         {
13294           is_ipv6 = 1;
13295           is_ip_any = 0;
13296         }
13297       else
13298         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
13299         {
13300           is_ipv6 = 1;
13301           is_ip_any = 0;
13302         }
13303       else
13304         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13305         {
13306           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13307             {
13308               clib_warning ("unsupported action: 'resolve'");
13309               return -99;
13310             }
13311         }
13312       else
13313         {
13314           clib_warning ("parse error '%U'", format_unformat_error, i);
13315           return -99;
13316         }
13317
13318     }
13319
13320   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
13321
13322   mp->spd_id = ntohl (spd_id);
13323   mp->priority = ntohl (priority);
13324   mp->is_outbound = is_outbound;
13325
13326   mp->is_ipv6 = is_ipv6;
13327   if (is_ipv6 || is_ip_any)
13328     {
13329       clib_memcpy (mp->remote_address_start, &raddr6_start,
13330                    sizeof (ip6_address_t));
13331       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
13332                    sizeof (ip6_address_t));
13333       clib_memcpy (mp->local_address_start, &laddr6_start,
13334                    sizeof (ip6_address_t));
13335       clib_memcpy (mp->local_address_stop, &laddr6_stop,
13336                    sizeof (ip6_address_t));
13337     }
13338   else
13339     {
13340       clib_memcpy (mp->remote_address_start, &raddr4_start,
13341                    sizeof (ip4_address_t));
13342       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
13343                    sizeof (ip4_address_t));
13344       clib_memcpy (mp->local_address_start, &laddr4_start,
13345                    sizeof (ip4_address_t));
13346       clib_memcpy (mp->local_address_stop, &laddr4_stop,
13347                    sizeof (ip4_address_t));
13348     }
13349   mp->protocol = (u8) protocol;
13350   mp->local_port_start = ntohs ((u16) lport_start);
13351   mp->local_port_stop = ntohs ((u16) lport_stop);
13352   mp->remote_port_start = ntohs ((u16) rport_start);
13353   mp->remote_port_stop = ntohs ((u16) rport_stop);
13354   mp->policy = (u8) policy;
13355   mp->sa_id = ntohl (sa_id);
13356   mp->is_add = is_add;
13357   mp->is_ip_any = is_ip_any;
13358   S (mp);
13359   W (ret);
13360   return ret;
13361 }
13362
13363 static int
13364 api_ipsec_sad_add_del_entry (vat_main_t * vam)
13365 {
13366   unformat_input_t *i = vam->input;
13367   vl_api_ipsec_sad_add_del_entry_t *mp;
13368   u32 sad_id = 0, spi = 0;
13369   u8 *ck = 0, *ik = 0;
13370   u8 is_add = 1;
13371
13372   u8 protocol = IPSEC_PROTOCOL_AH;
13373   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
13374   u32 crypto_alg = 0, integ_alg = 0;
13375   ip4_address_t tun_src4;
13376   ip4_address_t tun_dst4;
13377   ip6_address_t tun_src6;
13378   ip6_address_t tun_dst6;
13379   int ret;
13380
13381   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13382     {
13383       if (unformat (i, "del"))
13384         is_add = 0;
13385       else if (unformat (i, "sad_id %d", &sad_id))
13386         ;
13387       else if (unformat (i, "spi %d", &spi))
13388         ;
13389       else if (unformat (i, "esp"))
13390         protocol = IPSEC_PROTOCOL_ESP;
13391       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
13392         {
13393           is_tunnel = 1;
13394           is_tunnel_ipv6 = 0;
13395         }
13396       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
13397         {
13398           is_tunnel = 1;
13399           is_tunnel_ipv6 = 0;
13400         }
13401       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
13402         {
13403           is_tunnel = 1;
13404           is_tunnel_ipv6 = 1;
13405         }
13406       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
13407         {
13408           is_tunnel = 1;
13409           is_tunnel_ipv6 = 1;
13410         }
13411       else
13412         if (unformat
13413             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
13414         {
13415           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
13416               crypto_alg >= IPSEC_CRYPTO_N_ALG)
13417             {
13418               clib_warning ("unsupported crypto-alg: '%U'",
13419                             format_ipsec_crypto_alg, crypto_alg);
13420               return -99;
13421             }
13422         }
13423       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13424         ;
13425       else
13426         if (unformat
13427             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
13428         {
13429           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
13430               integ_alg >= IPSEC_INTEG_N_ALG)
13431             {
13432               clib_warning ("unsupported integ-alg: '%U'",
13433                             format_ipsec_integ_alg, integ_alg);
13434               return -99;
13435             }
13436         }
13437       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13438         ;
13439       else
13440         {
13441           clib_warning ("parse error '%U'", format_unformat_error, i);
13442           return -99;
13443         }
13444
13445     }
13446
13447   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
13448
13449   mp->sad_id = ntohl (sad_id);
13450   mp->is_add = is_add;
13451   mp->protocol = protocol;
13452   mp->spi = ntohl (spi);
13453   mp->is_tunnel = is_tunnel;
13454   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
13455   mp->crypto_algorithm = crypto_alg;
13456   mp->integrity_algorithm = integ_alg;
13457   mp->crypto_key_length = vec_len (ck);
13458   mp->integrity_key_length = vec_len (ik);
13459
13460   if (mp->crypto_key_length > sizeof (mp->crypto_key))
13461     mp->crypto_key_length = sizeof (mp->crypto_key);
13462
13463   if (mp->integrity_key_length > sizeof (mp->integrity_key))
13464     mp->integrity_key_length = sizeof (mp->integrity_key);
13465
13466   if (ck)
13467     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
13468   if (ik)
13469     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
13470
13471   if (is_tunnel)
13472     {
13473       if (is_tunnel_ipv6)
13474         {
13475           clib_memcpy (mp->tunnel_src_address, &tun_src6,
13476                        sizeof (ip6_address_t));
13477           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
13478                        sizeof (ip6_address_t));
13479         }
13480       else
13481         {
13482           clib_memcpy (mp->tunnel_src_address, &tun_src4,
13483                        sizeof (ip4_address_t));
13484           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
13485                        sizeof (ip4_address_t));
13486         }
13487     }
13488
13489   S (mp);
13490   W (ret);
13491   return ret;
13492 }
13493
13494 static int
13495 api_ipsec_sa_set_key (vat_main_t * vam)
13496 {
13497   unformat_input_t *i = vam->input;
13498   vl_api_ipsec_sa_set_key_t *mp;
13499   u32 sa_id;
13500   u8 *ck = 0, *ik = 0;
13501   int ret;
13502
13503   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13504     {
13505       if (unformat (i, "sa_id %d", &sa_id))
13506         ;
13507       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13508         ;
13509       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13510         ;
13511       else
13512         {
13513           clib_warning ("parse error '%U'", format_unformat_error, i);
13514           return -99;
13515         }
13516     }
13517
13518   M (IPSEC_SA_SET_KEY, mp);
13519
13520   mp->sa_id = ntohl (sa_id);
13521   mp->crypto_key_length = vec_len (ck);
13522   mp->integrity_key_length = vec_len (ik);
13523
13524   if (mp->crypto_key_length > sizeof (mp->crypto_key))
13525     mp->crypto_key_length = sizeof (mp->crypto_key);
13526
13527   if (mp->integrity_key_length > sizeof (mp->integrity_key))
13528     mp->integrity_key_length = sizeof (mp->integrity_key);
13529
13530   if (ck)
13531     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
13532   if (ik)
13533     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
13534
13535   S (mp);
13536   W (ret);
13537   return ret;
13538 }
13539
13540 static int
13541 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
13542 {
13543   unformat_input_t *i = vam->input;
13544   vl_api_ipsec_tunnel_if_add_del_t *mp;
13545   u32 local_spi = 0, remote_spi = 0;
13546   u32 crypto_alg = 0, integ_alg = 0;
13547   u8 *lck = NULL, *rck = NULL;
13548   u8 *lik = NULL, *rik = NULL;
13549   ip4_address_t local_ip = { {0} };
13550   ip4_address_t remote_ip = { {0} };
13551   u8 is_add = 1;
13552   u8 esn = 0;
13553   u8 anti_replay = 0;
13554   int ret;
13555
13556   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13557     {
13558       if (unformat (i, "del"))
13559         is_add = 0;
13560       else if (unformat (i, "esn"))
13561         esn = 1;
13562       else if (unformat (i, "anti_replay"))
13563         anti_replay = 1;
13564       else if (unformat (i, "local_spi %d", &local_spi))
13565         ;
13566       else if (unformat (i, "remote_spi %d", &remote_spi))
13567         ;
13568       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
13569         ;
13570       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
13571         ;
13572       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
13573         ;
13574       else
13575         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
13576         ;
13577       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
13578         ;
13579       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
13580         ;
13581       else
13582         if (unformat
13583             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
13584         {
13585           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
13586               crypto_alg >= IPSEC_CRYPTO_N_ALG)
13587             {
13588               errmsg ("unsupported crypto-alg: '%U'\n",
13589                       format_ipsec_crypto_alg, crypto_alg);
13590               return -99;
13591             }
13592         }
13593       else
13594         if (unformat
13595             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
13596         {
13597           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
13598               integ_alg >= IPSEC_INTEG_N_ALG)
13599             {
13600               errmsg ("unsupported integ-alg: '%U'\n",
13601                       format_ipsec_integ_alg, integ_alg);
13602               return -99;
13603             }
13604         }
13605       else
13606         {
13607           errmsg ("parse error '%U'\n", format_unformat_error, i);
13608           return -99;
13609         }
13610     }
13611
13612   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
13613
13614   mp->is_add = is_add;
13615   mp->esn = esn;
13616   mp->anti_replay = anti_replay;
13617
13618   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
13619   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
13620
13621   mp->local_spi = htonl (local_spi);
13622   mp->remote_spi = htonl (remote_spi);
13623   mp->crypto_alg = (u8) crypto_alg;
13624
13625   mp->local_crypto_key_len = 0;
13626   if (lck)
13627     {
13628       mp->local_crypto_key_len = vec_len (lck);
13629       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
13630         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
13631       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
13632     }
13633
13634   mp->remote_crypto_key_len = 0;
13635   if (rck)
13636     {
13637       mp->remote_crypto_key_len = vec_len (rck);
13638       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
13639         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
13640       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
13641     }
13642
13643   mp->integ_alg = (u8) integ_alg;
13644
13645   mp->local_integ_key_len = 0;
13646   if (lik)
13647     {
13648       mp->local_integ_key_len = vec_len (lik);
13649       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
13650         mp->local_integ_key_len = sizeof (mp->local_integ_key);
13651       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
13652     }
13653
13654   mp->remote_integ_key_len = 0;
13655   if (rik)
13656     {
13657       mp->remote_integ_key_len = vec_len (rik);
13658       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
13659         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
13660       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
13661     }
13662
13663   S (mp);
13664   W (ret);
13665   return ret;
13666 }
13667
13668 static int
13669 api_ikev2_profile_add_del (vat_main_t * vam)
13670 {
13671   unformat_input_t *i = vam->input;
13672   vl_api_ikev2_profile_add_del_t *mp;
13673   u8 is_add = 1;
13674   u8 *name = 0;
13675   int ret;
13676
13677   const char *valid_chars = "a-zA-Z0-9_";
13678
13679   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13680     {
13681       if (unformat (i, "del"))
13682         is_add = 0;
13683       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13684         vec_add1 (name, 0);
13685       else
13686         {
13687           errmsg ("parse error '%U'", format_unformat_error, i);
13688           return -99;
13689         }
13690     }
13691
13692   if (!vec_len (name))
13693     {
13694       errmsg ("profile name must be specified");
13695       return -99;
13696     }
13697
13698   if (vec_len (name) > 64)
13699     {
13700       errmsg ("profile name too long");
13701       return -99;
13702     }
13703
13704   M (IKEV2_PROFILE_ADD_DEL, mp);
13705
13706   clib_memcpy (mp->name, name, vec_len (name));
13707   mp->is_add = is_add;
13708   vec_free (name);
13709
13710   S (mp);
13711   W (ret);
13712   return ret;
13713 }
13714
13715 static int
13716 api_ikev2_profile_set_auth (vat_main_t * vam)
13717 {
13718   unformat_input_t *i = vam->input;
13719   vl_api_ikev2_profile_set_auth_t *mp;
13720   u8 *name = 0;
13721   u8 *data = 0;
13722   u32 auth_method = 0;
13723   u8 is_hex = 0;
13724   int ret;
13725
13726   const char *valid_chars = "a-zA-Z0-9_";
13727
13728   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13729     {
13730       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13731         vec_add1 (name, 0);
13732       else if (unformat (i, "auth_method %U",
13733                          unformat_ikev2_auth_method, &auth_method))
13734         ;
13735       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
13736         is_hex = 1;
13737       else if (unformat (i, "auth_data %v", &data))
13738         ;
13739       else
13740         {
13741           errmsg ("parse error '%U'", format_unformat_error, i);
13742           return -99;
13743         }
13744     }
13745
13746   if (!vec_len (name))
13747     {
13748       errmsg ("profile name must be specified");
13749       return -99;
13750     }
13751
13752   if (vec_len (name) > 64)
13753     {
13754       errmsg ("profile name too long");
13755       return -99;
13756     }
13757
13758   if (!vec_len (data))
13759     {
13760       errmsg ("auth_data must be specified");
13761       return -99;
13762     }
13763
13764   if (!auth_method)
13765     {
13766       errmsg ("auth_method must be specified");
13767       return -99;
13768     }
13769
13770   M (IKEV2_PROFILE_SET_AUTH, mp);
13771
13772   mp->is_hex = is_hex;
13773   mp->auth_method = (u8) auth_method;
13774   mp->data_len = vec_len (data);
13775   clib_memcpy (mp->name, name, vec_len (name));
13776   clib_memcpy (mp->data, data, vec_len (data));
13777   vec_free (name);
13778   vec_free (data);
13779
13780   S (mp);
13781   W (ret);
13782   return ret;
13783 }
13784
13785 static int
13786 api_ikev2_profile_set_id (vat_main_t * vam)
13787 {
13788   unformat_input_t *i = vam->input;
13789   vl_api_ikev2_profile_set_id_t *mp;
13790   u8 *name = 0;
13791   u8 *data = 0;
13792   u8 is_local = 0;
13793   u32 id_type = 0;
13794   ip4_address_t ip4;
13795   int ret;
13796
13797   const char *valid_chars = "a-zA-Z0-9_";
13798
13799   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13800     {
13801       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13802         vec_add1 (name, 0);
13803       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
13804         ;
13805       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
13806         {
13807           data = vec_new (u8, 4);
13808           clib_memcpy (data, ip4.as_u8, 4);
13809         }
13810       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
13811         ;
13812       else if (unformat (i, "id_data %v", &data))
13813         ;
13814       else if (unformat (i, "local"))
13815         is_local = 1;
13816       else if (unformat (i, "remote"))
13817         is_local = 0;
13818       else
13819         {
13820           errmsg ("parse error '%U'", format_unformat_error, i);
13821           return -99;
13822         }
13823     }
13824
13825   if (!vec_len (name))
13826     {
13827       errmsg ("profile name must be specified");
13828       return -99;
13829     }
13830
13831   if (vec_len (name) > 64)
13832     {
13833       errmsg ("profile name too long");
13834       return -99;
13835     }
13836
13837   if (!vec_len (data))
13838     {
13839       errmsg ("id_data must be specified");
13840       return -99;
13841     }
13842
13843   if (!id_type)
13844     {
13845       errmsg ("id_type must be specified");
13846       return -99;
13847     }
13848
13849   M (IKEV2_PROFILE_SET_ID, mp);
13850
13851   mp->is_local = is_local;
13852   mp->id_type = (u8) id_type;
13853   mp->data_len = vec_len (data);
13854   clib_memcpy (mp->name, name, vec_len (name));
13855   clib_memcpy (mp->data, data, vec_len (data));
13856   vec_free (name);
13857   vec_free (data);
13858
13859   S (mp);
13860   W (ret);
13861   return ret;
13862 }
13863
13864 static int
13865 api_ikev2_profile_set_ts (vat_main_t * vam)
13866 {
13867   unformat_input_t *i = vam->input;
13868   vl_api_ikev2_profile_set_ts_t *mp;
13869   u8 *name = 0;
13870   u8 is_local = 0;
13871   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
13872   ip4_address_t start_addr, end_addr;
13873
13874   const char *valid_chars = "a-zA-Z0-9_";
13875   int ret;
13876
13877   start_addr.as_u32 = 0;
13878   end_addr.as_u32 = (u32) ~ 0;
13879
13880   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13881     {
13882       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13883         vec_add1 (name, 0);
13884       else if (unformat (i, "protocol %d", &proto))
13885         ;
13886       else if (unformat (i, "start_port %d", &start_port))
13887         ;
13888       else if (unformat (i, "end_port %d", &end_port))
13889         ;
13890       else
13891         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
13892         ;
13893       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
13894         ;
13895       else if (unformat (i, "local"))
13896         is_local = 1;
13897       else if (unformat (i, "remote"))
13898         is_local = 0;
13899       else
13900         {
13901           errmsg ("parse error '%U'", format_unformat_error, i);
13902           return -99;
13903         }
13904     }
13905
13906   if (!vec_len (name))
13907     {
13908       errmsg ("profile name must be specified");
13909       return -99;
13910     }
13911
13912   if (vec_len (name) > 64)
13913     {
13914       errmsg ("profile name too long");
13915       return -99;
13916     }
13917
13918   M (IKEV2_PROFILE_SET_TS, mp);
13919
13920   mp->is_local = is_local;
13921   mp->proto = (u8) proto;
13922   mp->start_port = (u16) start_port;
13923   mp->end_port = (u16) end_port;
13924   mp->start_addr = start_addr.as_u32;
13925   mp->end_addr = end_addr.as_u32;
13926   clib_memcpy (mp->name, name, vec_len (name));
13927   vec_free (name);
13928
13929   S (mp);
13930   W (ret);
13931   return ret;
13932 }
13933
13934 static int
13935 api_ikev2_set_local_key (vat_main_t * vam)
13936 {
13937   unformat_input_t *i = vam->input;
13938   vl_api_ikev2_set_local_key_t *mp;
13939   u8 *file = 0;
13940   int ret;
13941
13942   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13943     {
13944       if (unformat (i, "file %v", &file))
13945         vec_add1 (file, 0);
13946       else
13947         {
13948           errmsg ("parse error '%U'", format_unformat_error, i);
13949           return -99;
13950         }
13951     }
13952
13953   if (!vec_len (file))
13954     {
13955       errmsg ("RSA key file must be specified");
13956       return -99;
13957     }
13958
13959   if (vec_len (file) > 256)
13960     {
13961       errmsg ("file name too long");
13962       return -99;
13963     }
13964
13965   M (IKEV2_SET_LOCAL_KEY, mp);
13966
13967   clib_memcpy (mp->key_file, file, vec_len (file));
13968   vec_free (file);
13969
13970   S (mp);
13971   W (ret);
13972   return ret;
13973 }
13974
13975 static int
13976 api_ikev2_set_responder (vat_main_t * vam)
13977 {
13978   unformat_input_t *i = vam->input;
13979   vl_api_ikev2_set_responder_t *mp;
13980   int ret;
13981   u8 *name = 0;
13982   u32 sw_if_index = ~0;
13983   ip4_address_t address;
13984
13985   const char *valid_chars = "a-zA-Z0-9_";
13986
13987   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13988     {
13989       if (unformat
13990           (i, "%U interface %d address %U", unformat_token, valid_chars,
13991            &name, &sw_if_index, unformat_ip4_address, &address))
13992         vec_add1 (name, 0);
13993       else
13994         {
13995           errmsg ("parse error '%U'", format_unformat_error, i);
13996           return -99;
13997         }
13998     }
13999
14000   if (!vec_len (name))
14001     {
14002       errmsg ("profile name must be specified");
14003       return -99;
14004     }
14005
14006   if (vec_len (name) > 64)
14007     {
14008       errmsg ("profile name too long");
14009       return -99;
14010     }
14011
14012   M (IKEV2_SET_RESPONDER, mp);
14013
14014   clib_memcpy (mp->name, name, vec_len (name));
14015   vec_free (name);
14016
14017   mp->sw_if_index = sw_if_index;
14018   clib_memcpy (mp->address, &address, sizeof (address));
14019
14020   S (mp);
14021   W (ret);
14022   return ret;
14023 }
14024
14025 static int
14026 api_ikev2_set_ike_transforms (vat_main_t * vam)
14027 {
14028   unformat_input_t *i = vam->input;
14029   vl_api_ikev2_set_ike_transforms_t *mp;
14030   int ret;
14031   u8 *name = 0;
14032   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
14033
14034   const char *valid_chars = "a-zA-Z0-9_";
14035
14036   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14037     {
14038       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
14039                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
14040         vec_add1 (name, 0);
14041       else
14042         {
14043           errmsg ("parse error '%U'", format_unformat_error, i);
14044           return -99;
14045         }
14046     }
14047
14048   if (!vec_len (name))
14049     {
14050       errmsg ("profile name must be specified");
14051       return -99;
14052     }
14053
14054   if (vec_len (name) > 64)
14055     {
14056       errmsg ("profile name too long");
14057       return -99;
14058     }
14059
14060   M (IKEV2_SET_IKE_TRANSFORMS, mp);
14061
14062   clib_memcpy (mp->name, name, vec_len (name));
14063   vec_free (name);
14064   mp->crypto_alg = crypto_alg;
14065   mp->crypto_key_size = crypto_key_size;
14066   mp->integ_alg = integ_alg;
14067   mp->dh_group = dh_group;
14068
14069   S (mp);
14070   W (ret);
14071   return ret;
14072 }
14073
14074
14075 static int
14076 api_ikev2_set_esp_transforms (vat_main_t * vam)
14077 {
14078   unformat_input_t *i = vam->input;
14079   vl_api_ikev2_set_esp_transforms_t *mp;
14080   int ret;
14081   u8 *name = 0;
14082   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
14083
14084   const char *valid_chars = "a-zA-Z0-9_";
14085
14086   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14087     {
14088       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
14089                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
14090         vec_add1 (name, 0);
14091       else
14092         {
14093           errmsg ("parse error '%U'", format_unformat_error, i);
14094           return -99;
14095         }
14096     }
14097
14098   if (!vec_len (name))
14099     {
14100       errmsg ("profile name must be specified");
14101       return -99;
14102     }
14103
14104   if (vec_len (name) > 64)
14105     {
14106       errmsg ("profile name too long");
14107       return -99;
14108     }
14109
14110   M (IKEV2_SET_ESP_TRANSFORMS, mp);
14111
14112   clib_memcpy (mp->name, name, vec_len (name));
14113   vec_free (name);
14114   mp->crypto_alg = crypto_alg;
14115   mp->crypto_key_size = crypto_key_size;
14116   mp->integ_alg = integ_alg;
14117   mp->dh_group = dh_group;
14118
14119   S (mp);
14120   W (ret);
14121   return ret;
14122 }
14123
14124 static int
14125 api_ikev2_set_sa_lifetime (vat_main_t * vam)
14126 {
14127   unformat_input_t *i = vam->input;
14128   vl_api_ikev2_set_sa_lifetime_t *mp;
14129   int ret;
14130   u8 *name = 0;
14131   u64 lifetime, lifetime_maxdata;
14132   u32 lifetime_jitter, handover;
14133
14134   const char *valid_chars = "a-zA-Z0-9_";
14135
14136   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14137     {
14138       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
14139                     &lifetime, &lifetime_jitter, &handover,
14140                     &lifetime_maxdata))
14141         vec_add1 (name, 0);
14142       else
14143         {
14144           errmsg ("parse error '%U'", format_unformat_error, i);
14145           return -99;
14146         }
14147     }
14148
14149   if (!vec_len (name))
14150     {
14151       errmsg ("profile name must be specified");
14152       return -99;
14153     }
14154
14155   if (vec_len (name) > 64)
14156     {
14157       errmsg ("profile name too long");
14158       return -99;
14159     }
14160
14161   M (IKEV2_SET_SA_LIFETIME, mp);
14162
14163   clib_memcpy (mp->name, name, vec_len (name));
14164   vec_free (name);
14165   mp->lifetime = lifetime;
14166   mp->lifetime_jitter = lifetime_jitter;
14167   mp->handover = handover;
14168   mp->lifetime_maxdata = lifetime_maxdata;
14169
14170   S (mp);
14171   W (ret);
14172   return ret;
14173 }
14174
14175 static int
14176 api_ikev2_initiate_sa_init (vat_main_t * vam)
14177 {
14178   unformat_input_t *i = vam->input;
14179   vl_api_ikev2_initiate_sa_init_t *mp;
14180   int ret;
14181   u8 *name = 0;
14182
14183   const char *valid_chars = "a-zA-Z0-9_";
14184
14185   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14186     {
14187       if (unformat (i, "%U", unformat_token, valid_chars, &name))
14188         vec_add1 (name, 0);
14189       else
14190         {
14191           errmsg ("parse error '%U'", format_unformat_error, i);
14192           return -99;
14193         }
14194     }
14195
14196   if (!vec_len (name))
14197     {
14198       errmsg ("profile name must be specified");
14199       return -99;
14200     }
14201
14202   if (vec_len (name) > 64)
14203     {
14204       errmsg ("profile name too long");
14205       return -99;
14206     }
14207
14208   M (IKEV2_INITIATE_SA_INIT, mp);
14209
14210   clib_memcpy (mp->name, name, vec_len (name));
14211   vec_free (name);
14212
14213   S (mp);
14214   W (ret);
14215   return ret;
14216 }
14217
14218 static int
14219 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
14220 {
14221   unformat_input_t *i = vam->input;
14222   vl_api_ikev2_initiate_del_ike_sa_t *mp;
14223   int ret;
14224   u64 ispi;
14225
14226
14227   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14228     {
14229       if (unformat (i, "%lx", &ispi))
14230         ;
14231       else
14232         {
14233           errmsg ("parse error '%U'", format_unformat_error, i);
14234           return -99;
14235         }
14236     }
14237
14238   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
14239
14240   mp->ispi = ispi;
14241
14242   S (mp);
14243   W (ret);
14244   return ret;
14245 }
14246
14247 static int
14248 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
14249 {
14250   unformat_input_t *i = vam->input;
14251   vl_api_ikev2_initiate_del_child_sa_t *mp;
14252   int ret;
14253   u32 ispi;
14254
14255
14256   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14257     {
14258       if (unformat (i, "%x", &ispi))
14259         ;
14260       else
14261         {
14262           errmsg ("parse error '%U'", format_unformat_error, i);
14263           return -99;
14264         }
14265     }
14266
14267   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
14268
14269   mp->ispi = ispi;
14270
14271   S (mp);
14272   W (ret);
14273   return ret;
14274 }
14275
14276 static int
14277 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
14278 {
14279   unformat_input_t *i = vam->input;
14280   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
14281   int ret;
14282   u32 ispi;
14283
14284
14285   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14286     {
14287       if (unformat (i, "%x", &ispi))
14288         ;
14289       else
14290         {
14291           errmsg ("parse error '%U'", format_unformat_error, i);
14292           return -99;
14293         }
14294     }
14295
14296   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
14297
14298   mp->ispi = ispi;
14299
14300   S (mp);
14301   W (ret);
14302   return ret;
14303 }
14304
14305 /*
14306  * MAP
14307  */
14308 static int
14309 api_map_add_domain (vat_main_t * vam)
14310 {
14311   unformat_input_t *i = vam->input;
14312   vl_api_map_add_domain_t *mp;
14313
14314   ip4_address_t ip4_prefix;
14315   ip6_address_t ip6_prefix;
14316   ip6_address_t ip6_src;
14317   u32 num_m_args = 0;
14318   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
14319     0, psid_length = 0;
14320   u8 is_translation = 0;
14321   u32 mtu = 0;
14322   u32 ip6_src_len = 128;
14323   int ret;
14324
14325   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14326     {
14327       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
14328                     &ip4_prefix, &ip4_prefix_len))
14329         num_m_args++;
14330       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
14331                          &ip6_prefix, &ip6_prefix_len))
14332         num_m_args++;
14333       else
14334         if (unformat
14335             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
14336              &ip6_src_len))
14337         num_m_args++;
14338       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
14339         num_m_args++;
14340       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
14341         num_m_args++;
14342       else if (unformat (i, "psid-offset %d", &psid_offset))
14343         num_m_args++;
14344       else if (unformat (i, "psid-len %d", &psid_length))
14345         num_m_args++;
14346       else if (unformat (i, "mtu %d", &mtu))
14347         num_m_args++;
14348       else if (unformat (i, "map-t"))
14349         is_translation = 1;
14350       else
14351         {
14352           clib_warning ("parse error '%U'", format_unformat_error, i);
14353           return -99;
14354         }
14355     }
14356
14357   if (num_m_args < 3)
14358     {
14359       errmsg ("mandatory argument(s) missing");
14360       return -99;
14361     }
14362
14363   /* Construct the API message */
14364   M (MAP_ADD_DOMAIN, mp);
14365
14366   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
14367   mp->ip4_prefix_len = ip4_prefix_len;
14368
14369   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
14370   mp->ip6_prefix_len = ip6_prefix_len;
14371
14372   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
14373   mp->ip6_src_prefix_len = ip6_src_len;
14374
14375   mp->ea_bits_len = ea_bits_len;
14376   mp->psid_offset = psid_offset;
14377   mp->psid_length = psid_length;
14378   mp->is_translation = is_translation;
14379   mp->mtu = htons (mtu);
14380
14381   /* send it... */
14382   S (mp);
14383
14384   /* Wait for a reply, return good/bad news  */
14385   W (ret);
14386   return ret;
14387 }
14388
14389 static int
14390 api_map_del_domain (vat_main_t * vam)
14391 {
14392   unformat_input_t *i = vam->input;
14393   vl_api_map_del_domain_t *mp;
14394
14395   u32 num_m_args = 0;
14396   u32 index;
14397   int ret;
14398
14399   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14400     {
14401       if (unformat (i, "index %d", &index))
14402         num_m_args++;
14403       else
14404         {
14405           clib_warning ("parse error '%U'", format_unformat_error, i);
14406           return -99;
14407         }
14408     }
14409
14410   if (num_m_args != 1)
14411     {
14412       errmsg ("mandatory argument(s) missing");
14413       return -99;
14414     }
14415
14416   /* Construct the API message */
14417   M (MAP_DEL_DOMAIN, mp);
14418
14419   mp->index = ntohl (index);
14420
14421   /* send it... */
14422   S (mp);
14423
14424   /* Wait for a reply, return good/bad news  */
14425   W (ret);
14426   return ret;
14427 }
14428
14429 static int
14430 api_map_add_del_rule (vat_main_t * vam)
14431 {
14432   unformat_input_t *i = vam->input;
14433   vl_api_map_add_del_rule_t *mp;
14434   u8 is_add = 1;
14435   ip6_address_t ip6_dst;
14436   u32 num_m_args = 0, index, psid = 0;
14437   int ret;
14438
14439   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14440     {
14441       if (unformat (i, "index %d", &index))
14442         num_m_args++;
14443       else if (unformat (i, "psid %d", &psid))
14444         num_m_args++;
14445       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
14446         num_m_args++;
14447       else if (unformat (i, "del"))
14448         {
14449           is_add = 0;
14450         }
14451       else
14452         {
14453           clib_warning ("parse error '%U'", format_unformat_error, i);
14454           return -99;
14455         }
14456     }
14457
14458   /* Construct the API message */
14459   M (MAP_ADD_DEL_RULE, mp);
14460
14461   mp->index = ntohl (index);
14462   mp->is_add = is_add;
14463   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
14464   mp->psid = ntohs (psid);
14465
14466   /* send it... */
14467   S (mp);
14468
14469   /* Wait for a reply, return good/bad news  */
14470   W (ret);
14471   return ret;
14472 }
14473
14474 static int
14475 api_map_domain_dump (vat_main_t * vam)
14476 {
14477   vl_api_map_domain_dump_t *mp;
14478   vl_api_control_ping_t *mp_ping;
14479   int ret;
14480
14481   /* Construct the API message */
14482   M (MAP_DOMAIN_DUMP, mp);
14483
14484   /* send it... */
14485   S (mp);
14486
14487   /* Use a control ping for synchronization */
14488   M (CONTROL_PING, mp_ping);
14489   S (mp_ping);
14490
14491   W (ret);
14492   return ret;
14493 }
14494
14495 static int
14496 api_map_rule_dump (vat_main_t * vam)
14497 {
14498   unformat_input_t *i = vam->input;
14499   vl_api_map_rule_dump_t *mp;
14500   vl_api_control_ping_t *mp_ping;
14501   u32 domain_index = ~0;
14502   int ret;
14503
14504   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14505     {
14506       if (unformat (i, "index %u", &domain_index))
14507         ;
14508       else
14509         break;
14510     }
14511
14512   if (domain_index == ~0)
14513     {
14514       clib_warning ("parse error: domain index expected");
14515       return -99;
14516     }
14517
14518   /* Construct the API message */
14519   M (MAP_RULE_DUMP, mp);
14520
14521   mp->domain_index = htonl (domain_index);
14522
14523   /* send it... */
14524   S (mp);
14525
14526   /* Use a control ping for synchronization */
14527   M (CONTROL_PING, mp_ping);
14528   S (mp_ping);
14529
14530   W (ret);
14531   return ret;
14532 }
14533
14534 static void vl_api_map_add_domain_reply_t_handler
14535   (vl_api_map_add_domain_reply_t * mp)
14536 {
14537   vat_main_t *vam = &vat_main;
14538   i32 retval = ntohl (mp->retval);
14539
14540   if (vam->async_mode)
14541     {
14542       vam->async_errors += (retval < 0);
14543     }
14544   else
14545     {
14546       vam->retval = retval;
14547       vam->result_ready = 1;
14548     }
14549 }
14550
14551 static void vl_api_map_add_domain_reply_t_handler_json
14552   (vl_api_map_add_domain_reply_t * mp)
14553 {
14554   vat_main_t *vam = &vat_main;
14555   vat_json_node_t node;
14556
14557   vat_json_init_object (&node);
14558   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
14559   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
14560
14561   vat_json_print (vam->ofp, &node);
14562   vat_json_free (&node);
14563
14564   vam->retval = ntohl (mp->retval);
14565   vam->result_ready = 1;
14566 }
14567
14568 static int
14569 api_get_first_msg_id (vat_main_t * vam)
14570 {
14571   vl_api_get_first_msg_id_t *mp;
14572   unformat_input_t *i = vam->input;
14573   u8 *name;
14574   u8 name_set = 0;
14575   int ret;
14576
14577   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14578     {
14579       if (unformat (i, "client %s", &name))
14580         name_set = 1;
14581       else
14582         break;
14583     }
14584
14585   if (name_set == 0)
14586     {
14587       errmsg ("missing client name");
14588       return -99;
14589     }
14590   vec_add1 (name, 0);
14591
14592   if (vec_len (name) > 63)
14593     {
14594       errmsg ("client name too long");
14595       return -99;
14596     }
14597
14598   M (GET_FIRST_MSG_ID, mp);
14599   clib_memcpy (mp->name, name, vec_len (name));
14600   S (mp);
14601   W (ret);
14602   return ret;
14603 }
14604
14605 static int
14606 api_cop_interface_enable_disable (vat_main_t * vam)
14607 {
14608   unformat_input_t *line_input = vam->input;
14609   vl_api_cop_interface_enable_disable_t *mp;
14610   u32 sw_if_index = ~0;
14611   u8 enable_disable = 1;
14612   int ret;
14613
14614   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14615     {
14616       if (unformat (line_input, "disable"))
14617         enable_disable = 0;
14618       if (unformat (line_input, "enable"))
14619         enable_disable = 1;
14620       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14621                          vam, &sw_if_index))
14622         ;
14623       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14624         ;
14625       else
14626         break;
14627     }
14628
14629   if (sw_if_index == ~0)
14630     {
14631       errmsg ("missing interface name or sw_if_index");
14632       return -99;
14633     }
14634
14635   /* Construct the API message */
14636   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14637   mp->sw_if_index = ntohl (sw_if_index);
14638   mp->enable_disable = enable_disable;
14639
14640   /* send it... */
14641   S (mp);
14642   /* Wait for the reply */
14643   W (ret);
14644   return ret;
14645 }
14646
14647 static int
14648 api_cop_whitelist_enable_disable (vat_main_t * vam)
14649 {
14650   unformat_input_t *line_input = vam->input;
14651   vl_api_cop_whitelist_enable_disable_t *mp;
14652   u32 sw_if_index = ~0;
14653   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14654   u32 fib_id = 0;
14655   int ret;
14656
14657   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14658     {
14659       if (unformat (line_input, "ip4"))
14660         ip4 = 1;
14661       else if (unformat (line_input, "ip6"))
14662         ip6 = 1;
14663       else if (unformat (line_input, "default"))
14664         default_cop = 1;
14665       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14666                          vam, &sw_if_index))
14667         ;
14668       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14669         ;
14670       else if (unformat (line_input, "fib-id %d", &fib_id))
14671         ;
14672       else
14673         break;
14674     }
14675
14676   if (sw_if_index == ~0)
14677     {
14678       errmsg ("missing interface name or sw_if_index");
14679       return -99;
14680     }
14681
14682   /* Construct the API message */
14683   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14684   mp->sw_if_index = ntohl (sw_if_index);
14685   mp->fib_id = ntohl (fib_id);
14686   mp->ip4 = ip4;
14687   mp->ip6 = ip6;
14688   mp->default_cop = default_cop;
14689
14690   /* send it... */
14691   S (mp);
14692   /* Wait for the reply */
14693   W (ret);
14694   return ret;
14695 }
14696
14697 static int
14698 api_get_node_graph (vat_main_t * vam)
14699 {
14700   vl_api_get_node_graph_t *mp;
14701   int ret;
14702
14703   M (GET_NODE_GRAPH, mp);
14704
14705   /* send it... */
14706   S (mp);
14707   /* Wait for the reply */
14708   W (ret);
14709   return ret;
14710 }
14711
14712 /* *INDENT-OFF* */
14713 /** Used for parsing LISP eids */
14714 typedef CLIB_PACKED(struct{
14715   u8 addr[16];   /**< eid address */
14716   u32 len;       /**< prefix length if IP */
14717   u8 type;      /**< type of eid */
14718 }) lisp_eid_vat_t;
14719 /* *INDENT-ON* */
14720
14721 static uword
14722 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14723 {
14724   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14725
14726   memset (a, 0, sizeof (a[0]));
14727
14728   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
14729     {
14730       a->type = 0;              /* ipv4 type */
14731     }
14732   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
14733     {
14734       a->type = 1;              /* ipv6 type */
14735     }
14736   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
14737     {
14738       a->type = 2;              /* mac type */
14739     }
14740   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
14741     {
14742       a->type = 3;              /* NSH type */
14743       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
14744       nsh->spi = clib_host_to_net_u32 (nsh->spi);
14745     }
14746   else
14747     {
14748       return 0;
14749     }
14750
14751   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
14752     {
14753       return 0;
14754     }
14755
14756   return 1;
14757 }
14758
14759 static int
14760 lisp_eid_size_vat (u8 type)
14761 {
14762   switch (type)
14763     {
14764     case 0:
14765       return 4;
14766     case 1:
14767       return 16;
14768     case 2:
14769       return 6;
14770     case 3:
14771       return 5;
14772     }
14773   return 0;
14774 }
14775
14776 static void
14777 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
14778 {
14779   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
14780 }
14781
14782 static int
14783 api_one_add_del_locator_set (vat_main_t * vam)
14784 {
14785   unformat_input_t *input = vam->input;
14786   vl_api_one_add_del_locator_set_t *mp;
14787   u8 is_add = 1;
14788   u8 *locator_set_name = NULL;
14789   u8 locator_set_name_set = 0;
14790   vl_api_local_locator_t locator, *locators = 0;
14791   u32 sw_if_index, priority, weight;
14792   u32 data_len = 0;
14793
14794   int ret;
14795   /* Parse args required to build the message */
14796   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14797     {
14798       if (unformat (input, "del"))
14799         {
14800           is_add = 0;
14801         }
14802       else if (unformat (input, "locator-set %s", &locator_set_name))
14803         {
14804           locator_set_name_set = 1;
14805         }
14806       else if (unformat (input, "sw_if_index %u p %u w %u",
14807                          &sw_if_index, &priority, &weight))
14808         {
14809           locator.sw_if_index = htonl (sw_if_index);
14810           locator.priority = priority;
14811           locator.weight = weight;
14812           vec_add1 (locators, locator);
14813         }
14814       else
14815         if (unformat
14816             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14817              &sw_if_index, &priority, &weight))
14818         {
14819           locator.sw_if_index = htonl (sw_if_index);
14820           locator.priority = priority;
14821           locator.weight = weight;
14822           vec_add1 (locators, locator);
14823         }
14824       else
14825         break;
14826     }
14827
14828   if (locator_set_name_set == 0)
14829     {
14830       errmsg ("missing locator-set name");
14831       vec_free (locators);
14832       return -99;
14833     }
14834
14835   if (vec_len (locator_set_name) > 64)
14836     {
14837       errmsg ("locator-set name too long");
14838       vec_free (locator_set_name);
14839       vec_free (locators);
14840       return -99;
14841     }
14842   vec_add1 (locator_set_name, 0);
14843
14844   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14845
14846   /* Construct the API message */
14847   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14848
14849   mp->is_add = is_add;
14850   clib_memcpy (mp->locator_set_name, locator_set_name,
14851                vec_len (locator_set_name));
14852   vec_free (locator_set_name);
14853
14854   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14855   if (locators)
14856     clib_memcpy (mp->locators, locators, data_len);
14857   vec_free (locators);
14858
14859   /* send it... */
14860   S (mp);
14861
14862   /* Wait for a reply... */
14863   W (ret);
14864   return ret;
14865 }
14866
14867 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14868
14869 static int
14870 api_one_add_del_locator (vat_main_t * vam)
14871 {
14872   unformat_input_t *input = vam->input;
14873   vl_api_one_add_del_locator_t *mp;
14874   u32 tmp_if_index = ~0;
14875   u32 sw_if_index = ~0;
14876   u8 sw_if_index_set = 0;
14877   u8 sw_if_index_if_name_set = 0;
14878   u32 priority = ~0;
14879   u8 priority_set = 0;
14880   u32 weight = ~0;
14881   u8 weight_set = 0;
14882   u8 is_add = 1;
14883   u8 *locator_set_name = NULL;
14884   u8 locator_set_name_set = 0;
14885   int ret;
14886
14887   /* Parse args required to build the message */
14888   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14889     {
14890       if (unformat (input, "del"))
14891         {
14892           is_add = 0;
14893         }
14894       else if (unformat (input, "locator-set %s", &locator_set_name))
14895         {
14896           locator_set_name_set = 1;
14897         }
14898       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14899                          &tmp_if_index))
14900         {
14901           sw_if_index_if_name_set = 1;
14902           sw_if_index = tmp_if_index;
14903         }
14904       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14905         {
14906           sw_if_index_set = 1;
14907           sw_if_index = tmp_if_index;
14908         }
14909       else if (unformat (input, "p %d", &priority))
14910         {
14911           priority_set = 1;
14912         }
14913       else if (unformat (input, "w %d", &weight))
14914         {
14915           weight_set = 1;
14916         }
14917       else
14918         break;
14919     }
14920
14921   if (locator_set_name_set == 0)
14922     {
14923       errmsg ("missing locator-set name");
14924       return -99;
14925     }
14926
14927   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14928     {
14929       errmsg ("missing sw_if_index");
14930       vec_free (locator_set_name);
14931       return -99;
14932     }
14933
14934   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14935     {
14936       errmsg ("cannot use both params interface name and sw_if_index");
14937       vec_free (locator_set_name);
14938       return -99;
14939     }
14940
14941   if (priority_set == 0)
14942     {
14943       errmsg ("missing locator-set priority");
14944       vec_free (locator_set_name);
14945       return -99;
14946     }
14947
14948   if (weight_set == 0)
14949     {
14950       errmsg ("missing locator-set weight");
14951       vec_free (locator_set_name);
14952       return -99;
14953     }
14954
14955   if (vec_len (locator_set_name) > 64)
14956     {
14957       errmsg ("locator-set name too long");
14958       vec_free (locator_set_name);
14959       return -99;
14960     }
14961   vec_add1 (locator_set_name, 0);
14962
14963   /* Construct the API message */
14964   M (ONE_ADD_DEL_LOCATOR, mp);
14965
14966   mp->is_add = is_add;
14967   mp->sw_if_index = ntohl (sw_if_index);
14968   mp->priority = priority;
14969   mp->weight = weight;
14970   clib_memcpy (mp->locator_set_name, locator_set_name,
14971                vec_len (locator_set_name));
14972   vec_free (locator_set_name);
14973
14974   /* send it... */
14975   S (mp);
14976
14977   /* Wait for a reply... */
14978   W (ret);
14979   return ret;
14980 }
14981
14982 #define api_lisp_add_del_locator api_one_add_del_locator
14983
14984 uword
14985 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14986 {
14987   u32 *key_id = va_arg (*args, u32 *);
14988   u8 *s = 0;
14989
14990   if (unformat (input, "%s", &s))
14991     {
14992       if (!strcmp ((char *) s, "sha1"))
14993         key_id[0] = HMAC_SHA_1_96;
14994       else if (!strcmp ((char *) s, "sha256"))
14995         key_id[0] = HMAC_SHA_256_128;
14996       else
14997         {
14998           clib_warning ("invalid key_id: '%s'", s);
14999           key_id[0] = HMAC_NO_KEY;
15000         }
15001     }
15002   else
15003     return 0;
15004
15005   vec_free (s);
15006   return 1;
15007 }
15008
15009 static int
15010 api_one_add_del_local_eid (vat_main_t * vam)
15011 {
15012   unformat_input_t *input = vam->input;
15013   vl_api_one_add_del_local_eid_t *mp;
15014   u8 is_add = 1;
15015   u8 eid_set = 0;
15016   lisp_eid_vat_t _eid, *eid = &_eid;
15017   u8 *locator_set_name = 0;
15018   u8 locator_set_name_set = 0;
15019   u32 vni = 0;
15020   u16 key_id = 0;
15021   u8 *key = 0;
15022   int ret;
15023
15024   /* Parse args required to build the message */
15025   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15026     {
15027       if (unformat (input, "del"))
15028         {
15029           is_add = 0;
15030         }
15031       else if (unformat (input, "vni %d", &vni))
15032         {
15033           ;
15034         }
15035       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15036         {
15037           eid_set = 1;
15038         }
15039       else if (unformat (input, "locator-set %s", &locator_set_name))
15040         {
15041           locator_set_name_set = 1;
15042         }
15043       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15044         ;
15045       else if (unformat (input, "secret-key %_%v%_", &key))
15046         ;
15047       else
15048         break;
15049     }
15050
15051   if (locator_set_name_set == 0)
15052     {
15053       errmsg ("missing locator-set name");
15054       return -99;
15055     }
15056
15057   if (0 == eid_set)
15058     {
15059       errmsg ("EID address not set!");
15060       vec_free (locator_set_name);
15061       return -99;
15062     }
15063
15064   if (key && (0 == key_id))
15065     {
15066       errmsg ("invalid key_id!");
15067       return -99;
15068     }
15069
15070   if (vec_len (key) > 64)
15071     {
15072       errmsg ("key too long");
15073       vec_free (key);
15074       return -99;
15075     }
15076
15077   if (vec_len (locator_set_name) > 64)
15078     {
15079       errmsg ("locator-set name too long");
15080       vec_free (locator_set_name);
15081       return -99;
15082     }
15083   vec_add1 (locator_set_name, 0);
15084
15085   /* Construct the API message */
15086   M (ONE_ADD_DEL_LOCAL_EID, mp);
15087
15088   mp->is_add = is_add;
15089   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15090   mp->eid_type = eid->type;
15091   mp->prefix_len = eid->len;
15092   mp->vni = clib_host_to_net_u32 (vni);
15093   mp->key_id = clib_host_to_net_u16 (key_id);
15094   clib_memcpy (mp->locator_set_name, locator_set_name,
15095                vec_len (locator_set_name));
15096   clib_memcpy (mp->key, key, vec_len (key));
15097
15098   vec_free (locator_set_name);
15099   vec_free (key);
15100
15101   /* send it... */
15102   S (mp);
15103
15104   /* Wait for a reply... */
15105   W (ret);
15106   return ret;
15107 }
15108
15109 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15110
15111 static int
15112 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15113 {
15114   u32 dp_table = 0, vni = 0;;
15115   unformat_input_t *input = vam->input;
15116   vl_api_gpe_add_del_fwd_entry_t *mp;
15117   u8 is_add = 1;
15118   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15119   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15120   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15121   u32 action = ~0, w;
15122   ip4_address_t rmt_rloc4, lcl_rloc4;
15123   ip6_address_t rmt_rloc6, lcl_rloc6;
15124   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15125   int ret;
15126
15127   memset (&rloc, 0, sizeof (rloc));
15128
15129   /* Parse args required to build the message */
15130   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15131     {
15132       if (unformat (input, "del"))
15133         is_add = 0;
15134       else if (unformat (input, "add"))
15135         is_add = 1;
15136       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15137         {
15138           rmt_eid_set = 1;
15139         }
15140       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15141         {
15142           lcl_eid_set = 1;
15143         }
15144       else if (unformat (input, "vrf %d", &dp_table))
15145         ;
15146       else if (unformat (input, "bd %d", &dp_table))
15147         ;
15148       else if (unformat (input, "vni %d", &vni))
15149         ;
15150       else if (unformat (input, "w %d", &w))
15151         {
15152           if (!curr_rloc)
15153             {
15154               errmsg ("No RLOC configured for setting priority/weight!");
15155               return -99;
15156             }
15157           curr_rloc->weight = w;
15158         }
15159       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15160                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15161         {
15162           rloc.is_ip4 = 1;
15163
15164           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15165           rloc.weight = 0;
15166           vec_add1 (lcl_locs, rloc);
15167
15168           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15169           vec_add1 (rmt_locs, rloc);
15170           /* weight saved in rmt loc */
15171           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15172         }
15173       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15174                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15175         {
15176           rloc.is_ip4 = 0;
15177           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15178           rloc.weight = 0;
15179           vec_add1 (lcl_locs, rloc);
15180
15181           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15182           vec_add1 (rmt_locs, rloc);
15183           /* weight saved in rmt loc */
15184           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15185         }
15186       else if (unformat (input, "action %d", &action))
15187         {
15188           ;
15189         }
15190       else
15191         {
15192           clib_warning ("parse error '%U'", format_unformat_error, input);
15193           return -99;
15194         }
15195     }
15196
15197   if (!rmt_eid_set)
15198     {
15199       errmsg ("remote eid addresses not set");
15200       return -99;
15201     }
15202
15203   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15204     {
15205       errmsg ("eid types don't match");
15206       return -99;
15207     }
15208
15209   if (0 == rmt_locs && (u32) ~ 0 == action)
15210     {
15211       errmsg ("action not set for negative mapping");
15212       return -99;
15213     }
15214
15215   /* Construct the API message */
15216   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15217       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15218
15219   mp->is_add = is_add;
15220   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15221   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15222   mp->eid_type = rmt_eid->type;
15223   mp->dp_table = clib_host_to_net_u32 (dp_table);
15224   mp->vni = clib_host_to_net_u32 (vni);
15225   mp->rmt_len = rmt_eid->len;
15226   mp->lcl_len = lcl_eid->len;
15227   mp->action = action;
15228
15229   if (0 != rmt_locs && 0 != lcl_locs)
15230     {
15231       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15232       clib_memcpy (mp->locs, lcl_locs,
15233                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15234
15235       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15236       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15237                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15238     }
15239   vec_free (lcl_locs);
15240   vec_free (rmt_locs);
15241
15242   /* send it... */
15243   S (mp);
15244
15245   /* Wait for a reply... */
15246   W (ret);
15247   return ret;
15248 }
15249
15250 static int
15251 api_one_add_del_map_server (vat_main_t * vam)
15252 {
15253   unformat_input_t *input = vam->input;
15254   vl_api_one_add_del_map_server_t *mp;
15255   u8 is_add = 1;
15256   u8 ipv4_set = 0;
15257   u8 ipv6_set = 0;
15258   ip4_address_t ipv4;
15259   ip6_address_t ipv6;
15260   int ret;
15261
15262   /* Parse args required to build the message */
15263   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15264     {
15265       if (unformat (input, "del"))
15266         {
15267           is_add = 0;
15268         }
15269       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15270         {
15271           ipv4_set = 1;
15272         }
15273       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15274         {
15275           ipv6_set = 1;
15276         }
15277       else
15278         break;
15279     }
15280
15281   if (ipv4_set && ipv6_set)
15282     {
15283       errmsg ("both eid v4 and v6 addresses set");
15284       return -99;
15285     }
15286
15287   if (!ipv4_set && !ipv6_set)
15288     {
15289       errmsg ("eid addresses not set");
15290       return -99;
15291     }
15292
15293   /* Construct the API message */
15294   M (ONE_ADD_DEL_MAP_SERVER, mp);
15295
15296   mp->is_add = is_add;
15297   if (ipv6_set)
15298     {
15299       mp->is_ipv6 = 1;
15300       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15301     }
15302   else
15303     {
15304       mp->is_ipv6 = 0;
15305       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15306     }
15307
15308   /* send it... */
15309   S (mp);
15310
15311   /* Wait for a reply... */
15312   W (ret);
15313   return ret;
15314 }
15315
15316 #define api_lisp_add_del_map_server api_one_add_del_map_server
15317
15318 static int
15319 api_one_add_del_map_resolver (vat_main_t * vam)
15320 {
15321   unformat_input_t *input = vam->input;
15322   vl_api_one_add_del_map_resolver_t *mp;
15323   u8 is_add = 1;
15324   u8 ipv4_set = 0;
15325   u8 ipv6_set = 0;
15326   ip4_address_t ipv4;
15327   ip6_address_t ipv6;
15328   int ret;
15329
15330   /* Parse args required to build the message */
15331   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15332     {
15333       if (unformat (input, "del"))
15334         {
15335           is_add = 0;
15336         }
15337       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15338         {
15339           ipv4_set = 1;
15340         }
15341       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15342         {
15343           ipv6_set = 1;
15344         }
15345       else
15346         break;
15347     }
15348
15349   if (ipv4_set && ipv6_set)
15350     {
15351       errmsg ("both eid v4 and v6 addresses set");
15352       return -99;
15353     }
15354
15355   if (!ipv4_set && !ipv6_set)
15356     {
15357       errmsg ("eid addresses not set");
15358       return -99;
15359     }
15360
15361   /* Construct the API message */
15362   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
15363
15364   mp->is_add = is_add;
15365   if (ipv6_set)
15366     {
15367       mp->is_ipv6 = 1;
15368       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15369     }
15370   else
15371     {
15372       mp->is_ipv6 = 0;
15373       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15374     }
15375
15376   /* send it... */
15377   S (mp);
15378
15379   /* Wait for a reply... */
15380   W (ret);
15381   return ret;
15382 }
15383
15384 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
15385
15386 static int
15387 api_lisp_gpe_enable_disable (vat_main_t * vam)
15388 {
15389   unformat_input_t *input = vam->input;
15390   vl_api_gpe_enable_disable_t *mp;
15391   u8 is_set = 0;
15392   u8 is_en = 1;
15393   int ret;
15394
15395   /* Parse args required to build the message */
15396   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15397     {
15398       if (unformat (input, "enable"))
15399         {
15400           is_set = 1;
15401           is_en = 1;
15402         }
15403       else if (unformat (input, "disable"))
15404         {
15405           is_set = 1;
15406           is_en = 0;
15407         }
15408       else
15409         break;
15410     }
15411
15412   if (is_set == 0)
15413     {
15414       errmsg ("Value not set");
15415       return -99;
15416     }
15417
15418   /* Construct the API message */
15419   M (GPE_ENABLE_DISABLE, mp);
15420
15421   mp->is_en = is_en;
15422
15423   /* send it... */
15424   S (mp);
15425
15426   /* Wait for a reply... */
15427   W (ret);
15428   return ret;
15429 }
15430
15431 static int
15432 api_one_rloc_probe_enable_disable (vat_main_t * vam)
15433 {
15434   unformat_input_t *input = vam->input;
15435   vl_api_one_rloc_probe_enable_disable_t *mp;
15436   u8 is_set = 0;
15437   u8 is_en = 0;
15438   int ret;
15439
15440   /* Parse args required to build the message */
15441   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15442     {
15443       if (unformat (input, "enable"))
15444         {
15445           is_set = 1;
15446           is_en = 1;
15447         }
15448       else if (unformat (input, "disable"))
15449         is_set = 1;
15450       else
15451         break;
15452     }
15453
15454   if (!is_set)
15455     {
15456       errmsg ("Value not set");
15457       return -99;
15458     }
15459
15460   /* Construct the API message */
15461   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
15462
15463   mp->is_enabled = is_en;
15464
15465   /* send it... */
15466   S (mp);
15467
15468   /* Wait for a reply... */
15469   W (ret);
15470   return ret;
15471 }
15472
15473 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
15474
15475 static int
15476 api_one_map_register_enable_disable (vat_main_t * vam)
15477 {
15478   unformat_input_t *input = vam->input;
15479   vl_api_one_map_register_enable_disable_t *mp;
15480   u8 is_set = 0;
15481   u8 is_en = 0;
15482   int ret;
15483
15484   /* Parse args required to build the message */
15485   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15486     {
15487       if (unformat (input, "enable"))
15488         {
15489           is_set = 1;
15490           is_en = 1;
15491         }
15492       else if (unformat (input, "disable"))
15493         is_set = 1;
15494       else
15495         break;
15496     }
15497
15498   if (!is_set)
15499     {
15500       errmsg ("Value not set");
15501       return -99;
15502     }
15503
15504   /* Construct the API message */
15505   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
15506
15507   mp->is_enabled = is_en;
15508
15509   /* send it... */
15510   S (mp);
15511
15512   /* Wait for a reply... */
15513   W (ret);
15514   return ret;
15515 }
15516
15517 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
15518
15519 static int
15520 api_one_enable_disable (vat_main_t * vam)
15521 {
15522   unformat_input_t *input = vam->input;
15523   vl_api_one_enable_disable_t *mp;
15524   u8 is_set = 0;
15525   u8 is_en = 0;
15526   int ret;
15527
15528   /* Parse args required to build the message */
15529   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15530     {
15531       if (unformat (input, "enable"))
15532         {
15533           is_set = 1;
15534           is_en = 1;
15535         }
15536       else if (unformat (input, "disable"))
15537         {
15538           is_set = 1;
15539         }
15540       else
15541         break;
15542     }
15543
15544   if (!is_set)
15545     {
15546       errmsg ("Value not set");
15547       return -99;
15548     }
15549
15550   /* Construct the API message */
15551   M (ONE_ENABLE_DISABLE, mp);
15552
15553   mp->is_en = is_en;
15554
15555   /* send it... */
15556   S (mp);
15557
15558   /* Wait for a reply... */
15559   W (ret);
15560   return ret;
15561 }
15562
15563 #define api_lisp_enable_disable api_one_enable_disable
15564
15565 static int
15566 api_show_one_map_register_state (vat_main_t * vam)
15567 {
15568   vl_api_show_one_map_register_state_t *mp;
15569   int ret;
15570
15571   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15572
15573   /* send */
15574   S (mp);
15575
15576   /* wait for reply */
15577   W (ret);
15578   return ret;
15579 }
15580
15581 #define api_show_lisp_map_register_state api_show_one_map_register_state
15582
15583 static int
15584 api_show_one_rloc_probe_state (vat_main_t * vam)
15585 {
15586   vl_api_show_one_rloc_probe_state_t *mp;
15587   int ret;
15588
15589   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15590
15591   /* send */
15592   S (mp);
15593
15594   /* wait for reply */
15595   W (ret);
15596   return ret;
15597 }
15598
15599 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15600
15601 static int
15602 api_one_add_del_ndp_entry (vat_main_t * vam)
15603 {
15604   vl_api_one_add_del_ndp_entry_t *mp;
15605   unformat_input_t *input = vam->input;
15606   u8 is_add = 1;
15607   u8 mac_set = 0;
15608   u8 bd_set = 0;
15609   u8 ip_set = 0;
15610   u8 mac[6] = { 0, };
15611   u8 ip6[16] = { 0, };
15612   u32 bd = ~0;
15613   int ret;
15614
15615   /* Parse args required to build the message */
15616   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15617     {
15618       if (unformat (input, "del"))
15619         is_add = 0;
15620       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15621         mac_set = 1;
15622       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
15623         ip_set = 1;
15624       else if (unformat (input, "bd %d", &bd))
15625         bd_set = 1;
15626       else
15627         {
15628           errmsg ("parse error '%U'", format_unformat_error, input);
15629           return -99;
15630         }
15631     }
15632
15633   if (!bd_set || !ip_set || (!mac_set && is_add))
15634     {
15635       errmsg ("Missing BD, IP or MAC!");
15636       return -99;
15637     }
15638
15639   M (ONE_ADD_DEL_NDP_ENTRY, mp);
15640   mp->is_add = is_add;
15641   clib_memcpy (mp->mac, mac, 6);
15642   mp->bd = clib_host_to_net_u32 (bd);
15643   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
15644
15645   /* send */
15646   S (mp);
15647
15648   /* wait for reply */
15649   W (ret);
15650   return ret;
15651 }
15652
15653 static int
15654 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15655 {
15656   vl_api_one_add_del_l2_arp_entry_t *mp;
15657   unformat_input_t *input = vam->input;
15658   u8 is_add = 1;
15659   u8 mac_set = 0;
15660   u8 bd_set = 0;
15661   u8 ip_set = 0;
15662   u8 mac[6] = { 0, };
15663   u32 ip4 = 0, bd = ~0;
15664   int ret;
15665
15666   /* Parse args required to build the message */
15667   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15668     {
15669       if (unformat (input, "del"))
15670         is_add = 0;
15671       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15672         mac_set = 1;
15673       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15674         ip_set = 1;
15675       else if (unformat (input, "bd %d", &bd))
15676         bd_set = 1;
15677       else
15678         {
15679           errmsg ("parse error '%U'", format_unformat_error, input);
15680           return -99;
15681         }
15682     }
15683
15684   if (!bd_set || !ip_set || (!mac_set && is_add))
15685     {
15686       errmsg ("Missing BD, IP or MAC!");
15687       return -99;
15688     }
15689
15690   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15691   mp->is_add = is_add;
15692   clib_memcpy (mp->mac, mac, 6);
15693   mp->bd = clib_host_to_net_u32 (bd);
15694   mp->ip4 = ip4;
15695
15696   /* send */
15697   S (mp);
15698
15699   /* wait for reply */
15700   W (ret);
15701   return ret;
15702 }
15703
15704 static int
15705 api_one_ndp_bd_get (vat_main_t * vam)
15706 {
15707   vl_api_one_ndp_bd_get_t *mp;
15708   int ret;
15709
15710   M (ONE_NDP_BD_GET, mp);
15711
15712   /* send */
15713   S (mp);
15714
15715   /* wait for reply */
15716   W (ret);
15717   return ret;
15718 }
15719
15720 static int
15721 api_one_ndp_entries_get (vat_main_t * vam)
15722 {
15723   vl_api_one_ndp_entries_get_t *mp;
15724   unformat_input_t *input = vam->input;
15725   u8 bd_set = 0;
15726   u32 bd = ~0;
15727   int ret;
15728
15729   /* Parse args required to build the message */
15730   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15731     {
15732       if (unformat (input, "bd %d", &bd))
15733         bd_set = 1;
15734       else
15735         {
15736           errmsg ("parse error '%U'", format_unformat_error, input);
15737           return -99;
15738         }
15739     }
15740
15741   if (!bd_set)
15742     {
15743       errmsg ("Expected bridge domain!");
15744       return -99;
15745     }
15746
15747   M (ONE_NDP_ENTRIES_GET, mp);
15748   mp->bd = clib_host_to_net_u32 (bd);
15749
15750   /* send */
15751   S (mp);
15752
15753   /* wait for reply */
15754   W (ret);
15755   return ret;
15756 }
15757
15758 static int
15759 api_one_l2_arp_bd_get (vat_main_t * vam)
15760 {
15761   vl_api_one_l2_arp_bd_get_t *mp;
15762   int ret;
15763
15764   M (ONE_L2_ARP_BD_GET, mp);
15765
15766   /* send */
15767   S (mp);
15768
15769   /* wait for reply */
15770   W (ret);
15771   return ret;
15772 }
15773
15774 static int
15775 api_one_l2_arp_entries_get (vat_main_t * vam)
15776 {
15777   vl_api_one_l2_arp_entries_get_t *mp;
15778   unformat_input_t *input = vam->input;
15779   u8 bd_set = 0;
15780   u32 bd = ~0;
15781   int ret;
15782
15783   /* Parse args required to build the message */
15784   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15785     {
15786       if (unformat (input, "bd %d", &bd))
15787         bd_set = 1;
15788       else
15789         {
15790           errmsg ("parse error '%U'", format_unformat_error, input);
15791           return -99;
15792         }
15793     }
15794
15795   if (!bd_set)
15796     {
15797       errmsg ("Expected bridge domain!");
15798       return -99;
15799     }
15800
15801   M (ONE_L2_ARP_ENTRIES_GET, mp);
15802   mp->bd = clib_host_to_net_u32 (bd);
15803
15804   /* send */
15805   S (mp);
15806
15807   /* wait for reply */
15808   W (ret);
15809   return ret;
15810 }
15811
15812 static int
15813 api_one_stats_enable_disable (vat_main_t * vam)
15814 {
15815   vl_api_one_stats_enable_disable_t *mp;
15816   unformat_input_t *input = vam->input;
15817   u8 is_set = 0;
15818   u8 is_en = 0;
15819   int ret;
15820
15821   /* Parse args required to build the message */
15822   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15823     {
15824       if (unformat (input, "enable"))
15825         {
15826           is_set = 1;
15827           is_en = 1;
15828         }
15829       else if (unformat (input, "disable"))
15830         {
15831           is_set = 1;
15832         }
15833       else
15834         break;
15835     }
15836
15837   if (!is_set)
15838     {
15839       errmsg ("Value not set");
15840       return -99;
15841     }
15842
15843   M (ONE_STATS_ENABLE_DISABLE, mp);
15844   mp->is_en = is_en;
15845
15846   /* send */
15847   S (mp);
15848
15849   /* wait for reply */
15850   W (ret);
15851   return ret;
15852 }
15853
15854 static int
15855 api_show_one_stats_enable_disable (vat_main_t * vam)
15856 {
15857   vl_api_show_one_stats_enable_disable_t *mp;
15858   int ret;
15859
15860   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
15861
15862   /* send */
15863   S (mp);
15864
15865   /* wait for reply */
15866   W (ret);
15867   return ret;
15868 }
15869
15870 static int
15871 api_show_one_map_request_mode (vat_main_t * vam)
15872 {
15873   vl_api_show_one_map_request_mode_t *mp;
15874   int ret;
15875
15876   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
15877
15878   /* send */
15879   S (mp);
15880
15881   /* wait for reply */
15882   W (ret);
15883   return ret;
15884 }
15885
15886 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
15887
15888 static int
15889 api_one_map_request_mode (vat_main_t * vam)
15890 {
15891   unformat_input_t *input = vam->input;
15892   vl_api_one_map_request_mode_t *mp;
15893   u8 mode = 0;
15894   int ret;
15895
15896   /* Parse args required to build the message */
15897   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15898     {
15899       if (unformat (input, "dst-only"))
15900         mode = 0;
15901       else if (unformat (input, "src-dst"))
15902         mode = 1;
15903       else
15904         {
15905           errmsg ("parse error '%U'", format_unformat_error, input);
15906           return -99;
15907         }
15908     }
15909
15910   M (ONE_MAP_REQUEST_MODE, mp);
15911
15912   mp->mode = mode;
15913
15914   /* send */
15915   S (mp);
15916
15917   /* wait for reply */
15918   W (ret);
15919   return ret;
15920 }
15921
15922 #define api_lisp_map_request_mode api_one_map_request_mode
15923
15924 /**
15925  * Enable/disable ONE proxy ITR.
15926  *
15927  * @param vam vpp API test context
15928  * @return return code
15929  */
15930 static int
15931 api_one_pitr_set_locator_set (vat_main_t * vam)
15932 {
15933   u8 ls_name_set = 0;
15934   unformat_input_t *input = vam->input;
15935   vl_api_one_pitr_set_locator_set_t *mp;
15936   u8 is_add = 1;
15937   u8 *ls_name = 0;
15938   int ret;
15939
15940   /* Parse args required to build the message */
15941   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15942     {
15943       if (unformat (input, "del"))
15944         is_add = 0;
15945       else if (unformat (input, "locator-set %s", &ls_name))
15946         ls_name_set = 1;
15947       else
15948         {
15949           errmsg ("parse error '%U'", format_unformat_error, input);
15950           return -99;
15951         }
15952     }
15953
15954   if (!ls_name_set)
15955     {
15956       errmsg ("locator-set name not set!");
15957       return -99;
15958     }
15959
15960   M (ONE_PITR_SET_LOCATOR_SET, mp);
15961
15962   mp->is_add = is_add;
15963   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15964   vec_free (ls_name);
15965
15966   /* send */
15967   S (mp);
15968
15969   /* wait for reply */
15970   W (ret);
15971   return ret;
15972 }
15973
15974 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
15975
15976 static int
15977 api_one_nsh_set_locator_set (vat_main_t * vam)
15978 {
15979   u8 ls_name_set = 0;
15980   unformat_input_t *input = vam->input;
15981   vl_api_one_nsh_set_locator_set_t *mp;
15982   u8 is_add = 1;
15983   u8 *ls_name = 0;
15984   int ret;
15985
15986   /* Parse args required to build the message */
15987   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15988     {
15989       if (unformat (input, "del"))
15990         is_add = 0;
15991       else if (unformat (input, "ls %s", &ls_name))
15992         ls_name_set = 1;
15993       else
15994         {
15995           errmsg ("parse error '%U'", format_unformat_error, input);
15996           return -99;
15997         }
15998     }
15999
16000   if (!ls_name_set && is_add)
16001     {
16002       errmsg ("locator-set name not set!");
16003       return -99;
16004     }
16005
16006   M (ONE_NSH_SET_LOCATOR_SET, mp);
16007
16008   mp->is_add = is_add;
16009   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16010   vec_free (ls_name);
16011
16012   /* send */
16013   S (mp);
16014
16015   /* wait for reply */
16016   W (ret);
16017   return ret;
16018 }
16019
16020 static int
16021 api_show_one_pitr (vat_main_t * vam)
16022 {
16023   vl_api_show_one_pitr_t *mp;
16024   int ret;
16025
16026   if (!vam->json_output)
16027     {
16028       print (vam->ofp, "%=20s", "lisp status:");
16029     }
16030
16031   M (SHOW_ONE_PITR, mp);
16032   /* send it... */
16033   S (mp);
16034
16035   /* Wait for a reply... */
16036   W (ret);
16037   return ret;
16038 }
16039
16040 #define api_show_lisp_pitr api_show_one_pitr
16041
16042 static int
16043 api_one_use_petr (vat_main_t * vam)
16044 {
16045   unformat_input_t *input = vam->input;
16046   vl_api_one_use_petr_t *mp;
16047   u8 is_add = 0;
16048   ip_address_t ip;
16049   int ret;
16050
16051   memset (&ip, 0, sizeof (ip));
16052
16053   /* Parse args required to build the message */
16054   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16055     {
16056       if (unformat (input, "disable"))
16057         is_add = 0;
16058       else
16059         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16060         {
16061           is_add = 1;
16062           ip_addr_version (&ip) = IP4;
16063         }
16064       else
16065         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16066         {
16067           is_add = 1;
16068           ip_addr_version (&ip) = IP6;
16069         }
16070       else
16071         {
16072           errmsg ("parse error '%U'", format_unformat_error, input);
16073           return -99;
16074         }
16075     }
16076
16077   M (ONE_USE_PETR, mp);
16078
16079   mp->is_add = is_add;
16080   if (is_add)
16081     {
16082       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
16083       if (mp->is_ip4)
16084         clib_memcpy (mp->address, &ip, 4);
16085       else
16086         clib_memcpy (mp->address, &ip, 16);
16087     }
16088
16089   /* send */
16090   S (mp);
16091
16092   /* wait for reply */
16093   W (ret);
16094   return ret;
16095 }
16096
16097 #define api_lisp_use_petr api_one_use_petr
16098
16099 static int
16100 api_show_one_nsh_mapping (vat_main_t * vam)
16101 {
16102   vl_api_show_one_use_petr_t *mp;
16103   int ret;
16104
16105   if (!vam->json_output)
16106     {
16107       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16108     }
16109
16110   M (SHOW_ONE_NSH_MAPPING, mp);
16111   /* send it... */
16112   S (mp);
16113
16114   /* Wait for a reply... */
16115   W (ret);
16116   return ret;
16117 }
16118
16119 static int
16120 api_show_one_use_petr (vat_main_t * vam)
16121 {
16122   vl_api_show_one_use_petr_t *mp;
16123   int ret;
16124
16125   if (!vam->json_output)
16126     {
16127       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16128     }
16129
16130   M (SHOW_ONE_USE_PETR, mp);
16131   /* send it... */
16132   S (mp);
16133
16134   /* Wait for a reply... */
16135   W (ret);
16136   return ret;
16137 }
16138
16139 #define api_show_lisp_use_petr api_show_one_use_petr
16140
16141 /**
16142  * Add/delete mapping between vni and vrf
16143  */
16144 static int
16145 api_one_eid_table_add_del_map (vat_main_t * vam)
16146 {
16147   unformat_input_t *input = vam->input;
16148   vl_api_one_eid_table_add_del_map_t *mp;
16149   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
16150   u32 vni, vrf, bd_index;
16151   int ret;
16152
16153   /* Parse args required to build the message */
16154   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16155     {
16156       if (unformat (input, "del"))
16157         is_add = 0;
16158       else if (unformat (input, "vrf %d", &vrf))
16159         vrf_set = 1;
16160       else if (unformat (input, "bd_index %d", &bd_index))
16161         bd_index_set = 1;
16162       else if (unformat (input, "vni %d", &vni))
16163         vni_set = 1;
16164       else
16165         break;
16166     }
16167
16168   if (!vni_set || (!vrf_set && !bd_index_set))
16169     {
16170       errmsg ("missing arguments!");
16171       return -99;
16172     }
16173
16174   if (vrf_set && bd_index_set)
16175     {
16176       errmsg ("error: both vrf and bd entered!");
16177       return -99;
16178     }
16179
16180   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
16181
16182   mp->is_add = is_add;
16183   mp->vni = htonl (vni);
16184   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
16185   mp->is_l2 = bd_index_set;
16186
16187   /* send */
16188   S (mp);
16189
16190   /* wait for reply */
16191   W (ret);
16192   return ret;
16193 }
16194
16195 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
16196
16197 uword
16198 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
16199 {
16200   u32 *action = va_arg (*args, u32 *);
16201   u8 *s = 0;
16202
16203   if (unformat (input, "%s", &s))
16204     {
16205       if (!strcmp ((char *) s, "no-action"))
16206         action[0] = 0;
16207       else if (!strcmp ((char *) s, "natively-forward"))
16208         action[0] = 1;
16209       else if (!strcmp ((char *) s, "send-map-request"))
16210         action[0] = 2;
16211       else if (!strcmp ((char *) s, "drop"))
16212         action[0] = 3;
16213       else
16214         {
16215           clib_warning ("invalid action: '%s'", s);
16216           action[0] = 3;
16217         }
16218     }
16219   else
16220     return 0;
16221
16222   vec_free (s);
16223   return 1;
16224 }
16225
16226 /**
16227  * Add/del remote mapping to/from ONE control plane
16228  *
16229  * @param vam vpp API test context
16230  * @return return code
16231  */
16232 static int
16233 api_one_add_del_remote_mapping (vat_main_t * vam)
16234 {
16235   unformat_input_t *input = vam->input;
16236   vl_api_one_add_del_remote_mapping_t *mp;
16237   u32 vni = 0;
16238   lisp_eid_vat_t _eid, *eid = &_eid;
16239   lisp_eid_vat_t _seid, *seid = &_seid;
16240   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
16241   u32 action = ~0, p, w, data_len;
16242   ip4_address_t rloc4;
16243   ip6_address_t rloc6;
16244   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
16245   int ret;
16246
16247   memset (&rloc, 0, sizeof (rloc));
16248
16249   /* Parse args required to build the message */
16250   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16251     {
16252       if (unformat (input, "del-all"))
16253         {
16254           del_all = 1;
16255         }
16256       else if (unformat (input, "del"))
16257         {
16258           is_add = 0;
16259         }
16260       else if (unformat (input, "add"))
16261         {
16262           is_add = 1;
16263         }
16264       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16265         {
16266           eid_set = 1;
16267         }
16268       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
16269         {
16270           seid_set = 1;
16271         }
16272       else if (unformat (input, "vni %d", &vni))
16273         {
16274           ;
16275         }
16276       else if (unformat (input, "p %d w %d", &p, &w))
16277         {
16278           if (!curr_rloc)
16279             {
16280               errmsg ("No RLOC configured for setting priority/weight!");
16281               return -99;
16282             }
16283           curr_rloc->priority = p;
16284           curr_rloc->weight = w;
16285         }
16286       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
16287         {
16288           rloc.is_ip4 = 1;
16289           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
16290           vec_add1 (rlocs, rloc);
16291           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16292         }
16293       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
16294         {
16295           rloc.is_ip4 = 0;
16296           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
16297           vec_add1 (rlocs, rloc);
16298           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16299         }
16300       else if (unformat (input, "action %U",
16301                          unformat_negative_mapping_action, &action))
16302         {
16303           ;
16304         }
16305       else
16306         {
16307           clib_warning ("parse error '%U'", format_unformat_error, input);
16308           return -99;
16309         }
16310     }
16311
16312   if (0 == eid_set)
16313     {
16314       errmsg ("missing params!");
16315       return -99;
16316     }
16317
16318   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
16319     {
16320       errmsg ("no action set for negative map-reply!");
16321       return -99;
16322     }
16323
16324   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
16325
16326   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
16327   mp->is_add = is_add;
16328   mp->vni = htonl (vni);
16329   mp->action = (u8) action;
16330   mp->is_src_dst = seid_set;
16331   mp->eid_len = eid->len;
16332   mp->seid_len = seid->len;
16333   mp->del_all = del_all;
16334   mp->eid_type = eid->type;
16335   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16336   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
16337
16338   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
16339   clib_memcpy (mp->rlocs, rlocs, data_len);
16340   vec_free (rlocs);
16341
16342   /* send it... */
16343   S (mp);
16344
16345   /* Wait for a reply... */
16346   W (ret);
16347   return ret;
16348 }
16349
16350 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
16351
16352 /**
16353  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
16354  * forwarding entries in data-plane accordingly.
16355  *
16356  * @param vam vpp API test context
16357  * @return return code
16358  */
16359 static int
16360 api_one_add_del_adjacency (vat_main_t * vam)
16361 {
16362   unformat_input_t *input = vam->input;
16363   vl_api_one_add_del_adjacency_t *mp;
16364   u32 vni = 0;
16365   ip4_address_t leid4, reid4;
16366   ip6_address_t leid6, reid6;
16367   u8 reid_mac[6] = { 0 };
16368   u8 leid_mac[6] = { 0 };
16369   u8 reid_type, leid_type;
16370   u32 leid_len = 0, reid_len = 0, len;
16371   u8 is_add = 1;
16372   int ret;
16373
16374   leid_type = reid_type = (u8) ~ 0;
16375
16376   /* Parse args required to build the message */
16377   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16378     {
16379       if (unformat (input, "del"))
16380         {
16381           is_add = 0;
16382         }
16383       else if (unformat (input, "add"))
16384         {
16385           is_add = 1;
16386         }
16387       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
16388                          &reid4, &len))
16389         {
16390           reid_type = 0;        /* ipv4 */
16391           reid_len = len;
16392         }
16393       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
16394                          &reid6, &len))
16395         {
16396           reid_type = 1;        /* ipv6 */
16397           reid_len = len;
16398         }
16399       else if (unformat (input, "reid %U", unformat_ethernet_address,
16400                          reid_mac))
16401         {
16402           reid_type = 2;        /* mac */
16403         }
16404       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
16405                          &leid4, &len))
16406         {
16407           leid_type = 0;        /* ipv4 */
16408           leid_len = len;
16409         }
16410       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
16411                          &leid6, &len))
16412         {
16413           leid_type = 1;        /* ipv6 */
16414           leid_len = len;
16415         }
16416       else if (unformat (input, "leid %U", unformat_ethernet_address,
16417                          leid_mac))
16418         {
16419           leid_type = 2;        /* mac */
16420         }
16421       else if (unformat (input, "vni %d", &vni))
16422         {
16423           ;
16424         }
16425       else
16426         {
16427           errmsg ("parse error '%U'", format_unformat_error, input);
16428           return -99;
16429         }
16430     }
16431
16432   if ((u8) ~ 0 == reid_type)
16433     {
16434       errmsg ("missing params!");
16435       return -99;
16436     }
16437
16438   if (leid_type != reid_type)
16439     {
16440       errmsg ("remote and local EIDs are of different types!");
16441       return -99;
16442     }
16443
16444   M (ONE_ADD_DEL_ADJACENCY, mp);
16445   mp->is_add = is_add;
16446   mp->vni = htonl (vni);
16447   mp->leid_len = leid_len;
16448   mp->reid_len = reid_len;
16449   mp->eid_type = reid_type;
16450
16451   switch (mp->eid_type)
16452     {
16453     case 0:
16454       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
16455       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
16456       break;
16457     case 1:
16458       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
16459       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
16460       break;
16461     case 2:
16462       clib_memcpy (mp->leid, leid_mac, 6);
16463       clib_memcpy (mp->reid, reid_mac, 6);
16464       break;
16465     default:
16466       errmsg ("unknown EID type %d!", mp->eid_type);
16467       return 0;
16468     }
16469
16470   /* send it... */
16471   S (mp);
16472
16473   /* Wait for a reply... */
16474   W (ret);
16475   return ret;
16476 }
16477
16478 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16479
16480 uword
16481 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16482 {
16483   u32 *mode = va_arg (*args, u32 *);
16484
16485   if (unformat (input, "lisp"))
16486     *mode = 0;
16487   else if (unformat (input, "vxlan"))
16488     *mode = 1;
16489   else
16490     return 0;
16491
16492   return 1;
16493 }
16494
16495 static int
16496 api_gpe_get_encap_mode (vat_main_t * vam)
16497 {
16498   vl_api_gpe_get_encap_mode_t *mp;
16499   int ret;
16500
16501   /* Construct the API message */
16502   M (GPE_GET_ENCAP_MODE, mp);
16503
16504   /* send it... */
16505   S (mp);
16506
16507   /* Wait for a reply... */
16508   W (ret);
16509   return ret;
16510 }
16511
16512 static int
16513 api_gpe_set_encap_mode (vat_main_t * vam)
16514 {
16515   unformat_input_t *input = vam->input;
16516   vl_api_gpe_set_encap_mode_t *mp;
16517   int ret;
16518   u32 mode = 0;
16519
16520   /* Parse args required to build the message */
16521   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16522     {
16523       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16524         ;
16525       else
16526         break;
16527     }
16528
16529   /* Construct the API message */
16530   M (GPE_SET_ENCAP_MODE, mp);
16531
16532   mp->mode = mode;
16533
16534   /* send it... */
16535   S (mp);
16536
16537   /* Wait for a reply... */
16538   W (ret);
16539   return ret;
16540 }
16541
16542 static int
16543 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16544 {
16545   unformat_input_t *input = vam->input;
16546   vl_api_gpe_add_del_iface_t *mp;
16547   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16548   u32 dp_table = 0, vni = 0;
16549   int ret;
16550
16551   /* Parse args required to build the message */
16552   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16553     {
16554       if (unformat (input, "up"))
16555         {
16556           action_set = 1;
16557           is_add = 1;
16558         }
16559       else if (unformat (input, "down"))
16560         {
16561           action_set = 1;
16562           is_add = 0;
16563         }
16564       else if (unformat (input, "table_id %d", &dp_table))
16565         {
16566           dp_table_set = 1;
16567         }
16568       else if (unformat (input, "bd_id %d", &dp_table))
16569         {
16570           dp_table_set = 1;
16571           is_l2 = 1;
16572         }
16573       else if (unformat (input, "vni %d", &vni))
16574         {
16575           vni_set = 1;
16576         }
16577       else
16578         break;
16579     }
16580
16581   if (action_set == 0)
16582     {
16583       errmsg ("Action not set");
16584       return -99;
16585     }
16586   if (dp_table_set == 0 || vni_set == 0)
16587     {
16588       errmsg ("vni and dp_table must be set");
16589       return -99;
16590     }
16591
16592   /* Construct the API message */
16593   M (GPE_ADD_DEL_IFACE, mp);
16594
16595   mp->is_add = is_add;
16596   mp->dp_table = clib_host_to_net_u32 (dp_table);
16597   mp->is_l2 = is_l2;
16598   mp->vni = clib_host_to_net_u32 (vni);
16599
16600   /* send it... */
16601   S (mp);
16602
16603   /* Wait for a reply... */
16604   W (ret);
16605   return ret;
16606 }
16607
16608 static int
16609 api_one_map_register_fallback_threshold (vat_main_t * vam)
16610 {
16611   unformat_input_t *input = vam->input;
16612   vl_api_one_map_register_fallback_threshold_t *mp;
16613   u32 value = 0;
16614   u8 is_set = 0;
16615   int ret;
16616
16617   /* Parse args required to build the message */
16618   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16619     {
16620       if (unformat (input, "%u", &value))
16621         is_set = 1;
16622       else
16623         {
16624           clib_warning ("parse error '%U'", format_unformat_error, input);
16625           return -99;
16626         }
16627     }
16628
16629   if (!is_set)
16630     {
16631       errmsg ("fallback threshold value is missing!");
16632       return -99;
16633     }
16634
16635   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16636   mp->value = clib_host_to_net_u32 (value);
16637
16638   /* send it... */
16639   S (mp);
16640
16641   /* Wait for a reply... */
16642   W (ret);
16643   return ret;
16644 }
16645
16646 static int
16647 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16648 {
16649   vl_api_show_one_map_register_fallback_threshold_t *mp;
16650   int ret;
16651
16652   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16653
16654   /* send it... */
16655   S (mp);
16656
16657   /* Wait for a reply... */
16658   W (ret);
16659   return ret;
16660 }
16661
16662 uword
16663 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
16664 {
16665   u32 *proto = va_arg (*args, u32 *);
16666
16667   if (unformat (input, "udp"))
16668     *proto = 1;
16669   else if (unformat (input, "api"))
16670     *proto = 2;
16671   else
16672     return 0;
16673
16674   return 1;
16675 }
16676
16677 static int
16678 api_one_set_transport_protocol (vat_main_t * vam)
16679 {
16680   unformat_input_t *input = vam->input;
16681   vl_api_one_set_transport_protocol_t *mp;
16682   u8 is_set = 0;
16683   u32 protocol = 0;
16684   int ret;
16685
16686   /* Parse args required to build the message */
16687   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16688     {
16689       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
16690         is_set = 1;
16691       else
16692         {
16693           clib_warning ("parse error '%U'", format_unformat_error, input);
16694           return -99;
16695         }
16696     }
16697
16698   if (!is_set)
16699     {
16700       errmsg ("Transport protocol missing!");
16701       return -99;
16702     }
16703
16704   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
16705   mp->protocol = (u8) protocol;
16706
16707   /* send it... */
16708   S (mp);
16709
16710   /* Wait for a reply... */
16711   W (ret);
16712   return ret;
16713 }
16714
16715 static int
16716 api_one_get_transport_protocol (vat_main_t * vam)
16717 {
16718   vl_api_one_get_transport_protocol_t *mp;
16719   int ret;
16720
16721   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
16722
16723   /* send it... */
16724   S (mp);
16725
16726   /* Wait for a reply... */
16727   W (ret);
16728   return ret;
16729 }
16730
16731 static int
16732 api_one_map_register_set_ttl (vat_main_t * vam)
16733 {
16734   unformat_input_t *input = vam->input;
16735   vl_api_one_map_register_set_ttl_t *mp;
16736   u32 ttl = 0;
16737   u8 is_set = 0;
16738   int ret;
16739
16740   /* Parse args required to build the message */
16741   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16742     {
16743       if (unformat (input, "%u", &ttl))
16744         is_set = 1;
16745       else
16746         {
16747           clib_warning ("parse error '%U'", format_unformat_error, input);
16748           return -99;
16749         }
16750     }
16751
16752   if (!is_set)
16753     {
16754       errmsg ("TTL value missing!");
16755       return -99;
16756     }
16757
16758   M (ONE_MAP_REGISTER_SET_TTL, mp);
16759   mp->ttl = clib_host_to_net_u32 (ttl);
16760
16761   /* send it... */
16762   S (mp);
16763
16764   /* Wait for a reply... */
16765   W (ret);
16766   return ret;
16767 }
16768
16769 static int
16770 api_show_one_map_register_ttl (vat_main_t * vam)
16771 {
16772   vl_api_show_one_map_register_ttl_t *mp;
16773   int ret;
16774
16775   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
16776
16777   /* send it... */
16778   S (mp);
16779
16780   /* Wait for a reply... */
16781   W (ret);
16782   return ret;
16783 }
16784
16785 /**
16786  * Add/del map request itr rlocs from ONE control plane and updates
16787  *
16788  * @param vam vpp API test context
16789  * @return return code
16790  */
16791 static int
16792 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
16793 {
16794   unformat_input_t *input = vam->input;
16795   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
16796   u8 *locator_set_name = 0;
16797   u8 locator_set_name_set = 0;
16798   u8 is_add = 1;
16799   int ret;
16800
16801   /* Parse args required to build the message */
16802   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16803     {
16804       if (unformat (input, "del"))
16805         {
16806           is_add = 0;
16807         }
16808       else if (unformat (input, "%_%v%_", &locator_set_name))
16809         {
16810           locator_set_name_set = 1;
16811         }
16812       else
16813         {
16814           clib_warning ("parse error '%U'", format_unformat_error, input);
16815           return -99;
16816         }
16817     }
16818
16819   if (is_add && !locator_set_name_set)
16820     {
16821       errmsg ("itr-rloc is not set!");
16822       return -99;
16823     }
16824
16825   if (is_add && vec_len (locator_set_name) > 64)
16826     {
16827       errmsg ("itr-rloc locator-set name too long");
16828       vec_free (locator_set_name);
16829       return -99;
16830     }
16831
16832   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
16833   mp->is_add = is_add;
16834   if (is_add)
16835     {
16836       clib_memcpy (mp->locator_set_name, locator_set_name,
16837                    vec_len (locator_set_name));
16838     }
16839   else
16840     {
16841       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
16842     }
16843   vec_free (locator_set_name);
16844
16845   /* send it... */
16846   S (mp);
16847
16848   /* Wait for a reply... */
16849   W (ret);
16850   return ret;
16851 }
16852
16853 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
16854
16855 static int
16856 api_one_locator_dump (vat_main_t * vam)
16857 {
16858   unformat_input_t *input = vam->input;
16859   vl_api_one_locator_dump_t *mp;
16860   vl_api_control_ping_t *mp_ping;
16861   u8 is_index_set = 0, is_name_set = 0;
16862   u8 *ls_name = 0;
16863   u32 ls_index = ~0;
16864   int ret;
16865
16866   /* Parse args required to build the message */
16867   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16868     {
16869       if (unformat (input, "ls_name %_%v%_", &ls_name))
16870         {
16871           is_name_set = 1;
16872         }
16873       else if (unformat (input, "ls_index %d", &ls_index))
16874         {
16875           is_index_set = 1;
16876         }
16877       else
16878         {
16879           errmsg ("parse error '%U'", format_unformat_error, input);
16880           return -99;
16881         }
16882     }
16883
16884   if (!is_index_set && !is_name_set)
16885     {
16886       errmsg ("error: expected one of index or name!");
16887       return -99;
16888     }
16889
16890   if (is_index_set && is_name_set)
16891     {
16892       errmsg ("error: only one param expected!");
16893       return -99;
16894     }
16895
16896   if (vec_len (ls_name) > 62)
16897     {
16898       errmsg ("error: locator set name too long!");
16899       return -99;
16900     }
16901
16902   if (!vam->json_output)
16903     {
16904       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
16905     }
16906
16907   M (ONE_LOCATOR_DUMP, mp);
16908   mp->is_index_set = is_index_set;
16909
16910   if (is_index_set)
16911     mp->ls_index = clib_host_to_net_u32 (ls_index);
16912   else
16913     {
16914       vec_add1 (ls_name, 0);
16915       strncpy ((char *) mp->ls_name, (char *) ls_name,
16916                sizeof (mp->ls_name) - 1);
16917     }
16918
16919   /* send it... */
16920   S (mp);
16921
16922   /* Use a control ping for synchronization */
16923   M (CONTROL_PING, mp_ping);
16924   S (mp_ping);
16925
16926   /* Wait for a reply... */
16927   W (ret);
16928   return ret;
16929 }
16930
16931 #define api_lisp_locator_dump api_one_locator_dump
16932
16933 static int
16934 api_one_locator_set_dump (vat_main_t * vam)
16935 {
16936   vl_api_one_locator_set_dump_t *mp;
16937   vl_api_control_ping_t *mp_ping;
16938   unformat_input_t *input = vam->input;
16939   u8 filter = 0;
16940   int ret;
16941
16942   /* Parse args required to build the message */
16943   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16944     {
16945       if (unformat (input, "local"))
16946         {
16947           filter = 1;
16948         }
16949       else if (unformat (input, "remote"))
16950         {
16951           filter = 2;
16952         }
16953       else
16954         {
16955           errmsg ("parse error '%U'", format_unformat_error, input);
16956           return -99;
16957         }
16958     }
16959
16960   if (!vam->json_output)
16961     {
16962       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
16963     }
16964
16965   M (ONE_LOCATOR_SET_DUMP, mp);
16966
16967   mp->filter = filter;
16968
16969   /* send it... */
16970   S (mp);
16971
16972   /* Use a control ping for synchronization */
16973   M (CONTROL_PING, mp_ping);
16974   S (mp_ping);
16975
16976   /* Wait for a reply... */
16977   W (ret);
16978   return ret;
16979 }
16980
16981 #define api_lisp_locator_set_dump api_one_locator_set_dump
16982
16983 static int
16984 api_one_eid_table_map_dump (vat_main_t * vam)
16985 {
16986   u8 is_l2 = 0;
16987   u8 mode_set = 0;
16988   unformat_input_t *input = vam->input;
16989   vl_api_one_eid_table_map_dump_t *mp;
16990   vl_api_control_ping_t *mp_ping;
16991   int ret;
16992
16993   /* Parse args required to build the message */
16994   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16995     {
16996       if (unformat (input, "l2"))
16997         {
16998           is_l2 = 1;
16999           mode_set = 1;
17000         }
17001       else if (unformat (input, "l3"))
17002         {
17003           is_l2 = 0;
17004           mode_set = 1;
17005         }
17006       else
17007         {
17008           errmsg ("parse error '%U'", format_unformat_error, input);
17009           return -99;
17010         }
17011     }
17012
17013   if (!mode_set)
17014     {
17015       errmsg ("expected one of 'l2' or 'l3' parameter!");
17016       return -99;
17017     }
17018
17019   if (!vam->json_output)
17020     {
17021       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17022     }
17023
17024   M (ONE_EID_TABLE_MAP_DUMP, mp);
17025   mp->is_l2 = is_l2;
17026
17027   /* send it... */
17028   S (mp);
17029
17030   /* Use a control ping for synchronization */
17031   M (CONTROL_PING, mp_ping);
17032   S (mp_ping);
17033
17034   /* Wait for a reply... */
17035   W (ret);
17036   return ret;
17037 }
17038
17039 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17040
17041 static int
17042 api_one_eid_table_vni_dump (vat_main_t * vam)
17043 {
17044   vl_api_one_eid_table_vni_dump_t *mp;
17045   vl_api_control_ping_t *mp_ping;
17046   int ret;
17047
17048   if (!vam->json_output)
17049     {
17050       print (vam->ofp, "VNI");
17051     }
17052
17053   M (ONE_EID_TABLE_VNI_DUMP, mp);
17054
17055   /* send it... */
17056   S (mp);
17057
17058   /* Use a control ping for synchronization */
17059   M (CONTROL_PING, mp_ping);
17060   S (mp_ping);
17061
17062   /* Wait for a reply... */
17063   W (ret);
17064   return ret;
17065 }
17066
17067 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17068
17069 static int
17070 api_one_eid_table_dump (vat_main_t * vam)
17071 {
17072   unformat_input_t *i = vam->input;
17073   vl_api_one_eid_table_dump_t *mp;
17074   vl_api_control_ping_t *mp_ping;
17075   struct in_addr ip4;
17076   struct in6_addr ip6;
17077   u8 mac[6];
17078   u8 eid_type = ~0, eid_set = 0;
17079   u32 prefix_length = ~0, t, vni = 0;
17080   u8 filter = 0;
17081   int ret;
17082   lisp_nsh_api_t nsh;
17083
17084   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17085     {
17086       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17087         {
17088           eid_set = 1;
17089           eid_type = 0;
17090           prefix_length = t;
17091         }
17092       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17093         {
17094           eid_set = 1;
17095           eid_type = 1;
17096           prefix_length = t;
17097         }
17098       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17099         {
17100           eid_set = 1;
17101           eid_type = 2;
17102         }
17103       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17104         {
17105           eid_set = 1;
17106           eid_type = 3;
17107         }
17108       else if (unformat (i, "vni %d", &t))
17109         {
17110           vni = t;
17111         }
17112       else if (unformat (i, "local"))
17113         {
17114           filter = 1;
17115         }
17116       else if (unformat (i, "remote"))
17117         {
17118           filter = 2;
17119         }
17120       else
17121         {
17122           errmsg ("parse error '%U'", format_unformat_error, i);
17123           return -99;
17124         }
17125     }
17126
17127   if (!vam->json_output)
17128     {
17129       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17130              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17131     }
17132
17133   M (ONE_EID_TABLE_DUMP, mp);
17134
17135   mp->filter = filter;
17136   if (eid_set)
17137     {
17138       mp->eid_set = 1;
17139       mp->vni = htonl (vni);
17140       mp->eid_type = eid_type;
17141       switch (eid_type)
17142         {
17143         case 0:
17144           mp->prefix_length = prefix_length;
17145           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17146           break;
17147         case 1:
17148           mp->prefix_length = prefix_length;
17149           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
17150           break;
17151         case 2:
17152           clib_memcpy (mp->eid, mac, sizeof (mac));
17153           break;
17154         case 3:
17155           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
17156           break;
17157         default:
17158           errmsg ("unknown EID type %d!", eid_type);
17159           return -99;
17160         }
17161     }
17162
17163   /* send it... */
17164   S (mp);
17165
17166   /* Use a control ping for synchronization */
17167   M (CONTROL_PING, mp_ping);
17168   S (mp_ping);
17169
17170   /* Wait for a reply... */
17171   W (ret);
17172   return ret;
17173 }
17174
17175 #define api_lisp_eid_table_dump api_one_eid_table_dump
17176
17177 static int
17178 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
17179 {
17180   unformat_input_t *i = vam->input;
17181   vl_api_gpe_fwd_entries_get_t *mp;
17182   u8 vni_set = 0;
17183   u32 vni = ~0;
17184   int ret;
17185
17186   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17187     {
17188       if (unformat (i, "vni %d", &vni))
17189         {
17190           vni_set = 1;
17191         }
17192       else
17193         {
17194           errmsg ("parse error '%U'", format_unformat_error, i);
17195           return -99;
17196         }
17197     }
17198
17199   if (!vni_set)
17200     {
17201       errmsg ("vni not set!");
17202       return -99;
17203     }
17204
17205   if (!vam->json_output)
17206     {
17207       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
17208              "leid", "reid");
17209     }
17210
17211   M (GPE_FWD_ENTRIES_GET, mp);
17212   mp->vni = clib_host_to_net_u32 (vni);
17213
17214   /* send it... */
17215   S (mp);
17216
17217   /* Wait for a reply... */
17218   W (ret);
17219   return ret;
17220 }
17221
17222 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
17223 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
17224 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
17225 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
17226 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
17227 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
17228 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
17229 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
17230
17231 static int
17232 api_one_adjacencies_get (vat_main_t * vam)
17233 {
17234   unformat_input_t *i = vam->input;
17235   vl_api_one_adjacencies_get_t *mp;
17236   u8 vni_set = 0;
17237   u32 vni = ~0;
17238   int ret;
17239
17240   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17241     {
17242       if (unformat (i, "vni %d", &vni))
17243         {
17244           vni_set = 1;
17245         }
17246       else
17247         {
17248           errmsg ("parse error '%U'", format_unformat_error, i);
17249           return -99;
17250         }
17251     }
17252
17253   if (!vni_set)
17254     {
17255       errmsg ("vni not set!");
17256       return -99;
17257     }
17258
17259   if (!vam->json_output)
17260     {
17261       print (vam->ofp, "%s %40s", "leid", "reid");
17262     }
17263
17264   M (ONE_ADJACENCIES_GET, mp);
17265   mp->vni = clib_host_to_net_u32 (vni);
17266
17267   /* send it... */
17268   S (mp);
17269
17270   /* Wait for a reply... */
17271   W (ret);
17272   return ret;
17273 }
17274
17275 #define api_lisp_adjacencies_get api_one_adjacencies_get
17276
17277 static int
17278 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
17279 {
17280   unformat_input_t *i = vam->input;
17281   vl_api_gpe_native_fwd_rpaths_get_t *mp;
17282   int ret;
17283   u8 ip_family_set = 0, is_ip4 = 1;
17284
17285   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17286     {
17287       if (unformat (i, "ip4"))
17288         {
17289           ip_family_set = 1;
17290           is_ip4 = 1;
17291         }
17292       else if (unformat (i, "ip6"))
17293         {
17294           ip_family_set = 1;
17295           is_ip4 = 0;
17296         }
17297       else
17298         {
17299           errmsg ("parse error '%U'", format_unformat_error, i);
17300           return -99;
17301         }
17302     }
17303
17304   if (!ip_family_set)
17305     {
17306       errmsg ("ip family not set!");
17307       return -99;
17308     }
17309
17310   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
17311   mp->is_ip4 = is_ip4;
17312
17313   /* send it... */
17314   S (mp);
17315
17316   /* Wait for a reply... */
17317   W (ret);
17318   return ret;
17319 }
17320
17321 static int
17322 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
17323 {
17324   vl_api_gpe_fwd_entry_vnis_get_t *mp;
17325   int ret;
17326
17327   if (!vam->json_output)
17328     {
17329       print (vam->ofp, "VNIs");
17330     }
17331
17332   M (GPE_FWD_ENTRY_VNIS_GET, mp);
17333
17334   /* send it... */
17335   S (mp);
17336
17337   /* Wait for a reply... */
17338   W (ret);
17339   return ret;
17340 }
17341
17342 static int
17343 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
17344 {
17345   unformat_input_t *i = vam->input;
17346   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
17347   int ret = 0;
17348   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
17349   struct in_addr ip4;
17350   struct in6_addr ip6;
17351   u32 table_id = 0, nh_sw_if_index = ~0;
17352
17353   memset (&ip4, 0, sizeof (ip4));
17354   memset (&ip6, 0, sizeof (ip6));
17355
17356   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17357     {
17358       if (unformat (i, "del"))
17359         is_add = 0;
17360       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
17361                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17362         {
17363           ip_set = 1;
17364           is_ip4 = 1;
17365         }
17366       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
17367                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17368         {
17369           ip_set = 1;
17370           is_ip4 = 0;
17371         }
17372       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
17373         {
17374           ip_set = 1;
17375           is_ip4 = 1;
17376           nh_sw_if_index = ~0;
17377         }
17378       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
17379         {
17380           ip_set = 1;
17381           is_ip4 = 0;
17382           nh_sw_if_index = ~0;
17383         }
17384       else if (unformat (i, "table %d", &table_id))
17385         ;
17386       else
17387         {
17388           errmsg ("parse error '%U'", format_unformat_error, i);
17389           return -99;
17390         }
17391     }
17392
17393   if (!ip_set)
17394     {
17395       errmsg ("nh addr not set!");
17396       return -99;
17397     }
17398
17399   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
17400   mp->is_add = is_add;
17401   mp->table_id = clib_host_to_net_u32 (table_id);
17402   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
17403   mp->is_ip4 = is_ip4;
17404   if (is_ip4)
17405     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
17406   else
17407     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
17408
17409   /* send it... */
17410   S (mp);
17411
17412   /* Wait for a reply... */
17413   W (ret);
17414   return ret;
17415 }
17416
17417 static int
17418 api_one_map_server_dump (vat_main_t * vam)
17419 {
17420   vl_api_one_map_server_dump_t *mp;
17421   vl_api_control_ping_t *mp_ping;
17422   int ret;
17423
17424   if (!vam->json_output)
17425     {
17426       print (vam->ofp, "%=20s", "Map server");
17427     }
17428
17429   M (ONE_MAP_SERVER_DUMP, mp);
17430   /* send it... */
17431   S (mp);
17432
17433   /* Use a control ping for synchronization */
17434   M (CONTROL_PING, mp_ping);
17435   S (mp_ping);
17436
17437   /* Wait for a reply... */
17438   W (ret);
17439   return ret;
17440 }
17441
17442 #define api_lisp_map_server_dump api_one_map_server_dump
17443
17444 static int
17445 api_one_map_resolver_dump (vat_main_t * vam)
17446 {
17447   vl_api_one_map_resolver_dump_t *mp;
17448   vl_api_control_ping_t *mp_ping;
17449   int ret;
17450
17451   if (!vam->json_output)
17452     {
17453       print (vam->ofp, "%=20s", "Map resolver");
17454     }
17455
17456   M (ONE_MAP_RESOLVER_DUMP, mp);
17457   /* send it... */
17458   S (mp);
17459
17460   /* Use a control ping for synchronization */
17461   M (CONTROL_PING, mp_ping);
17462   S (mp_ping);
17463
17464   /* Wait for a reply... */
17465   W (ret);
17466   return ret;
17467 }
17468
17469 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
17470
17471 static int
17472 api_one_stats_flush (vat_main_t * vam)
17473 {
17474   vl_api_one_stats_flush_t *mp;
17475   int ret = 0;
17476
17477   M (ONE_STATS_FLUSH, mp);
17478   S (mp);
17479   W (ret);
17480   return ret;
17481 }
17482
17483 static int
17484 api_one_stats_dump (vat_main_t * vam)
17485 {
17486   vl_api_one_stats_dump_t *mp;
17487   vl_api_control_ping_t *mp_ping;
17488   int ret;
17489
17490   M (ONE_STATS_DUMP, mp);
17491   /* send it... */
17492   S (mp);
17493
17494   /* Use a control ping for synchronization */
17495   M (CONTROL_PING, mp_ping);
17496   S (mp_ping);
17497
17498   /* Wait for a reply... */
17499   W (ret);
17500   return ret;
17501 }
17502
17503 static int
17504 api_show_one_status (vat_main_t * vam)
17505 {
17506   vl_api_show_one_status_t *mp;
17507   int ret;
17508
17509   if (!vam->json_output)
17510     {
17511       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17512     }
17513
17514   M (SHOW_ONE_STATUS, mp);
17515   /* send it... */
17516   S (mp);
17517   /* Wait for a reply... */
17518   W (ret);
17519   return ret;
17520 }
17521
17522 #define api_show_lisp_status api_show_one_status
17523
17524 static int
17525 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17526 {
17527   vl_api_gpe_fwd_entry_path_dump_t *mp;
17528   vl_api_control_ping_t *mp_ping;
17529   unformat_input_t *i = vam->input;
17530   u32 fwd_entry_index = ~0;
17531   int ret;
17532
17533   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17534     {
17535       if (unformat (i, "index %d", &fwd_entry_index))
17536         ;
17537       else
17538         break;
17539     }
17540
17541   if (~0 == fwd_entry_index)
17542     {
17543       errmsg ("no index specified!");
17544       return -99;
17545     }
17546
17547   if (!vam->json_output)
17548     {
17549       print (vam->ofp, "first line");
17550     }
17551
17552   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17553
17554   /* send it... */
17555   S (mp);
17556   /* Use a control ping for synchronization */
17557   M (CONTROL_PING, mp_ping);
17558   S (mp_ping);
17559
17560   /* Wait for a reply... */
17561   W (ret);
17562   return ret;
17563 }
17564
17565 static int
17566 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17567 {
17568   vl_api_one_get_map_request_itr_rlocs_t *mp;
17569   int ret;
17570
17571   if (!vam->json_output)
17572     {
17573       print (vam->ofp, "%=20s", "itr-rlocs:");
17574     }
17575
17576   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17577   /* send it... */
17578   S (mp);
17579   /* Wait for a reply... */
17580   W (ret);
17581   return ret;
17582 }
17583
17584 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17585
17586 static int
17587 api_af_packet_create (vat_main_t * vam)
17588 {
17589   unformat_input_t *i = vam->input;
17590   vl_api_af_packet_create_t *mp;
17591   u8 *host_if_name = 0;
17592   u8 hw_addr[6];
17593   u8 random_hw_addr = 1;
17594   int ret;
17595
17596   memset (hw_addr, 0, sizeof (hw_addr));
17597
17598   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17599     {
17600       if (unformat (i, "name %s", &host_if_name))
17601         vec_add1 (host_if_name, 0);
17602       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17603         random_hw_addr = 0;
17604       else
17605         break;
17606     }
17607
17608   if (!vec_len (host_if_name))
17609     {
17610       errmsg ("host-interface name must be specified");
17611       return -99;
17612     }
17613
17614   if (vec_len (host_if_name) > 64)
17615     {
17616       errmsg ("host-interface name too long");
17617       return -99;
17618     }
17619
17620   M (AF_PACKET_CREATE, mp);
17621
17622   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17623   clib_memcpy (mp->hw_addr, hw_addr, 6);
17624   mp->use_random_hw_addr = random_hw_addr;
17625   vec_free (host_if_name);
17626
17627   S (mp);
17628
17629   /* *INDENT-OFF* */
17630   W2 (ret,
17631       ({
17632         if (ret == 0)
17633           fprintf (vam->ofp ? vam->ofp : stderr,
17634                    " new sw_if_index = %d\n", vam->sw_if_index);
17635       }));
17636   /* *INDENT-ON* */
17637   return ret;
17638 }
17639
17640 static int
17641 api_af_packet_delete (vat_main_t * vam)
17642 {
17643   unformat_input_t *i = vam->input;
17644   vl_api_af_packet_delete_t *mp;
17645   u8 *host_if_name = 0;
17646   int ret;
17647
17648   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17649     {
17650       if (unformat (i, "name %s", &host_if_name))
17651         vec_add1 (host_if_name, 0);
17652       else
17653         break;
17654     }
17655
17656   if (!vec_len (host_if_name))
17657     {
17658       errmsg ("host-interface name must be specified");
17659       return -99;
17660     }
17661
17662   if (vec_len (host_if_name) > 64)
17663     {
17664       errmsg ("host-interface name too long");
17665       return -99;
17666     }
17667
17668   M (AF_PACKET_DELETE, mp);
17669
17670   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17671   vec_free (host_if_name);
17672
17673   S (mp);
17674   W (ret);
17675   return ret;
17676 }
17677
17678 static int
17679 api_policer_add_del (vat_main_t * vam)
17680 {
17681   unformat_input_t *i = vam->input;
17682   vl_api_policer_add_del_t *mp;
17683   u8 is_add = 1;
17684   u8 *name = 0;
17685   u32 cir = 0;
17686   u32 eir = 0;
17687   u64 cb = 0;
17688   u64 eb = 0;
17689   u8 rate_type = 0;
17690   u8 round_type = 0;
17691   u8 type = 0;
17692   u8 color_aware = 0;
17693   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17694   int ret;
17695
17696   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17697   conform_action.dscp = 0;
17698   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17699   exceed_action.dscp = 0;
17700   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17701   violate_action.dscp = 0;
17702
17703   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17704     {
17705       if (unformat (i, "del"))
17706         is_add = 0;
17707       else if (unformat (i, "name %s", &name))
17708         vec_add1 (name, 0);
17709       else if (unformat (i, "cir %u", &cir))
17710         ;
17711       else if (unformat (i, "eir %u", &eir))
17712         ;
17713       else if (unformat (i, "cb %u", &cb))
17714         ;
17715       else if (unformat (i, "eb %u", &eb))
17716         ;
17717       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17718                          &rate_type))
17719         ;
17720       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17721                          &round_type))
17722         ;
17723       else if (unformat (i, "type %U", unformat_policer_type, &type))
17724         ;
17725       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17726                          &conform_action))
17727         ;
17728       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17729                          &exceed_action))
17730         ;
17731       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17732                          &violate_action))
17733         ;
17734       else if (unformat (i, "color-aware"))
17735         color_aware = 1;
17736       else
17737         break;
17738     }
17739
17740   if (!vec_len (name))
17741     {
17742       errmsg ("policer name must be specified");
17743       return -99;
17744     }
17745
17746   if (vec_len (name) > 64)
17747     {
17748       errmsg ("policer name too long");
17749       return -99;
17750     }
17751
17752   M (POLICER_ADD_DEL, mp);
17753
17754   clib_memcpy (mp->name, name, vec_len (name));
17755   vec_free (name);
17756   mp->is_add = is_add;
17757   mp->cir = cir;
17758   mp->eir = eir;
17759   mp->cb = cb;
17760   mp->eb = eb;
17761   mp->rate_type = rate_type;
17762   mp->round_type = round_type;
17763   mp->type = type;
17764   mp->conform_action_type = conform_action.action_type;
17765   mp->conform_dscp = conform_action.dscp;
17766   mp->exceed_action_type = exceed_action.action_type;
17767   mp->exceed_dscp = exceed_action.dscp;
17768   mp->violate_action_type = violate_action.action_type;
17769   mp->violate_dscp = violate_action.dscp;
17770   mp->color_aware = color_aware;
17771
17772   S (mp);
17773   W (ret);
17774   return ret;
17775 }
17776
17777 static int
17778 api_policer_dump (vat_main_t * vam)
17779 {
17780   unformat_input_t *i = vam->input;
17781   vl_api_policer_dump_t *mp;
17782   vl_api_control_ping_t *mp_ping;
17783   u8 *match_name = 0;
17784   u8 match_name_valid = 0;
17785   int ret;
17786
17787   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17788     {
17789       if (unformat (i, "name %s", &match_name))
17790         {
17791           vec_add1 (match_name, 0);
17792           match_name_valid = 1;
17793         }
17794       else
17795         break;
17796     }
17797
17798   M (POLICER_DUMP, mp);
17799   mp->match_name_valid = match_name_valid;
17800   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
17801   vec_free (match_name);
17802   /* send it... */
17803   S (mp);
17804
17805   /* Use a control ping for synchronization */
17806   M (CONTROL_PING, mp_ping);
17807   S (mp_ping);
17808
17809   /* Wait for a reply... */
17810   W (ret);
17811   return ret;
17812 }
17813
17814 static int
17815 api_policer_classify_set_interface (vat_main_t * vam)
17816 {
17817   unformat_input_t *i = vam->input;
17818   vl_api_policer_classify_set_interface_t *mp;
17819   u32 sw_if_index;
17820   int sw_if_index_set;
17821   u32 ip4_table_index = ~0;
17822   u32 ip6_table_index = ~0;
17823   u32 l2_table_index = ~0;
17824   u8 is_add = 1;
17825   int ret;
17826
17827   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17828     {
17829       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17830         sw_if_index_set = 1;
17831       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17832         sw_if_index_set = 1;
17833       else if (unformat (i, "del"))
17834         is_add = 0;
17835       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17836         ;
17837       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17838         ;
17839       else if (unformat (i, "l2-table %d", &l2_table_index))
17840         ;
17841       else
17842         {
17843           clib_warning ("parse error '%U'", format_unformat_error, i);
17844           return -99;
17845         }
17846     }
17847
17848   if (sw_if_index_set == 0)
17849     {
17850       errmsg ("missing interface name or sw_if_index");
17851       return -99;
17852     }
17853
17854   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
17855
17856   mp->sw_if_index = ntohl (sw_if_index);
17857   mp->ip4_table_index = ntohl (ip4_table_index);
17858   mp->ip6_table_index = ntohl (ip6_table_index);
17859   mp->l2_table_index = ntohl (l2_table_index);
17860   mp->is_add = is_add;
17861
17862   S (mp);
17863   W (ret);
17864   return ret;
17865 }
17866
17867 static int
17868 api_policer_classify_dump (vat_main_t * vam)
17869 {
17870   unformat_input_t *i = vam->input;
17871   vl_api_policer_classify_dump_t *mp;
17872   vl_api_control_ping_t *mp_ping;
17873   u8 type = POLICER_CLASSIFY_N_TABLES;
17874   int ret;
17875
17876   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
17877     ;
17878   else
17879     {
17880       errmsg ("classify table type must be specified");
17881       return -99;
17882     }
17883
17884   if (!vam->json_output)
17885     {
17886       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17887     }
17888
17889   M (POLICER_CLASSIFY_DUMP, mp);
17890   mp->type = type;
17891   /* send it... */
17892   S (mp);
17893
17894   /* Use a control ping for synchronization */
17895   M (CONTROL_PING, mp_ping);
17896   S (mp_ping);
17897
17898   /* Wait for a reply... */
17899   W (ret);
17900   return ret;
17901 }
17902
17903 static int
17904 api_netmap_create (vat_main_t * vam)
17905 {
17906   unformat_input_t *i = vam->input;
17907   vl_api_netmap_create_t *mp;
17908   u8 *if_name = 0;
17909   u8 hw_addr[6];
17910   u8 random_hw_addr = 1;
17911   u8 is_pipe = 0;
17912   u8 is_master = 0;
17913   int ret;
17914
17915   memset (hw_addr, 0, sizeof (hw_addr));
17916
17917   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17918     {
17919       if (unformat (i, "name %s", &if_name))
17920         vec_add1 (if_name, 0);
17921       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17922         random_hw_addr = 0;
17923       else if (unformat (i, "pipe"))
17924         is_pipe = 1;
17925       else if (unformat (i, "master"))
17926         is_master = 1;
17927       else if (unformat (i, "slave"))
17928         is_master = 0;
17929       else
17930         break;
17931     }
17932
17933   if (!vec_len (if_name))
17934     {
17935       errmsg ("interface name must be specified");
17936       return -99;
17937     }
17938
17939   if (vec_len (if_name) > 64)
17940     {
17941       errmsg ("interface name too long");
17942       return -99;
17943     }
17944
17945   M (NETMAP_CREATE, mp);
17946
17947   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
17948   clib_memcpy (mp->hw_addr, hw_addr, 6);
17949   mp->use_random_hw_addr = random_hw_addr;
17950   mp->is_pipe = is_pipe;
17951   mp->is_master = is_master;
17952   vec_free (if_name);
17953
17954   S (mp);
17955   W (ret);
17956   return ret;
17957 }
17958
17959 static int
17960 api_netmap_delete (vat_main_t * vam)
17961 {
17962   unformat_input_t *i = vam->input;
17963   vl_api_netmap_delete_t *mp;
17964   u8 *if_name = 0;
17965   int ret;
17966
17967   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17968     {
17969       if (unformat (i, "name %s", &if_name))
17970         vec_add1 (if_name, 0);
17971       else
17972         break;
17973     }
17974
17975   if (!vec_len (if_name))
17976     {
17977       errmsg ("interface name must be specified");
17978       return -99;
17979     }
17980
17981   if (vec_len (if_name) > 64)
17982     {
17983       errmsg ("interface name too long");
17984       return -99;
17985     }
17986
17987   M (NETMAP_DELETE, mp);
17988
17989   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
17990   vec_free (if_name);
17991
17992   S (mp);
17993   W (ret);
17994   return ret;
17995 }
17996
17997 static void
17998 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
17999 {
18000   if (fp->afi == IP46_TYPE_IP6)
18001     print (vam->ofp,
18002            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18003            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18004            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18005            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18006            format_ip6_address, fp->next_hop);
18007   else if (fp->afi == IP46_TYPE_IP4)
18008     print (vam->ofp,
18009            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18010            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18011            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18012            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18013            format_ip4_address, fp->next_hop);
18014 }
18015
18016 static void
18017 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18018                                  vl_api_fib_path2_t * fp)
18019 {
18020   struct in_addr ip4;
18021   struct in6_addr ip6;
18022
18023   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18024   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18025   vat_json_object_add_uint (node, "is_local", fp->is_local);
18026   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
18027   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
18028   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
18029   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
18030   if (fp->afi == IP46_TYPE_IP4)
18031     {
18032       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
18033       vat_json_object_add_ip4 (node, "next_hop", ip4);
18034     }
18035   else if (fp->afi == IP46_TYPE_IP6)
18036     {
18037       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
18038       vat_json_object_add_ip6 (node, "next_hop", ip6);
18039     }
18040 }
18041
18042 static void
18043 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18044 {
18045   vat_main_t *vam = &vat_main;
18046   int count = ntohl (mp->mt_count);
18047   vl_api_fib_path2_t *fp;
18048   i32 i;
18049
18050   print (vam->ofp, "[%d]: sw_if_index %d via:",
18051          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
18052   fp = mp->mt_paths;
18053   for (i = 0; i < count; i++)
18054     {
18055       vl_api_mpls_fib_path_print (vam, fp);
18056       fp++;
18057     }
18058
18059   print (vam->ofp, "");
18060 }
18061
18062 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18063 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18064
18065 static void
18066 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18067 {
18068   vat_main_t *vam = &vat_main;
18069   vat_json_node_t *node = NULL;
18070   int count = ntohl (mp->mt_count);
18071   vl_api_fib_path2_t *fp;
18072   i32 i;
18073
18074   if (VAT_JSON_ARRAY != vam->json_tree.type)
18075     {
18076       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18077       vat_json_init_array (&vam->json_tree);
18078     }
18079   node = vat_json_array_add (&vam->json_tree);
18080
18081   vat_json_init_object (node);
18082   vat_json_object_add_uint (node, "tunnel_index",
18083                             ntohl (mp->mt_tunnel_index));
18084   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
18085
18086   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
18087
18088   fp = mp->mt_paths;
18089   for (i = 0; i < count; i++)
18090     {
18091       vl_api_mpls_fib_path_json_print (node, fp);
18092       fp++;
18093     }
18094 }
18095
18096 static int
18097 api_mpls_tunnel_dump (vat_main_t * vam)
18098 {
18099   vl_api_mpls_tunnel_dump_t *mp;
18100   vl_api_control_ping_t *mp_ping;
18101   i32 index = -1;
18102   int ret;
18103
18104   /* Parse args required to build the message */
18105   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
18106     {
18107       if (!unformat (vam->input, "tunnel_index %d", &index))
18108         {
18109           index = -1;
18110           break;
18111         }
18112     }
18113
18114   print (vam->ofp, "  tunnel_index %d", index);
18115
18116   M (MPLS_TUNNEL_DUMP, mp);
18117   mp->tunnel_index = htonl (index);
18118   S (mp);
18119
18120   /* Use a control ping for synchronization */
18121   M (CONTROL_PING, mp_ping);
18122   S (mp_ping);
18123
18124   W (ret);
18125   return ret;
18126 }
18127
18128 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
18129 #define vl_api_mpls_fib_details_t_print vl_noop_handler
18130
18131
18132 static void
18133 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
18134 {
18135   vat_main_t *vam = &vat_main;
18136   int count = ntohl (mp->count);
18137   vl_api_fib_path2_t *fp;
18138   int i;
18139
18140   print (vam->ofp,
18141          "table-id %d, label %u, ess_bit %u",
18142          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
18143   fp = mp->path;
18144   for (i = 0; i < count; i++)
18145     {
18146       vl_api_mpls_fib_path_print (vam, fp);
18147       fp++;
18148     }
18149 }
18150
18151 static void vl_api_mpls_fib_details_t_handler_json
18152   (vl_api_mpls_fib_details_t * mp)
18153 {
18154   vat_main_t *vam = &vat_main;
18155   int count = ntohl (mp->count);
18156   vat_json_node_t *node = NULL;
18157   vl_api_fib_path2_t *fp;
18158   int i;
18159
18160   if (VAT_JSON_ARRAY != vam->json_tree.type)
18161     {
18162       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18163       vat_json_init_array (&vam->json_tree);
18164     }
18165   node = vat_json_array_add (&vam->json_tree);
18166
18167   vat_json_init_object (node);
18168   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
18169   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
18170   vat_json_object_add_uint (node, "label", ntohl (mp->label));
18171   vat_json_object_add_uint (node, "path_count", count);
18172   fp = mp->path;
18173   for (i = 0; i < count; i++)
18174     {
18175       vl_api_mpls_fib_path_json_print (node, fp);
18176       fp++;
18177     }
18178 }
18179
18180 static int
18181 api_mpls_fib_dump (vat_main_t * vam)
18182 {
18183   vl_api_mpls_fib_dump_t *mp;
18184   vl_api_control_ping_t *mp_ping;
18185   int ret;
18186
18187   M (MPLS_FIB_DUMP, mp);
18188   S (mp);
18189
18190   /* Use a control ping for synchronization */
18191   M (CONTROL_PING, mp_ping);
18192   S (mp_ping);
18193
18194   W (ret);
18195   return ret;
18196 }
18197
18198 #define vl_api_ip_fib_details_t_endian vl_noop_handler
18199 #define vl_api_ip_fib_details_t_print vl_noop_handler
18200
18201 static void
18202 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
18203 {
18204   vat_main_t *vam = &vat_main;
18205   int count = ntohl (mp->count);
18206   vl_api_fib_path_t *fp;
18207   int i;
18208
18209   print (vam->ofp,
18210          "table-id %d, prefix %U/%d",
18211          ntohl (mp->table_id), format_ip4_address, mp->address,
18212          mp->address_length);
18213   fp = mp->path;
18214   for (i = 0; i < count; i++)
18215     {
18216       if (fp->afi == IP46_TYPE_IP6)
18217         print (vam->ofp,
18218                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18219                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18220                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18221                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18222                format_ip6_address, fp->next_hop);
18223       else if (fp->afi == IP46_TYPE_IP4)
18224         print (vam->ofp,
18225                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18226                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18227                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18228                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18229                format_ip4_address, fp->next_hop);
18230       fp++;
18231     }
18232 }
18233
18234 static void vl_api_ip_fib_details_t_handler_json
18235   (vl_api_ip_fib_details_t * mp)
18236 {
18237   vat_main_t *vam = &vat_main;
18238   int count = ntohl (mp->count);
18239   vat_json_node_t *node = NULL;
18240   struct in_addr ip4;
18241   struct in6_addr ip6;
18242   vl_api_fib_path_t *fp;
18243   int i;
18244
18245   if (VAT_JSON_ARRAY != vam->json_tree.type)
18246     {
18247       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18248       vat_json_init_array (&vam->json_tree);
18249     }
18250   node = vat_json_array_add (&vam->json_tree);
18251
18252   vat_json_init_object (node);
18253   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
18254   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
18255   vat_json_object_add_ip4 (node, "prefix", ip4);
18256   vat_json_object_add_uint (node, "mask_length", mp->address_length);
18257   vat_json_object_add_uint (node, "path_count", count);
18258   fp = mp->path;
18259   for (i = 0; i < count; i++)
18260     {
18261       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18262       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18263       vat_json_object_add_uint (node, "is_local", fp->is_local);
18264       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
18265       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
18266       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
18267       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
18268       if (fp->afi == IP46_TYPE_IP4)
18269         {
18270           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
18271           vat_json_object_add_ip4 (node, "next_hop", ip4);
18272         }
18273       else if (fp->afi == IP46_TYPE_IP6)
18274         {
18275           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
18276           vat_json_object_add_ip6 (node, "next_hop", ip6);
18277         }
18278     }
18279 }
18280
18281 static int
18282 api_ip_fib_dump (vat_main_t * vam)
18283 {
18284   vl_api_ip_fib_dump_t *mp;
18285   vl_api_control_ping_t *mp_ping;
18286   int ret;
18287
18288   M (IP_FIB_DUMP, mp);
18289   S (mp);
18290
18291   /* Use a control ping for synchronization */
18292   M (CONTROL_PING, mp_ping);
18293   S (mp_ping);
18294
18295   W (ret);
18296   return ret;
18297 }
18298
18299 static int
18300 api_ip_mfib_dump (vat_main_t * vam)
18301 {
18302   vl_api_ip_mfib_dump_t *mp;
18303   vl_api_control_ping_t *mp_ping;
18304   int ret;
18305
18306   M (IP_MFIB_DUMP, mp);
18307   S (mp);
18308
18309   /* Use a control ping for synchronization */
18310   M (CONTROL_PING, mp_ping);
18311   S (mp_ping);
18312
18313   W (ret);
18314   return ret;
18315 }
18316
18317 static void vl_api_ip_neighbor_details_t_handler
18318   (vl_api_ip_neighbor_details_t * mp)
18319 {
18320   vat_main_t *vam = &vat_main;
18321
18322   print (vam->ofp, "%c %U %U",
18323          (mp->is_static) ? 'S' : 'D',
18324          format_ethernet_address, &mp->mac_address,
18325          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
18326          &mp->ip_address);
18327 }
18328
18329 static void vl_api_ip_neighbor_details_t_handler_json
18330   (vl_api_ip_neighbor_details_t * mp)
18331 {
18332
18333   vat_main_t *vam = &vat_main;
18334   vat_json_node_t *node;
18335   struct in_addr ip4;
18336   struct in6_addr ip6;
18337
18338   if (VAT_JSON_ARRAY != vam->json_tree.type)
18339     {
18340       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18341       vat_json_init_array (&vam->json_tree);
18342     }
18343   node = vat_json_array_add (&vam->json_tree);
18344
18345   vat_json_init_object (node);
18346   vat_json_object_add_string_copy (node, "flag",
18347                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
18348                                    "dynamic");
18349
18350   vat_json_object_add_string_copy (node, "link_layer",
18351                                    format (0, "%U", format_ethernet_address,
18352                                            &mp->mac_address));
18353
18354   if (mp->is_ipv6)
18355     {
18356       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
18357       vat_json_object_add_ip6 (node, "ip_address", ip6);
18358     }
18359   else
18360     {
18361       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
18362       vat_json_object_add_ip4 (node, "ip_address", ip4);
18363     }
18364 }
18365
18366 static int
18367 api_ip_neighbor_dump (vat_main_t * vam)
18368 {
18369   unformat_input_t *i = vam->input;
18370   vl_api_ip_neighbor_dump_t *mp;
18371   vl_api_control_ping_t *mp_ping;
18372   u8 is_ipv6 = 0;
18373   u32 sw_if_index = ~0;
18374   int ret;
18375
18376   /* Parse args required to build the message */
18377   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18378     {
18379       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18380         ;
18381       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18382         ;
18383       else if (unformat (i, "ip6"))
18384         is_ipv6 = 1;
18385       else
18386         break;
18387     }
18388
18389   if (sw_if_index == ~0)
18390     {
18391       errmsg ("missing interface name or sw_if_index");
18392       return -99;
18393     }
18394
18395   M (IP_NEIGHBOR_DUMP, mp);
18396   mp->is_ipv6 = (u8) is_ipv6;
18397   mp->sw_if_index = ntohl (sw_if_index);
18398   S (mp);
18399
18400   /* Use a control ping for synchronization */
18401   M (CONTROL_PING, mp_ping);
18402   S (mp_ping);
18403
18404   W (ret);
18405   return ret;
18406 }
18407
18408 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
18409 #define vl_api_ip6_fib_details_t_print vl_noop_handler
18410
18411 static void
18412 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
18413 {
18414   vat_main_t *vam = &vat_main;
18415   int count = ntohl (mp->count);
18416   vl_api_fib_path_t *fp;
18417   int i;
18418
18419   print (vam->ofp,
18420          "table-id %d, prefix %U/%d",
18421          ntohl (mp->table_id), format_ip6_address, mp->address,
18422          mp->address_length);
18423   fp = mp->path;
18424   for (i = 0; i < count; i++)
18425     {
18426       if (fp->afi == IP46_TYPE_IP6)
18427         print (vam->ofp,
18428                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18429                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18430                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18431                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18432                format_ip6_address, fp->next_hop);
18433       else if (fp->afi == IP46_TYPE_IP4)
18434         print (vam->ofp,
18435                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18436                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18437                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18438                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18439                format_ip4_address, fp->next_hop);
18440       fp++;
18441     }
18442 }
18443
18444 static void vl_api_ip6_fib_details_t_handler_json
18445   (vl_api_ip6_fib_details_t * mp)
18446 {
18447   vat_main_t *vam = &vat_main;
18448   int count = ntohl (mp->count);
18449   vat_json_node_t *node = NULL;
18450   struct in_addr ip4;
18451   struct in6_addr ip6;
18452   vl_api_fib_path_t *fp;
18453   int i;
18454
18455   if (VAT_JSON_ARRAY != vam->json_tree.type)
18456     {
18457       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18458       vat_json_init_array (&vam->json_tree);
18459     }
18460   node = vat_json_array_add (&vam->json_tree);
18461
18462   vat_json_init_object (node);
18463   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
18464   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
18465   vat_json_object_add_ip6 (node, "prefix", ip6);
18466   vat_json_object_add_uint (node, "mask_length", mp->address_length);
18467   vat_json_object_add_uint (node, "path_count", count);
18468   fp = mp->path;
18469   for (i = 0; i < count; i++)
18470     {
18471       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18472       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18473       vat_json_object_add_uint (node, "is_local", fp->is_local);
18474       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
18475       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
18476       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
18477       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
18478       if (fp->afi == IP46_TYPE_IP4)
18479         {
18480           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
18481           vat_json_object_add_ip4 (node, "next_hop", ip4);
18482         }
18483       else if (fp->afi == IP46_TYPE_IP6)
18484         {
18485           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
18486           vat_json_object_add_ip6 (node, "next_hop", ip6);
18487         }
18488     }
18489 }
18490
18491 static int
18492 api_ip6_fib_dump (vat_main_t * vam)
18493 {
18494   vl_api_ip6_fib_dump_t *mp;
18495   vl_api_control_ping_t *mp_ping;
18496   int ret;
18497
18498   M (IP6_FIB_DUMP, mp);
18499   S (mp);
18500
18501   /* Use a control ping for synchronization */
18502   M (CONTROL_PING, mp_ping);
18503   S (mp_ping);
18504
18505   W (ret);
18506   return ret;
18507 }
18508
18509 static int
18510 api_ip6_mfib_dump (vat_main_t * vam)
18511 {
18512   vl_api_ip6_mfib_dump_t *mp;
18513   vl_api_control_ping_t *mp_ping;
18514   int ret;
18515
18516   M (IP6_MFIB_DUMP, mp);
18517   S (mp);
18518
18519   /* Use a control ping for synchronization */
18520   M (CONTROL_PING, mp_ping);
18521   S (mp_ping);
18522
18523   W (ret);
18524   return ret;
18525 }
18526
18527 int
18528 api_classify_table_ids (vat_main_t * vam)
18529 {
18530   vl_api_classify_table_ids_t *mp;
18531   int ret;
18532
18533   /* Construct the API message */
18534   M (CLASSIFY_TABLE_IDS, mp);
18535   mp->context = 0;
18536
18537   S (mp);
18538   W (ret);
18539   return ret;
18540 }
18541
18542 int
18543 api_classify_table_by_interface (vat_main_t * vam)
18544 {
18545   unformat_input_t *input = vam->input;
18546   vl_api_classify_table_by_interface_t *mp;
18547
18548   u32 sw_if_index = ~0;
18549   int ret;
18550   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18551     {
18552       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18553         ;
18554       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18555         ;
18556       else
18557         break;
18558     }
18559   if (sw_if_index == ~0)
18560     {
18561       errmsg ("missing interface name or sw_if_index");
18562       return -99;
18563     }
18564
18565   /* Construct the API message */
18566   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18567   mp->context = 0;
18568   mp->sw_if_index = ntohl (sw_if_index);
18569
18570   S (mp);
18571   W (ret);
18572   return ret;
18573 }
18574
18575 int
18576 api_classify_table_info (vat_main_t * vam)
18577 {
18578   unformat_input_t *input = vam->input;
18579   vl_api_classify_table_info_t *mp;
18580
18581   u32 table_id = ~0;
18582   int ret;
18583   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18584     {
18585       if (unformat (input, "table_id %d", &table_id))
18586         ;
18587       else
18588         break;
18589     }
18590   if (table_id == ~0)
18591     {
18592       errmsg ("missing table id");
18593       return -99;
18594     }
18595
18596   /* Construct the API message */
18597   M (CLASSIFY_TABLE_INFO, mp);
18598   mp->context = 0;
18599   mp->table_id = ntohl (table_id);
18600
18601   S (mp);
18602   W (ret);
18603   return ret;
18604 }
18605
18606 int
18607 api_classify_session_dump (vat_main_t * vam)
18608 {
18609   unformat_input_t *input = vam->input;
18610   vl_api_classify_session_dump_t *mp;
18611   vl_api_control_ping_t *mp_ping;
18612
18613   u32 table_id = ~0;
18614   int ret;
18615   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18616     {
18617       if (unformat (input, "table_id %d", &table_id))
18618         ;
18619       else
18620         break;
18621     }
18622   if (table_id == ~0)
18623     {
18624       errmsg ("missing table id");
18625       return -99;
18626     }
18627
18628   /* Construct the API message */
18629   M (CLASSIFY_SESSION_DUMP, mp);
18630   mp->context = 0;
18631   mp->table_id = ntohl (table_id);
18632   S (mp);
18633
18634   /* Use a control ping for synchronization */
18635   M (CONTROL_PING, mp_ping);
18636   S (mp_ping);
18637
18638   W (ret);
18639   return ret;
18640 }
18641
18642 static void
18643 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
18644 {
18645   vat_main_t *vam = &vat_main;
18646
18647   print (vam->ofp, "collector_address %U, collector_port %d, "
18648          "src_address %U, vrf_id %d, path_mtu %u, "
18649          "template_interval %u, udp_checksum %d",
18650          format_ip4_address, mp->collector_address,
18651          ntohs (mp->collector_port),
18652          format_ip4_address, mp->src_address,
18653          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
18654          ntohl (mp->template_interval), mp->udp_checksum);
18655
18656   vam->retval = 0;
18657   vam->result_ready = 1;
18658 }
18659
18660 static void
18661   vl_api_ipfix_exporter_details_t_handler_json
18662   (vl_api_ipfix_exporter_details_t * mp)
18663 {
18664   vat_main_t *vam = &vat_main;
18665   vat_json_node_t node;
18666   struct in_addr collector_address;
18667   struct in_addr src_address;
18668
18669   vat_json_init_object (&node);
18670   clib_memcpy (&collector_address, &mp->collector_address,
18671                sizeof (collector_address));
18672   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
18673   vat_json_object_add_uint (&node, "collector_port",
18674                             ntohs (mp->collector_port));
18675   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
18676   vat_json_object_add_ip4 (&node, "src_address", src_address);
18677   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
18678   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
18679   vat_json_object_add_uint (&node, "template_interval",
18680                             ntohl (mp->template_interval));
18681   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
18682
18683   vat_json_print (vam->ofp, &node);
18684   vat_json_free (&node);
18685   vam->retval = 0;
18686   vam->result_ready = 1;
18687 }
18688
18689 int
18690 api_ipfix_exporter_dump (vat_main_t * vam)
18691 {
18692   vl_api_ipfix_exporter_dump_t *mp;
18693   int ret;
18694
18695   /* Construct the API message */
18696   M (IPFIX_EXPORTER_DUMP, mp);
18697   mp->context = 0;
18698
18699   S (mp);
18700   W (ret);
18701   return ret;
18702 }
18703
18704 static int
18705 api_ipfix_classify_stream_dump (vat_main_t * vam)
18706 {
18707   vl_api_ipfix_classify_stream_dump_t *mp;
18708   int ret;
18709
18710   /* Construct the API message */
18711   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
18712   mp->context = 0;
18713
18714   S (mp);
18715   W (ret);
18716   return ret;
18717   /* NOTREACHED */
18718   return 0;
18719 }
18720
18721 static void
18722   vl_api_ipfix_classify_stream_details_t_handler
18723   (vl_api_ipfix_classify_stream_details_t * mp)
18724 {
18725   vat_main_t *vam = &vat_main;
18726   print (vam->ofp, "domain_id %d, src_port %d",
18727          ntohl (mp->domain_id), ntohs (mp->src_port));
18728   vam->retval = 0;
18729   vam->result_ready = 1;
18730 }
18731
18732 static void
18733   vl_api_ipfix_classify_stream_details_t_handler_json
18734   (vl_api_ipfix_classify_stream_details_t * mp)
18735 {
18736   vat_main_t *vam = &vat_main;
18737   vat_json_node_t node;
18738
18739   vat_json_init_object (&node);
18740   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
18741   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
18742
18743   vat_json_print (vam->ofp, &node);
18744   vat_json_free (&node);
18745   vam->retval = 0;
18746   vam->result_ready = 1;
18747 }
18748
18749 static int
18750 api_ipfix_classify_table_dump (vat_main_t * vam)
18751 {
18752   vl_api_ipfix_classify_table_dump_t *mp;
18753   vl_api_control_ping_t *mp_ping;
18754   int ret;
18755
18756   if (!vam->json_output)
18757     {
18758       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
18759              "transport_protocol");
18760     }
18761
18762   /* Construct the API message */
18763   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
18764
18765   /* send it... */
18766   S (mp);
18767
18768   /* Use a control ping for synchronization */
18769   M (CONTROL_PING, mp_ping);
18770   S (mp_ping);
18771
18772   W (ret);
18773   return ret;
18774 }
18775
18776 static void
18777   vl_api_ipfix_classify_table_details_t_handler
18778   (vl_api_ipfix_classify_table_details_t * mp)
18779 {
18780   vat_main_t *vam = &vat_main;
18781   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
18782          mp->transport_protocol);
18783 }
18784
18785 static void
18786   vl_api_ipfix_classify_table_details_t_handler_json
18787   (vl_api_ipfix_classify_table_details_t * mp)
18788 {
18789   vat_json_node_t *node = NULL;
18790   vat_main_t *vam = &vat_main;
18791
18792   if (VAT_JSON_ARRAY != vam->json_tree.type)
18793     {
18794       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18795       vat_json_init_array (&vam->json_tree);
18796     }
18797
18798   node = vat_json_array_add (&vam->json_tree);
18799   vat_json_init_object (node);
18800
18801   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
18802   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
18803   vat_json_object_add_uint (node, "transport_protocol",
18804                             mp->transport_protocol);
18805 }
18806
18807 static int
18808 api_sw_interface_span_enable_disable (vat_main_t * vam)
18809 {
18810   unformat_input_t *i = vam->input;
18811   vl_api_sw_interface_span_enable_disable_t *mp;
18812   u32 src_sw_if_index = ~0;
18813   u32 dst_sw_if_index = ~0;
18814   u8 state = 3;
18815   int ret;
18816   u8 is_l2 = 0;
18817
18818   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18819     {
18820       if (unformat
18821           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
18822         ;
18823       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
18824         ;
18825       else
18826         if (unformat
18827             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
18828         ;
18829       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
18830         ;
18831       else if (unformat (i, "disable"))
18832         state = 0;
18833       else if (unformat (i, "rx"))
18834         state = 1;
18835       else if (unformat (i, "tx"))
18836         state = 2;
18837       else if (unformat (i, "both"))
18838         state = 3;
18839       else if (unformat (i, "l2"))
18840         is_l2 = 1;
18841       else
18842         break;
18843     }
18844
18845   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
18846
18847   mp->sw_if_index_from = htonl (src_sw_if_index);
18848   mp->sw_if_index_to = htonl (dst_sw_if_index);
18849   mp->state = state;
18850   mp->is_l2 = is_l2;
18851
18852   S (mp);
18853   W (ret);
18854   return ret;
18855 }
18856
18857 static void
18858 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
18859                                             * mp)
18860 {
18861   vat_main_t *vam = &vat_main;
18862   u8 *sw_if_from_name = 0;
18863   u8 *sw_if_to_name = 0;
18864   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18865   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18866   char *states[] = { "none", "rx", "tx", "both" };
18867   hash_pair_t *p;
18868
18869   /* *INDENT-OFF* */
18870   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18871   ({
18872     if ((u32) p->value[0] == sw_if_index_from)
18873       {
18874         sw_if_from_name = (u8 *)(p->key);
18875         if (sw_if_to_name)
18876           break;
18877       }
18878     if ((u32) p->value[0] == sw_if_index_to)
18879       {
18880         sw_if_to_name = (u8 *)(p->key);
18881         if (sw_if_from_name)
18882           break;
18883       }
18884   }));
18885   /* *INDENT-ON* */
18886   print (vam->ofp, "%20s => %20s (%s)",
18887          sw_if_from_name, sw_if_to_name, states[mp->state]);
18888 }
18889
18890 static void
18891   vl_api_sw_interface_span_details_t_handler_json
18892   (vl_api_sw_interface_span_details_t * mp)
18893 {
18894   vat_main_t *vam = &vat_main;
18895   vat_json_node_t *node = NULL;
18896   u8 *sw_if_from_name = 0;
18897   u8 *sw_if_to_name = 0;
18898   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18899   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18900   hash_pair_t *p;
18901
18902   /* *INDENT-OFF* */
18903   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18904   ({
18905     if ((u32) p->value[0] == sw_if_index_from)
18906       {
18907         sw_if_from_name = (u8 *)(p->key);
18908         if (sw_if_to_name)
18909           break;
18910       }
18911     if ((u32) p->value[0] == sw_if_index_to)
18912       {
18913         sw_if_to_name = (u8 *)(p->key);
18914         if (sw_if_from_name)
18915           break;
18916       }
18917   }));
18918   /* *INDENT-ON* */
18919
18920   if (VAT_JSON_ARRAY != vam->json_tree.type)
18921     {
18922       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18923       vat_json_init_array (&vam->json_tree);
18924     }
18925   node = vat_json_array_add (&vam->json_tree);
18926
18927   vat_json_init_object (node);
18928   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
18929   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
18930   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
18931   if (0 != sw_if_to_name)
18932     {
18933       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
18934     }
18935   vat_json_object_add_uint (node, "state", mp->state);
18936 }
18937
18938 static int
18939 api_sw_interface_span_dump (vat_main_t * vam)
18940 {
18941   unformat_input_t *input = vam->input;
18942   vl_api_sw_interface_span_dump_t *mp;
18943   vl_api_control_ping_t *mp_ping;
18944   u8 is_l2 = 0;
18945   int ret;
18946
18947   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18948     {
18949       if (unformat (input, "l2"))
18950         is_l2 = 1;
18951       else
18952         break;
18953     }
18954
18955   M (SW_INTERFACE_SPAN_DUMP, mp);
18956   mp->is_l2 = is_l2;
18957   S (mp);
18958
18959   /* Use a control ping for synchronization */
18960   M (CONTROL_PING, mp_ping);
18961   S (mp_ping);
18962
18963   W (ret);
18964   return ret;
18965 }
18966
18967 int
18968 api_pg_create_interface (vat_main_t * vam)
18969 {
18970   unformat_input_t *input = vam->input;
18971   vl_api_pg_create_interface_t *mp;
18972
18973   u32 if_id = ~0;
18974   int ret;
18975   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18976     {
18977       if (unformat (input, "if_id %d", &if_id))
18978         ;
18979       else
18980         break;
18981     }
18982   if (if_id == ~0)
18983     {
18984       errmsg ("missing pg interface index");
18985       return -99;
18986     }
18987
18988   /* Construct the API message */
18989   M (PG_CREATE_INTERFACE, mp);
18990   mp->context = 0;
18991   mp->interface_id = ntohl (if_id);
18992
18993   S (mp);
18994   W (ret);
18995   return ret;
18996 }
18997
18998 int
18999 api_pg_capture (vat_main_t * vam)
19000 {
19001   unformat_input_t *input = vam->input;
19002   vl_api_pg_capture_t *mp;
19003
19004   u32 if_id = ~0;
19005   u8 enable = 1;
19006   u32 count = 1;
19007   u8 pcap_file_set = 0;
19008   u8 *pcap_file = 0;
19009   int ret;
19010   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19011     {
19012       if (unformat (input, "if_id %d", &if_id))
19013         ;
19014       else if (unformat (input, "pcap %s", &pcap_file))
19015         pcap_file_set = 1;
19016       else if (unformat (input, "count %d", &count))
19017         ;
19018       else if (unformat (input, "disable"))
19019         enable = 0;
19020       else
19021         break;
19022     }
19023   if (if_id == ~0)
19024     {
19025       errmsg ("missing pg interface index");
19026       return -99;
19027     }
19028   if (pcap_file_set > 0)
19029     {
19030       if (vec_len (pcap_file) > 255)
19031         {
19032           errmsg ("pcap file name is too long");
19033           return -99;
19034         }
19035     }
19036
19037   u32 name_len = vec_len (pcap_file);
19038   /* Construct the API message */
19039   M (PG_CAPTURE, mp);
19040   mp->context = 0;
19041   mp->interface_id = ntohl (if_id);
19042   mp->is_enabled = enable;
19043   mp->count = ntohl (count);
19044   mp->pcap_name_length = ntohl (name_len);
19045   if (pcap_file_set != 0)
19046     {
19047       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19048     }
19049   vec_free (pcap_file);
19050
19051   S (mp);
19052   W (ret);
19053   return ret;
19054 }
19055
19056 int
19057 api_pg_enable_disable (vat_main_t * vam)
19058 {
19059   unformat_input_t *input = vam->input;
19060   vl_api_pg_enable_disable_t *mp;
19061
19062   u8 enable = 1;
19063   u8 stream_name_set = 0;
19064   u8 *stream_name = 0;
19065   int ret;
19066   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19067     {
19068       if (unformat (input, "stream %s", &stream_name))
19069         stream_name_set = 1;
19070       else if (unformat (input, "disable"))
19071         enable = 0;
19072       else
19073         break;
19074     }
19075
19076   if (stream_name_set > 0)
19077     {
19078       if (vec_len (stream_name) > 255)
19079         {
19080           errmsg ("stream name too long");
19081           return -99;
19082         }
19083     }
19084
19085   u32 name_len = vec_len (stream_name);
19086   /* Construct the API message */
19087   M (PG_ENABLE_DISABLE, mp);
19088   mp->context = 0;
19089   mp->is_enabled = enable;
19090   if (stream_name_set != 0)
19091     {
19092       mp->stream_name_length = ntohl (name_len);
19093       clib_memcpy (mp->stream_name, stream_name, name_len);
19094     }
19095   vec_free (stream_name);
19096
19097   S (mp);
19098   W (ret);
19099   return ret;
19100 }
19101
19102 int
19103 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
19104 {
19105   unformat_input_t *input = vam->input;
19106   vl_api_ip_source_and_port_range_check_add_del_t *mp;
19107
19108   u16 *low_ports = 0;
19109   u16 *high_ports = 0;
19110   u16 this_low;
19111   u16 this_hi;
19112   ip4_address_t ip4_addr;
19113   ip6_address_t ip6_addr;
19114   u32 length;
19115   u32 tmp, tmp2;
19116   u8 prefix_set = 0;
19117   u32 vrf_id = ~0;
19118   u8 is_add = 1;
19119   u8 is_ipv6 = 0;
19120   int ret;
19121
19122   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19123     {
19124       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
19125         {
19126           prefix_set = 1;
19127         }
19128       else
19129         if (unformat
19130             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
19131         {
19132           prefix_set = 1;
19133           is_ipv6 = 1;
19134         }
19135       else if (unformat (input, "vrf %d", &vrf_id))
19136         ;
19137       else if (unformat (input, "del"))
19138         is_add = 0;
19139       else if (unformat (input, "port %d", &tmp))
19140         {
19141           if (tmp == 0 || tmp > 65535)
19142             {
19143               errmsg ("port %d out of range", tmp);
19144               return -99;
19145             }
19146           this_low = tmp;
19147           this_hi = this_low + 1;
19148           vec_add1 (low_ports, this_low);
19149           vec_add1 (high_ports, this_hi);
19150         }
19151       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
19152         {
19153           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
19154             {
19155               errmsg ("incorrect range parameters");
19156               return -99;
19157             }
19158           this_low = tmp;
19159           /* Note: in debug CLI +1 is added to high before
19160              passing to real fn that does "the work"
19161              (ip_source_and_port_range_check_add_del).
19162              This fn is a wrapper around the binary API fn a
19163              control plane will call, which expects this increment
19164              to have occurred. Hence letting the binary API control
19165              plane fn do the increment for consistency between VAT
19166              and other control planes.
19167            */
19168           this_hi = tmp2;
19169           vec_add1 (low_ports, this_low);
19170           vec_add1 (high_ports, this_hi);
19171         }
19172       else
19173         break;
19174     }
19175
19176   if (prefix_set == 0)
19177     {
19178       errmsg ("<address>/<mask> not specified");
19179       return -99;
19180     }
19181
19182   if (vrf_id == ~0)
19183     {
19184       errmsg ("VRF ID required, not specified");
19185       return -99;
19186     }
19187
19188   if (vrf_id == 0)
19189     {
19190       errmsg
19191         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19192       return -99;
19193     }
19194
19195   if (vec_len (low_ports) == 0)
19196     {
19197       errmsg ("At least one port or port range required");
19198       return -99;
19199     }
19200
19201   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
19202
19203   mp->is_add = is_add;
19204
19205   if (is_ipv6)
19206     {
19207       mp->is_ipv6 = 1;
19208       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
19209     }
19210   else
19211     {
19212       mp->is_ipv6 = 0;
19213       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
19214     }
19215
19216   mp->mask_length = length;
19217   mp->number_of_ranges = vec_len (low_ports);
19218
19219   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
19220   vec_free (low_ports);
19221
19222   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
19223   vec_free (high_ports);
19224
19225   mp->vrf_id = ntohl (vrf_id);
19226
19227   S (mp);
19228   W (ret);
19229   return ret;
19230 }
19231
19232 int
19233 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
19234 {
19235   unformat_input_t *input = vam->input;
19236   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
19237   u32 sw_if_index = ~0;
19238   int vrf_set = 0;
19239   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
19240   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
19241   u8 is_add = 1;
19242   int ret;
19243
19244   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19245     {
19246       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19247         ;
19248       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19249         ;
19250       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
19251         vrf_set = 1;
19252       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
19253         vrf_set = 1;
19254       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
19255         vrf_set = 1;
19256       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
19257         vrf_set = 1;
19258       else if (unformat (input, "del"))
19259         is_add = 0;
19260       else
19261         break;
19262     }
19263
19264   if (sw_if_index == ~0)
19265     {
19266       errmsg ("Interface required but not specified");
19267       return -99;
19268     }
19269
19270   if (vrf_set == 0)
19271     {
19272       errmsg ("VRF ID required but not specified");
19273       return -99;
19274     }
19275
19276   if (tcp_out_vrf_id == 0
19277       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
19278     {
19279       errmsg
19280         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19281       return -99;
19282     }
19283
19284   /* Construct the API message */
19285   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
19286
19287   mp->sw_if_index = ntohl (sw_if_index);
19288   mp->is_add = is_add;
19289   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
19290   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
19291   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
19292   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
19293
19294   /* send it... */
19295   S (mp);
19296
19297   /* Wait for a reply... */
19298   W (ret);
19299   return ret;
19300 }
19301
19302 static int
19303 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
19304 {
19305   unformat_input_t *i = vam->input;
19306   vl_api_ipsec_gre_add_del_tunnel_t *mp;
19307   u32 local_sa_id = 0;
19308   u32 remote_sa_id = 0;
19309   ip4_address_t src_address;
19310   ip4_address_t dst_address;
19311   u8 is_add = 1;
19312   int ret;
19313
19314   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19315     {
19316       if (unformat (i, "local_sa %d", &local_sa_id))
19317         ;
19318       else if (unformat (i, "remote_sa %d", &remote_sa_id))
19319         ;
19320       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
19321         ;
19322       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
19323         ;
19324       else if (unformat (i, "del"))
19325         is_add = 0;
19326       else
19327         {
19328           clib_warning ("parse error '%U'", format_unformat_error, i);
19329           return -99;
19330         }
19331     }
19332
19333   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
19334
19335   mp->local_sa_id = ntohl (local_sa_id);
19336   mp->remote_sa_id = ntohl (remote_sa_id);
19337   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
19338   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
19339   mp->is_add = is_add;
19340
19341   S (mp);
19342   W (ret);
19343   return ret;
19344 }
19345
19346 static int
19347 api_punt (vat_main_t * vam)
19348 {
19349   unformat_input_t *i = vam->input;
19350   vl_api_punt_t *mp;
19351   u32 ipv = ~0;
19352   u32 protocol = ~0;
19353   u32 port = ~0;
19354   int is_add = 1;
19355   int ret;
19356
19357   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19358     {
19359       if (unformat (i, "ip %d", &ipv))
19360         ;
19361       else if (unformat (i, "protocol %d", &protocol))
19362         ;
19363       else if (unformat (i, "port %d", &port))
19364         ;
19365       else if (unformat (i, "del"))
19366         is_add = 0;
19367       else
19368         {
19369           clib_warning ("parse error '%U'", format_unformat_error, i);
19370           return -99;
19371         }
19372     }
19373
19374   M (PUNT, mp);
19375
19376   mp->is_add = (u8) is_add;
19377   mp->ipv = (u8) ipv;
19378   mp->l4_protocol = (u8) protocol;
19379   mp->l4_port = htons ((u16) port);
19380
19381   S (mp);
19382   W (ret);
19383   return ret;
19384 }
19385
19386 static void vl_api_ipsec_gre_tunnel_details_t_handler
19387   (vl_api_ipsec_gre_tunnel_details_t * mp)
19388 {
19389   vat_main_t *vam = &vat_main;
19390
19391   print (vam->ofp, "%11d%15U%15U%14d%14d",
19392          ntohl (mp->sw_if_index),
19393          format_ip4_address, &mp->src_address,
19394          format_ip4_address, &mp->dst_address,
19395          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
19396 }
19397
19398 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
19399   (vl_api_ipsec_gre_tunnel_details_t * mp)
19400 {
19401   vat_main_t *vam = &vat_main;
19402   vat_json_node_t *node = NULL;
19403   struct in_addr ip4;
19404
19405   if (VAT_JSON_ARRAY != vam->json_tree.type)
19406     {
19407       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19408       vat_json_init_array (&vam->json_tree);
19409     }
19410   node = vat_json_array_add (&vam->json_tree);
19411
19412   vat_json_init_object (node);
19413   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
19414   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
19415   vat_json_object_add_ip4 (node, "src_address", ip4);
19416   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
19417   vat_json_object_add_ip4 (node, "dst_address", ip4);
19418   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
19419   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
19420 }
19421
19422 static int
19423 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
19424 {
19425   unformat_input_t *i = vam->input;
19426   vl_api_ipsec_gre_tunnel_dump_t *mp;
19427   vl_api_control_ping_t *mp_ping;
19428   u32 sw_if_index;
19429   u8 sw_if_index_set = 0;
19430   int ret;
19431
19432   /* Parse args required to build the message */
19433   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19434     {
19435       if (unformat (i, "sw_if_index %d", &sw_if_index))
19436         sw_if_index_set = 1;
19437       else
19438         break;
19439     }
19440
19441   if (sw_if_index_set == 0)
19442     {
19443       sw_if_index = ~0;
19444     }
19445
19446   if (!vam->json_output)
19447     {
19448       print (vam->ofp, "%11s%15s%15s%14s%14s",
19449              "sw_if_index", "src_address", "dst_address",
19450              "local_sa_id", "remote_sa_id");
19451     }
19452
19453   /* Get list of gre-tunnel interfaces */
19454   M (IPSEC_GRE_TUNNEL_DUMP, mp);
19455
19456   mp->sw_if_index = htonl (sw_if_index);
19457
19458   S (mp);
19459
19460   /* Use a control ping for synchronization */
19461   M (CONTROL_PING, mp_ping);
19462   S (mp_ping);
19463
19464   W (ret);
19465   return ret;
19466 }
19467
19468 static int
19469 api_delete_subif (vat_main_t * vam)
19470 {
19471   unformat_input_t *i = vam->input;
19472   vl_api_delete_subif_t *mp;
19473   u32 sw_if_index = ~0;
19474   int ret;
19475
19476   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19477     {
19478       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19479         ;
19480       if (unformat (i, "sw_if_index %d", &sw_if_index))
19481         ;
19482       else
19483         break;
19484     }
19485
19486   if (sw_if_index == ~0)
19487     {
19488       errmsg ("missing sw_if_index");
19489       return -99;
19490     }
19491
19492   /* Construct the API message */
19493   M (DELETE_SUBIF, mp);
19494   mp->sw_if_index = ntohl (sw_if_index);
19495
19496   S (mp);
19497   W (ret);
19498   return ret;
19499 }
19500
19501 #define foreach_pbb_vtr_op      \
19502 _("disable",  L2_VTR_DISABLED)  \
19503 _("pop",  L2_VTR_POP_2)         \
19504 _("push",  L2_VTR_PUSH_2)
19505
19506 static int
19507 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
19508 {
19509   unformat_input_t *i = vam->input;
19510   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
19511   u32 sw_if_index = ~0, vtr_op = ~0;
19512   u16 outer_tag = ~0;
19513   u8 dmac[6], smac[6];
19514   u8 dmac_set = 0, smac_set = 0;
19515   u16 vlanid = 0;
19516   u32 sid = ~0;
19517   u32 tmp;
19518   int ret;
19519
19520   /* Shut up coverity */
19521   memset (dmac, 0, sizeof (dmac));
19522   memset (smac, 0, sizeof (smac));
19523
19524   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19525     {
19526       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19527         ;
19528       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19529         ;
19530       else if (unformat (i, "vtr_op %d", &vtr_op))
19531         ;
19532 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
19533       foreach_pbb_vtr_op
19534 #undef _
19535         else if (unformat (i, "translate_pbb_stag"))
19536         {
19537           if (unformat (i, "%d", &tmp))
19538             {
19539               vtr_op = L2_VTR_TRANSLATE_2_1;
19540               outer_tag = tmp;
19541             }
19542           else
19543             {
19544               errmsg
19545                 ("translate_pbb_stag operation requires outer tag definition");
19546               return -99;
19547             }
19548         }
19549       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
19550         dmac_set++;
19551       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
19552         smac_set++;
19553       else if (unformat (i, "sid %d", &sid))
19554         ;
19555       else if (unformat (i, "vlanid %d", &tmp))
19556         vlanid = tmp;
19557       else
19558         {
19559           clib_warning ("parse error '%U'", format_unformat_error, i);
19560           return -99;
19561         }
19562     }
19563
19564   if ((sw_if_index == ~0) || (vtr_op == ~0))
19565     {
19566       errmsg ("missing sw_if_index or vtr operation");
19567       return -99;
19568     }
19569   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
19570       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
19571     {
19572       errmsg
19573         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
19574       return -99;
19575     }
19576
19577   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
19578   mp->sw_if_index = ntohl (sw_if_index);
19579   mp->vtr_op = ntohl (vtr_op);
19580   mp->outer_tag = ntohs (outer_tag);
19581   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
19582   clib_memcpy (mp->b_smac, smac, sizeof (smac));
19583   mp->b_vlanid = ntohs (vlanid);
19584   mp->i_sid = ntohl (sid);
19585
19586   S (mp);
19587   W (ret);
19588   return ret;
19589 }
19590
19591 static int
19592 api_flow_classify_set_interface (vat_main_t * vam)
19593 {
19594   unformat_input_t *i = vam->input;
19595   vl_api_flow_classify_set_interface_t *mp;
19596   u32 sw_if_index;
19597   int sw_if_index_set;
19598   u32 ip4_table_index = ~0;
19599   u32 ip6_table_index = ~0;
19600   u8 is_add = 1;
19601   int ret;
19602
19603   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19604     {
19605       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19606         sw_if_index_set = 1;
19607       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19608         sw_if_index_set = 1;
19609       else if (unformat (i, "del"))
19610         is_add = 0;
19611       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19612         ;
19613       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19614         ;
19615       else
19616         {
19617           clib_warning ("parse error '%U'", format_unformat_error, i);
19618           return -99;
19619         }
19620     }
19621
19622   if (sw_if_index_set == 0)
19623     {
19624       errmsg ("missing interface name or sw_if_index");
19625       return -99;
19626     }
19627
19628   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
19629
19630   mp->sw_if_index = ntohl (sw_if_index);
19631   mp->ip4_table_index = ntohl (ip4_table_index);
19632   mp->ip6_table_index = ntohl (ip6_table_index);
19633   mp->is_add = is_add;
19634
19635   S (mp);
19636   W (ret);
19637   return ret;
19638 }
19639
19640 static int
19641 api_flow_classify_dump (vat_main_t * vam)
19642 {
19643   unformat_input_t *i = vam->input;
19644   vl_api_flow_classify_dump_t *mp;
19645   vl_api_control_ping_t *mp_ping;
19646   u8 type = FLOW_CLASSIFY_N_TABLES;
19647   int ret;
19648
19649   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19650     ;
19651   else
19652     {
19653       errmsg ("classify table type must be specified");
19654       return -99;
19655     }
19656
19657   if (!vam->json_output)
19658     {
19659       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19660     }
19661
19662   M (FLOW_CLASSIFY_DUMP, mp);
19663   mp->type = type;
19664   /* send it... */
19665   S (mp);
19666
19667   /* Use a control ping for synchronization */
19668   M (CONTROL_PING, mp_ping);
19669   S (mp_ping);
19670
19671   /* Wait for a reply... */
19672   W (ret);
19673   return ret;
19674 }
19675
19676 static int
19677 api_feature_enable_disable (vat_main_t * vam)
19678 {
19679   unformat_input_t *i = vam->input;
19680   vl_api_feature_enable_disable_t *mp;
19681   u8 *arc_name = 0;
19682   u8 *feature_name = 0;
19683   u32 sw_if_index = ~0;
19684   u8 enable = 1;
19685   int ret;
19686
19687   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19688     {
19689       if (unformat (i, "arc_name %s", &arc_name))
19690         ;
19691       else if (unformat (i, "feature_name %s", &feature_name))
19692         ;
19693       else
19694         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19695         ;
19696       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19697         ;
19698       else if (unformat (i, "disable"))
19699         enable = 0;
19700       else
19701         break;
19702     }
19703
19704   if (arc_name == 0)
19705     {
19706       errmsg ("missing arc name");
19707       return -99;
19708     }
19709   if (vec_len (arc_name) > 63)
19710     {
19711       errmsg ("arc name too long");
19712     }
19713
19714   if (feature_name == 0)
19715     {
19716       errmsg ("missing feature name");
19717       return -99;
19718     }
19719   if (vec_len (feature_name) > 63)
19720     {
19721       errmsg ("feature name too long");
19722     }
19723
19724   if (sw_if_index == ~0)
19725     {
19726       errmsg ("missing interface name or sw_if_index");
19727       return -99;
19728     }
19729
19730   /* Construct the API message */
19731   M (FEATURE_ENABLE_DISABLE, mp);
19732   mp->sw_if_index = ntohl (sw_if_index);
19733   mp->enable = enable;
19734   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
19735   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
19736   vec_free (arc_name);
19737   vec_free (feature_name);
19738
19739   S (mp);
19740   W (ret);
19741   return ret;
19742 }
19743
19744 static int
19745 api_sw_interface_tag_add_del (vat_main_t * vam)
19746 {
19747   unformat_input_t *i = vam->input;
19748   vl_api_sw_interface_tag_add_del_t *mp;
19749   u32 sw_if_index = ~0;
19750   u8 *tag = 0;
19751   u8 enable = 1;
19752   int ret;
19753
19754   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19755     {
19756       if (unformat (i, "tag %s", &tag))
19757         ;
19758       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19759         ;
19760       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19761         ;
19762       else if (unformat (i, "del"))
19763         enable = 0;
19764       else
19765         break;
19766     }
19767
19768   if (sw_if_index == ~0)
19769     {
19770       errmsg ("missing interface name or sw_if_index");
19771       return -99;
19772     }
19773
19774   if (enable && (tag == 0))
19775     {
19776       errmsg ("no tag specified");
19777       return -99;
19778     }
19779
19780   /* Construct the API message */
19781   M (SW_INTERFACE_TAG_ADD_DEL, mp);
19782   mp->sw_if_index = ntohl (sw_if_index);
19783   mp->is_add = enable;
19784   if (enable)
19785     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
19786   vec_free (tag);
19787
19788   S (mp);
19789   W (ret);
19790   return ret;
19791 }
19792
19793 static void vl_api_l2_xconnect_details_t_handler
19794   (vl_api_l2_xconnect_details_t * mp)
19795 {
19796   vat_main_t *vam = &vat_main;
19797
19798   print (vam->ofp, "%15d%15d",
19799          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
19800 }
19801
19802 static void vl_api_l2_xconnect_details_t_handler_json
19803   (vl_api_l2_xconnect_details_t * mp)
19804 {
19805   vat_main_t *vam = &vat_main;
19806   vat_json_node_t *node = NULL;
19807
19808   if (VAT_JSON_ARRAY != vam->json_tree.type)
19809     {
19810       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19811       vat_json_init_array (&vam->json_tree);
19812     }
19813   node = vat_json_array_add (&vam->json_tree);
19814
19815   vat_json_init_object (node);
19816   vat_json_object_add_uint (node, "rx_sw_if_index",
19817                             ntohl (mp->rx_sw_if_index));
19818   vat_json_object_add_uint (node, "tx_sw_if_index",
19819                             ntohl (mp->tx_sw_if_index));
19820 }
19821
19822 static int
19823 api_l2_xconnect_dump (vat_main_t * vam)
19824 {
19825   vl_api_l2_xconnect_dump_t *mp;
19826   vl_api_control_ping_t *mp_ping;
19827   int ret;
19828
19829   if (!vam->json_output)
19830     {
19831       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
19832     }
19833
19834   M (L2_XCONNECT_DUMP, mp);
19835
19836   S (mp);
19837
19838   /* Use a control ping for synchronization */
19839   M (CONTROL_PING, mp_ping);
19840   S (mp_ping);
19841
19842   W (ret);
19843   return ret;
19844 }
19845
19846 static int
19847 api_sw_interface_set_mtu (vat_main_t * vam)
19848 {
19849   unformat_input_t *i = vam->input;
19850   vl_api_sw_interface_set_mtu_t *mp;
19851   u32 sw_if_index = ~0;
19852   u32 mtu = 0;
19853   int ret;
19854
19855   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19856     {
19857       if (unformat (i, "mtu %d", &mtu))
19858         ;
19859       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19860         ;
19861       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19862         ;
19863       else
19864         break;
19865     }
19866
19867   if (sw_if_index == ~0)
19868     {
19869       errmsg ("missing interface name or sw_if_index");
19870       return -99;
19871     }
19872
19873   if (mtu == 0)
19874     {
19875       errmsg ("no mtu specified");
19876       return -99;
19877     }
19878
19879   /* Construct the API message */
19880   M (SW_INTERFACE_SET_MTU, mp);
19881   mp->sw_if_index = ntohl (sw_if_index);
19882   mp->mtu = ntohs ((u16) mtu);
19883
19884   S (mp);
19885   W (ret);
19886   return ret;
19887 }
19888
19889 static int
19890 api_p2p_ethernet_add (vat_main_t * vam)
19891 {
19892   unformat_input_t *i = vam->input;
19893   vl_api_p2p_ethernet_add_t *mp;
19894   u32 parent_if_index = ~0;
19895   u32 sub_id = ~0;
19896   u8 remote_mac[6];
19897   u8 mac_set = 0;
19898   int ret;
19899
19900   memset (remote_mac, 0, sizeof (remote_mac));
19901   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19902     {
19903       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19904         ;
19905       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19906         ;
19907       else
19908         if (unformat
19909             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19910         mac_set++;
19911       else if (unformat (i, "sub_id %d", &sub_id))
19912         ;
19913       else
19914         {
19915           clib_warning ("parse error '%U'", format_unformat_error, i);
19916           return -99;
19917         }
19918     }
19919
19920   if (parent_if_index == ~0)
19921     {
19922       errmsg ("missing interface name or sw_if_index");
19923       return -99;
19924     }
19925   if (mac_set == 0)
19926     {
19927       errmsg ("missing remote mac address");
19928       return -99;
19929     }
19930   if (sub_id == ~0)
19931     {
19932       errmsg ("missing sub-interface id");
19933       return -99;
19934     }
19935
19936   M (P2P_ETHERNET_ADD, mp);
19937   mp->parent_if_index = ntohl (parent_if_index);
19938   mp->subif_id = ntohl (sub_id);
19939   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19940
19941   S (mp);
19942   W (ret);
19943   return ret;
19944 }
19945
19946 static int
19947 api_p2p_ethernet_del (vat_main_t * vam)
19948 {
19949   unformat_input_t *i = vam->input;
19950   vl_api_p2p_ethernet_del_t *mp;
19951   u32 parent_if_index = ~0;
19952   u8 remote_mac[6];
19953   u8 mac_set = 0;
19954   int ret;
19955
19956   memset (remote_mac, 0, sizeof (remote_mac));
19957   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19958     {
19959       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19960         ;
19961       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19962         ;
19963       else
19964         if (unformat
19965             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19966         mac_set++;
19967       else
19968         {
19969           clib_warning ("parse error '%U'", format_unformat_error, i);
19970           return -99;
19971         }
19972     }
19973
19974   if (parent_if_index == ~0)
19975     {
19976       errmsg ("missing interface name or sw_if_index");
19977       return -99;
19978     }
19979   if (mac_set == 0)
19980     {
19981       errmsg ("missing remote mac address");
19982       return -99;
19983     }
19984
19985   M (P2P_ETHERNET_DEL, mp);
19986   mp->parent_if_index = ntohl (parent_if_index);
19987   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19988
19989   S (mp);
19990   W (ret);
19991   return ret;
19992 }
19993
19994 static int
19995 api_lldp_config (vat_main_t * vam)
19996 {
19997   unformat_input_t *i = vam->input;
19998   vl_api_lldp_config_t *mp;
19999   int tx_hold = 0;
20000   int tx_interval = 0;
20001   u8 *sys_name = NULL;
20002   int ret;
20003
20004   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20005     {
20006       if (unformat (i, "system-name %s", &sys_name))
20007         ;
20008       else if (unformat (i, "tx-hold %d", &tx_hold))
20009         ;
20010       else if (unformat (i, "tx-interval %d", &tx_interval))
20011         ;
20012       else
20013         {
20014           clib_warning ("parse error '%U'", format_unformat_error, i);
20015           return -99;
20016         }
20017     }
20018
20019   vec_add1 (sys_name, 0);
20020
20021   M (LLDP_CONFIG, mp);
20022   mp->tx_hold = htonl (tx_hold);
20023   mp->tx_interval = htonl (tx_interval);
20024   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20025   vec_free (sys_name);
20026
20027   S (mp);
20028   W (ret);
20029   return ret;
20030 }
20031
20032 static int
20033 api_sw_interface_set_lldp (vat_main_t * vam)
20034 {
20035   unformat_input_t *i = vam->input;
20036   vl_api_sw_interface_set_lldp_t *mp;
20037   u32 sw_if_index = ~0;
20038   u32 enable = 1;
20039   u8 *port_desc = NULL;
20040   int ret;
20041
20042   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20043     {
20044       if (unformat (i, "disable"))
20045         enable = 0;
20046       else
20047         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20048         ;
20049       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20050         ;
20051       else if (unformat (i, "port-desc %s", &port_desc))
20052         ;
20053       else
20054         break;
20055     }
20056
20057   if (sw_if_index == ~0)
20058     {
20059       errmsg ("missing interface name or sw_if_index");
20060       return -99;
20061     }
20062
20063   /* Construct the API message */
20064   vec_add1 (port_desc, 0);
20065   M (SW_INTERFACE_SET_LLDP, mp);
20066   mp->sw_if_index = ntohl (sw_if_index);
20067   mp->enable = enable;
20068   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20069   vec_free (port_desc);
20070
20071   S (mp);
20072   W (ret);
20073   return ret;
20074 }
20075
20076 static int
20077 api_tcp_configure_src_addresses (vat_main_t * vam)
20078 {
20079   vl_api_tcp_configure_src_addresses_t *mp;
20080   unformat_input_t *i = vam->input;
20081   ip4_address_t v4first, v4last;
20082   ip6_address_t v6first, v6last;
20083   u8 range_set = 0;
20084   u32 vrf_id = 0;
20085   int ret;
20086
20087   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20088     {
20089       if (unformat (i, "%U - %U",
20090                     unformat_ip4_address, &v4first,
20091                     unformat_ip4_address, &v4last))
20092         {
20093           if (range_set)
20094             {
20095               errmsg ("one range per message (range already set)");
20096               return -99;
20097             }
20098           range_set = 1;
20099         }
20100       else if (unformat (i, "%U - %U",
20101                          unformat_ip6_address, &v6first,
20102                          unformat_ip6_address, &v6last))
20103         {
20104           if (range_set)
20105             {
20106               errmsg ("one range per message (range already set)");
20107               return -99;
20108             }
20109           range_set = 2;
20110         }
20111       else if (unformat (i, "vrf %d", &vrf_id))
20112         ;
20113       else
20114         break;
20115     }
20116
20117   if (range_set == 0)
20118     {
20119       errmsg ("address range not set");
20120       return -99;
20121     }
20122
20123   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
20124   mp->vrf_id = ntohl (vrf_id);
20125   /* ipv6? */
20126   if (range_set == 2)
20127     {
20128       mp->is_ipv6 = 1;
20129       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20130       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20131     }
20132   else
20133     {
20134       mp->is_ipv6 = 0;
20135       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
20136       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
20137     }
20138   S (mp);
20139   W (ret);
20140   return ret;
20141 }
20142
20143 static int
20144 q_or_quit (vat_main_t * vam)
20145 {
20146 #if VPP_API_TEST_BUILTIN == 0
20147   longjmp (vam->jump_buf, 1);
20148 #endif
20149   return 0;                     /* not so much */
20150 }
20151
20152 static int
20153 q (vat_main_t * vam)
20154 {
20155   return q_or_quit (vam);
20156 }
20157
20158 static int
20159 quit (vat_main_t * vam)
20160 {
20161   return q_or_quit (vam);
20162 }
20163
20164 static int
20165 comment (vat_main_t * vam)
20166 {
20167   return 0;
20168 }
20169
20170 static int
20171 cmd_cmp (void *a1, void *a2)
20172 {
20173   u8 **c1 = a1;
20174   u8 **c2 = a2;
20175
20176   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
20177 }
20178
20179 static int
20180 help (vat_main_t * vam)
20181 {
20182   u8 **cmds = 0;
20183   u8 *name = 0;
20184   hash_pair_t *p;
20185   unformat_input_t *i = vam->input;
20186   int j;
20187
20188   if (unformat (i, "%s", &name))
20189     {
20190       uword *hs;
20191
20192       vec_add1 (name, 0);
20193
20194       hs = hash_get_mem (vam->help_by_name, name);
20195       if (hs)
20196         print (vam->ofp, "usage: %s %s", name, hs[0]);
20197       else
20198         print (vam->ofp, "No such msg / command '%s'", name);
20199       vec_free (name);
20200       return 0;
20201     }
20202
20203   print (vam->ofp, "Help is available for the following:");
20204
20205     /* *INDENT-OFF* */
20206     hash_foreach_pair (p, vam->function_by_name,
20207     ({
20208       vec_add1 (cmds, (u8 *)(p->key));
20209     }));
20210     /* *INDENT-ON* */
20211
20212   vec_sort_with_function (cmds, cmd_cmp);
20213
20214   for (j = 0; j < vec_len (cmds); j++)
20215     print (vam->ofp, "%s", cmds[j]);
20216
20217   vec_free (cmds);
20218   return 0;
20219 }
20220
20221 static int
20222 set (vat_main_t * vam)
20223 {
20224   u8 *name = 0, *value = 0;
20225   unformat_input_t *i = vam->input;
20226
20227   if (unformat (i, "%s", &name))
20228     {
20229       /* The input buffer is a vector, not a string. */
20230       value = vec_dup (i->buffer);
20231       vec_delete (value, i->index, 0);
20232       /* Almost certainly has a trailing newline */
20233       if (value[vec_len (value) - 1] == '\n')
20234         value[vec_len (value) - 1] = 0;
20235       /* Make sure it's a proper string, one way or the other */
20236       vec_add1 (value, 0);
20237       (void) clib_macro_set_value (&vam->macro_main,
20238                                    (char *) name, (char *) value);
20239     }
20240   else
20241     errmsg ("usage: set <name> <value>");
20242
20243   vec_free (name);
20244   vec_free (value);
20245   return 0;
20246 }
20247
20248 static int
20249 unset (vat_main_t * vam)
20250 {
20251   u8 *name = 0;
20252
20253   if (unformat (vam->input, "%s", &name))
20254     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
20255       errmsg ("unset: %s wasn't set", name);
20256   vec_free (name);
20257   return 0;
20258 }
20259
20260 typedef struct
20261 {
20262   u8 *name;
20263   u8 *value;
20264 } macro_sort_t;
20265
20266
20267 static int
20268 macro_sort_cmp (void *a1, void *a2)
20269 {
20270   macro_sort_t *s1 = a1;
20271   macro_sort_t *s2 = a2;
20272
20273   return strcmp ((char *) (s1->name), (char *) (s2->name));
20274 }
20275
20276 static int
20277 dump_macro_table (vat_main_t * vam)
20278 {
20279   macro_sort_t *sort_me = 0, *sm;
20280   int i;
20281   hash_pair_t *p;
20282
20283     /* *INDENT-OFF* */
20284     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
20285     ({
20286       vec_add2 (sort_me, sm, 1);
20287       sm->name = (u8 *)(p->key);
20288       sm->value = (u8 *) (p->value[0]);
20289     }));
20290     /* *INDENT-ON* */
20291
20292   vec_sort_with_function (sort_me, macro_sort_cmp);
20293
20294   if (vec_len (sort_me))
20295     print (vam->ofp, "%-15s%s", "Name", "Value");
20296   else
20297     print (vam->ofp, "The macro table is empty...");
20298
20299   for (i = 0; i < vec_len (sort_me); i++)
20300     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
20301   return 0;
20302 }
20303
20304 static int
20305 dump_node_table (vat_main_t * vam)
20306 {
20307   int i, j;
20308   vlib_node_t *node, *next_node;
20309
20310   if (vec_len (vam->graph_nodes) == 0)
20311     {
20312       print (vam->ofp, "Node table empty, issue get_node_graph...");
20313       return 0;
20314     }
20315
20316   for (i = 0; i < vec_len (vam->graph_nodes); i++)
20317     {
20318       node = vam->graph_nodes[i];
20319       print (vam->ofp, "[%d] %s", i, node->name);
20320       for (j = 0; j < vec_len (node->next_nodes); j++)
20321         {
20322           if (node->next_nodes[j] != ~0)
20323             {
20324               next_node = vam->graph_nodes[node->next_nodes[j]];
20325               print (vam->ofp, "  [%d] %s", j, next_node->name);
20326             }
20327         }
20328     }
20329   return 0;
20330 }
20331
20332 static int
20333 value_sort_cmp (void *a1, void *a2)
20334 {
20335   name_sort_t *n1 = a1;
20336   name_sort_t *n2 = a2;
20337
20338   if (n1->value < n2->value)
20339     return -1;
20340   if (n1->value > n2->value)
20341     return 1;
20342   return 0;
20343 }
20344
20345
20346 static int
20347 dump_msg_api_table (vat_main_t * vam)
20348 {
20349   api_main_t *am = &api_main;
20350   name_sort_t *nses = 0, *ns;
20351   hash_pair_t *hp;
20352   int i;
20353
20354   /* *INDENT-OFF* */
20355   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
20356   ({
20357     vec_add2 (nses, ns, 1);
20358     ns->name = (u8 *)(hp->key);
20359     ns->value = (u32) hp->value[0];
20360   }));
20361   /* *INDENT-ON* */
20362
20363   vec_sort_with_function (nses, value_sort_cmp);
20364
20365   for (i = 0; i < vec_len (nses); i++)
20366     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
20367   vec_free (nses);
20368   return 0;
20369 }
20370
20371 static int
20372 get_msg_id (vat_main_t * vam)
20373 {
20374   u8 *name_and_crc;
20375   u32 message_index;
20376
20377   if (unformat (vam->input, "%s", &name_and_crc))
20378     {
20379       message_index = vl_api_get_msg_index (name_and_crc);
20380       if (message_index == ~0)
20381         {
20382           print (vam->ofp, " '%s' not found", name_and_crc);
20383           return 0;
20384         }
20385       print (vam->ofp, " '%s' has message index %d",
20386              name_and_crc, message_index);
20387       return 0;
20388     }
20389   errmsg ("name_and_crc required...");
20390   return 0;
20391 }
20392
20393 static int
20394 search_node_table (vat_main_t * vam)
20395 {
20396   unformat_input_t *line_input = vam->input;
20397   u8 *node_to_find;
20398   int j;
20399   vlib_node_t *node, *next_node;
20400   uword *p;
20401
20402   if (vam->graph_node_index_by_name == 0)
20403     {
20404       print (vam->ofp, "Node table empty, issue get_node_graph...");
20405       return 0;
20406     }
20407
20408   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20409     {
20410       if (unformat (line_input, "%s", &node_to_find))
20411         {
20412           vec_add1 (node_to_find, 0);
20413           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
20414           if (p == 0)
20415             {
20416               print (vam->ofp, "%s not found...", node_to_find);
20417               goto out;
20418             }
20419           node = vam->graph_nodes[p[0]];
20420           print (vam->ofp, "[%d] %s", p[0], node->name);
20421           for (j = 0; j < vec_len (node->next_nodes); j++)
20422             {
20423               if (node->next_nodes[j] != ~0)
20424                 {
20425                   next_node = vam->graph_nodes[node->next_nodes[j]];
20426                   print (vam->ofp, "  [%d] %s", j, next_node->name);
20427                 }
20428             }
20429         }
20430
20431       else
20432         {
20433           clib_warning ("parse error '%U'", format_unformat_error,
20434                         line_input);
20435           return -99;
20436         }
20437
20438     out:
20439       vec_free (node_to_find);
20440
20441     }
20442
20443   return 0;
20444 }
20445
20446
20447 static int
20448 script (vat_main_t * vam)
20449 {
20450 #if (VPP_API_TEST_BUILTIN==0)
20451   u8 *s = 0;
20452   char *save_current_file;
20453   unformat_input_t save_input;
20454   jmp_buf save_jump_buf;
20455   u32 save_line_number;
20456
20457   FILE *new_fp, *save_ifp;
20458
20459   if (unformat (vam->input, "%s", &s))
20460     {
20461       new_fp = fopen ((char *) s, "r");
20462       if (new_fp == 0)
20463         {
20464           errmsg ("Couldn't open script file %s", s);
20465           vec_free (s);
20466           return -99;
20467         }
20468     }
20469   else
20470     {
20471       errmsg ("Missing script name");
20472       return -99;
20473     }
20474
20475   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
20476   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
20477   save_ifp = vam->ifp;
20478   save_line_number = vam->input_line_number;
20479   save_current_file = (char *) vam->current_file;
20480
20481   vam->input_line_number = 0;
20482   vam->ifp = new_fp;
20483   vam->current_file = s;
20484   do_one_file (vam);
20485
20486   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
20487   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
20488   vam->ifp = save_ifp;
20489   vam->input_line_number = save_line_number;
20490   vam->current_file = (u8 *) save_current_file;
20491   vec_free (s);
20492
20493   return 0;
20494 #else
20495   clib_warning ("use the exec command...");
20496   return -99;
20497 #endif
20498 }
20499
20500 static int
20501 echo (vat_main_t * vam)
20502 {
20503   print (vam->ofp, "%v", vam->input->buffer);
20504   return 0;
20505 }
20506
20507 /* List of API message constructors, CLI names map to api_xxx */
20508 #define foreach_vpe_api_msg                                             \
20509 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
20510 _(sw_interface_dump,"")                                                 \
20511 _(sw_interface_set_flags,                                               \
20512   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
20513 _(sw_interface_add_del_address,                                         \
20514   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
20515 _(sw_interface_set_table,                                               \
20516   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
20517 _(sw_interface_set_mpls_enable,                                         \
20518   "<intfc> | sw_if_index [disable | dis]")                              \
20519 _(sw_interface_set_vpath,                                               \
20520   "<intfc> | sw_if_index <id> enable | disable")                        \
20521 _(sw_interface_set_vxlan_bypass,                                        \
20522   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20523 _(sw_interface_set_l2_xconnect,                                         \
20524   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20525   "enable | disable")                                                   \
20526 _(sw_interface_set_l2_bridge,                                           \
20527   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
20528   "[shg <split-horizon-group>] [bvi]\n"                                 \
20529   "enable | disable")                                                   \
20530 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
20531 _(bridge_domain_add_del,                                                \
20532   "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") \
20533 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
20534 _(l2fib_add_del,                                                        \
20535   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
20536 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
20537 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
20538 _(l2_flags,                                                             \
20539   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20540 _(bridge_flags,                                                         \
20541   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20542 _(tap_connect,                                                          \
20543   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
20544 _(tap_modify,                                                           \
20545   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
20546 _(tap_delete,                                                           \
20547   "<vpp-if-name> | sw_if_index <id>")                                   \
20548 _(sw_interface_tap_dump, "")                                            \
20549 _(ip_table_add_del,                                                     \
20550   "table-id <n> [ipv6]\n")                                              \
20551 _(ip_add_del_route,                                                     \
20552   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
20553   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
20554   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
20555   "[multipath] [count <n>]")                                            \
20556 _(ip_mroute_add_del,                                                    \
20557   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
20558   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
20559 _(mpls_table_add_del,                                                   \
20560   "table-id <n>\n")                                                     \
20561 _(mpls_route_add_del,                                                   \
20562   "<label> <eos> via <addr> [table-id <n>]\n"                           \
20563   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
20564   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
20565   "[multipath] [count <n>]")                                            \
20566 _(mpls_ip_bind_unbind,                                                  \
20567   "<label> <addr/len>")                                                 \
20568 _(mpls_tunnel_add_del,                                                  \
20569   " via <addr> [table-id <n>]\n"                                        \
20570   "sw_if_index <id>] [l2]  [del]")                                      \
20571 _(proxy_arp_add_del,                                                    \
20572   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
20573 _(proxy_arp_intfc_enable_disable,                                       \
20574   "<intfc> | sw_if_index <id> enable | disable")                        \
20575 _(sw_interface_set_unnumbered,                                          \
20576   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
20577 _(ip_neighbor_add_del,                                                  \
20578   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
20579   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
20580 _(reset_vrf, "vrf <id> [ipv6]")                                         \
20581 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
20582 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
20583   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
20584   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
20585   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
20586 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
20587 _(reset_fib, "vrf <n> [ipv6]")                                          \
20588 _(dhcp_proxy_config,                                                    \
20589   "svr <v46-address> src <v46-address>\n"                               \
20590    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
20591 _(dhcp_proxy_set_vss,                                                   \
20592   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
20593 _(dhcp_proxy_dump, "ip6")                                               \
20594 _(dhcp_client_config,                                                   \
20595   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
20596 _(set_ip_flow_hash,                                                     \
20597   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
20598 _(sw_interface_ip6_enable_disable,                                      \
20599   "<intfc> | sw_if_index <id> enable | disable")                        \
20600 _(sw_interface_ip6_set_link_local_address,                              \
20601   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
20602 _(ip6nd_proxy_add_del,                                                  \
20603   "<intfc> | sw_if_index <id> <ip6-address>")                           \
20604 _(ip6nd_proxy_dump, "")                                                 \
20605 _(sw_interface_ip6nd_ra_prefix,                                         \
20606   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
20607   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
20608   "[nolink] [isno]")                                                    \
20609 _(sw_interface_ip6nd_ra_config,                                         \
20610   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
20611   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
20612   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
20613 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
20614 _(l2_patch_add_del,                                                     \
20615   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20616   "enable | disable")                                                   \
20617 _(sr_localsid_add_del,                                                  \
20618   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
20619   "fib-table <num> (end.psp) sw_if_index <num>")                        \
20620 _(classify_add_del_table,                                               \
20621   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
20622   " [del] [del-chain] mask <mask-value>\n"                              \
20623   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
20624   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
20625 _(classify_add_del_session,                                             \
20626   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
20627   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
20628   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
20629   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
20630 _(classify_set_interface_ip_table,                                      \
20631   "<intfc> | sw_if_index <nn> table <nn>")                              \
20632 _(classify_set_interface_l2_tables,                                     \
20633   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20634   "  [other-table <nn>]")                                               \
20635 _(get_node_index, "node <node-name")                                    \
20636 _(add_node_next, "node <node-name> next <next-node-name>")              \
20637 _(l2tpv3_create_tunnel,                                                 \
20638   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
20639   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
20640   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
20641 _(l2tpv3_set_tunnel_cookies,                                            \
20642   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
20643   "[new_remote_cookie <nn>]\n")                                         \
20644 _(l2tpv3_interface_enable_disable,                                      \
20645   "<intfc> | sw_if_index <nn> enable | disable")                        \
20646 _(l2tpv3_set_lookup_key,                                                \
20647   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
20648 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
20649 _(vxlan_add_del_tunnel,                                                 \
20650   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20651   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20652   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20653 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
20654 _(gre_add_del_tunnel,                                                   \
20655   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
20656 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
20657 _(l2_fib_clear_table, "")                                               \
20658 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
20659 _(l2_interface_vlan_tag_rewrite,                                        \
20660   "<intfc> | sw_if_index <nn> \n"                                       \
20661   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
20662   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
20663 _(create_vhost_user_if,                                                 \
20664         "socket <filename> [server] [renumber <dev_instance>] "         \
20665         "[mac <mac_address>]")                                          \
20666 _(modify_vhost_user_if,                                                 \
20667         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
20668         "[server] [renumber <dev_instance>]")                           \
20669 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
20670 _(sw_interface_vhost_user_dump, "")                                     \
20671 _(show_version, "")                                                     \
20672 _(vxlan_gpe_add_del_tunnel,                                             \
20673   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
20674   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20675   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
20676   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
20677 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
20678 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
20679 _(interface_name_renumber,                                              \
20680   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
20681 _(input_acl_set_interface,                                              \
20682   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20683   "  [l2-table <nn>] [del]")                                            \
20684 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
20685 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
20686 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
20687 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
20688 _(ip_dump, "ipv4 | ipv6")                                               \
20689 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
20690 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
20691   "  spid_id <n> ")                                                     \
20692 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
20693   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
20694   "  integ_alg <alg> integ_key <hex>")                                  \
20695 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
20696   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
20697   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
20698   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
20699 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
20700 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
20701   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
20702   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
20703   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
20704 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
20705 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
20706   "(auth_data 0x<data> | auth_data <data>)")                            \
20707 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
20708   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
20709 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
20710   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
20711   "(local|remote)")                                                     \
20712 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
20713 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
20714 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
20715 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
20716 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
20717 _(ikev2_initiate_sa_init, "<profile_name>")                             \
20718 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
20719 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
20720 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
20721 _(delete_loopback,"sw_if_index <nn>")                                   \
20722 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
20723 _(map_add_domain,                                                       \
20724   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
20725   "ip6-src <ip6addr> "                                                  \
20726   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
20727 _(map_del_domain, "index <n>")                                          \
20728 _(map_add_del_rule,                                                     \
20729   "index <n> psid <n> dst <ip6addr> [del]")                             \
20730 _(map_domain_dump, "")                                                  \
20731 _(map_rule_dump, "index <map-domain>")                                  \
20732 _(want_interface_events,  "enable|disable")                             \
20733 _(want_stats,"enable|disable")                                          \
20734 _(get_first_msg_id, "client <name>")                                    \
20735 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
20736 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
20737   "fib-id <nn> [ip4][ip6][default]")                                    \
20738 _(get_node_graph, " ")                                                  \
20739 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
20740 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
20741 _(ioam_disable, "")                                                     \
20742 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
20743                             " sw_if_index <sw_if_index> p <priority> "  \
20744                             "w <weight>] [del]")                        \
20745 _(one_add_del_locator, "locator-set <locator_name> "                    \
20746                         "iface <intf> | sw_if_index <sw_if_index> "     \
20747                         "p <priority> w <weight> [del]")                \
20748 _(one_add_del_local_eid,"vni <vni> eid "                                \
20749                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20750                          "locator-set <locator_name> [del]"             \
20751                          "[key-id sha1|sha256 secret-key <secret-key>]")\
20752 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
20753 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
20754 _(one_enable_disable, "enable|disable")                                 \
20755 _(one_map_register_enable_disable, "enable|disable")                    \
20756 _(one_map_register_fallback_threshold, "<value>")                       \
20757 _(one_rloc_probe_enable_disable, "enable|disable")                      \
20758 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
20759                                "[seid <seid>] "                         \
20760                                "rloc <locator> p <prio> "               \
20761                                "w <weight> [rloc <loc> ... ] "          \
20762                                "action <action> [del-all]")             \
20763 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
20764                           "<local-eid>")                                \
20765 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
20766 _(one_use_petr, "ip-address> | disable")                                \
20767 _(one_map_request_mode, "src-dst|dst-only")                             \
20768 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
20769 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
20770 _(one_locator_set_dump, "[local | remote]")                             \
20771 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
20772 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
20773                        "[local] | [remote]")                            \
20774 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
20775 _(one_ndp_bd_get, "")                                                   \
20776 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
20777 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
20778 _(one_l2_arp_bd_get, "")                                                \
20779 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
20780 _(one_stats_enable_disable, "enable|disalbe")                           \
20781 _(show_one_stats_enable_disable, "")                                    \
20782 _(one_eid_table_vni_dump, "")                                           \
20783 _(one_eid_table_map_dump, "l2|l3")                                      \
20784 _(one_map_resolver_dump, "")                                            \
20785 _(one_map_server_dump, "")                                              \
20786 _(one_adjacencies_get, "vni <vni>")                                     \
20787 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
20788 _(show_one_rloc_probe_state, "")                                        \
20789 _(show_one_map_register_state, "")                                      \
20790 _(show_one_status, "")                                                  \
20791 _(one_stats_dump, "")                                                   \
20792 _(one_stats_flush, "")                                                  \
20793 _(one_get_map_request_itr_rlocs, "")                                    \
20794 _(one_map_register_set_ttl, "<ttl>")                                    \
20795 _(one_set_transport_protocol, "udp|api")                                \
20796 _(one_get_transport_protocol, "")                                       \
20797 _(show_one_nsh_mapping, "")                                             \
20798 _(show_one_pitr, "")                                                    \
20799 _(show_one_use_petr, "")                                                \
20800 _(show_one_map_request_mode, "")                                        \
20801 _(show_one_map_register_ttl, "")                                        \
20802 _(show_one_map_register_fallback_threshold, "")                         \
20803 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
20804                             " sw_if_index <sw_if_index> p <priority> "  \
20805                             "w <weight>] [del]")                        \
20806 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
20807                         "iface <intf> | sw_if_index <sw_if_index> "     \
20808                         "p <priority> w <weight> [del]")                \
20809 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
20810                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20811                          "locator-set <locator_name> [del]"             \
20812                          "[key-id sha1|sha256 secret-key <secret-key>]") \
20813 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
20814 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
20815 _(lisp_enable_disable, "enable|disable")                                \
20816 _(lisp_map_register_enable_disable, "enable|disable")                   \
20817 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
20818 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
20819                                "[seid <seid>] "                         \
20820                                "rloc <locator> p <prio> "               \
20821                                "w <weight> [rloc <loc> ... ] "          \
20822                                "action <action> [del-all]")             \
20823 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
20824                           "<local-eid>")                                \
20825 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
20826 _(lisp_use_petr, "<ip-address> | disable")                              \
20827 _(lisp_map_request_mode, "src-dst|dst-only")                            \
20828 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
20829 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
20830 _(lisp_locator_set_dump, "[local | remote]")                            \
20831 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
20832 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
20833                        "[local] | [remote]")                            \
20834 _(lisp_eid_table_vni_dump, "")                                          \
20835 _(lisp_eid_table_map_dump, "l2|l3")                                     \
20836 _(lisp_map_resolver_dump, "")                                           \
20837 _(lisp_map_server_dump, "")                                             \
20838 _(lisp_adjacencies_get, "vni <vni>")                                    \
20839 _(gpe_fwd_entry_vnis_get, "")                                           \
20840 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
20841 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
20842                                 "[table <table-id>]")                   \
20843 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
20844 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
20845 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
20846 _(gpe_get_encap_mode, "")                                               \
20847 _(lisp_gpe_add_del_iface, "up|down")                                    \
20848 _(lisp_gpe_enable_disable, "enable|disable")                            \
20849 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
20850   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
20851 _(show_lisp_rloc_probe_state, "")                                       \
20852 _(show_lisp_map_register_state, "")                                     \
20853 _(show_lisp_status, "")                                                 \
20854 _(lisp_get_map_request_itr_rlocs, "")                                   \
20855 _(show_lisp_pitr, "")                                                   \
20856 _(show_lisp_use_petr, "")                                               \
20857 _(show_lisp_map_request_mode, "")                                       \
20858 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
20859 _(af_packet_delete, "name <host interface name>")                       \
20860 _(policer_add_del, "name <policer name> <params> [del]")                \
20861 _(policer_dump, "[name <policer name>]")                                \
20862 _(policer_classify_set_interface,                                       \
20863   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20864   "  [l2-table <nn>] [del]")                                            \
20865 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
20866 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
20867     "[master|slave]")                                                   \
20868 _(netmap_delete, "name <interface name>")                               \
20869 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
20870 _(mpls_fib_dump, "")                                                    \
20871 _(classify_table_ids, "")                                               \
20872 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
20873 _(classify_table_info, "table_id <nn>")                                 \
20874 _(classify_session_dump, "table_id <nn>")                               \
20875 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
20876     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
20877     "[template_interval <nn>] [udp_checksum]")                          \
20878 _(ipfix_exporter_dump, "")                                              \
20879 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
20880 _(ipfix_classify_stream_dump, "")                                       \
20881 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
20882 _(ipfix_classify_table_dump, "")                                        \
20883 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
20884 _(sw_interface_span_dump, "[l2]")                                           \
20885 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
20886 _(pg_create_interface, "if_id <nn>")                                    \
20887 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
20888 _(pg_enable_disable, "[stream <id>] disable")                           \
20889 _(ip_source_and_port_range_check_add_del,                               \
20890   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
20891 _(ip_source_and_port_range_check_interface_add_del,                     \
20892   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
20893   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
20894 _(ipsec_gre_add_del_tunnel,                                             \
20895   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
20896 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
20897 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
20898 _(l2_interface_pbb_tag_rewrite,                                         \
20899   "<intfc> | sw_if_index <nn> \n"                                       \
20900   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
20901   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
20902 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
20903 _(flow_classify_set_interface,                                          \
20904   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
20905 _(flow_classify_dump, "type [ip4|ip6]")                                 \
20906 _(ip_fib_dump, "")                                                      \
20907 _(ip_mfib_dump, "")                                                     \
20908 _(ip6_fib_dump, "")                                                     \
20909 _(ip6_mfib_dump, "")                                                    \
20910 _(feature_enable_disable, "arc_name <arc_name> "                        \
20911   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
20912 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
20913 "[disable]")                                                            \
20914 _(l2_xconnect_dump, "")                                                 \
20915 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
20916 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
20917 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
20918 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
20919 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
20920 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
20921 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>] [disable]") \
20922 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")
20923
20924 /* List of command functions, CLI names map directly to functions */
20925 #define foreach_cli_function                                    \
20926 _(comment, "usage: comment <ignore-rest-of-line>")              \
20927 _(dump_interface_table, "usage: dump_interface_table")          \
20928 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
20929 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
20930 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
20931 _(dump_stats_table, "usage: dump_stats_table")                  \
20932 _(dump_macro_table, "usage: dump_macro_table ")                 \
20933 _(dump_node_table, "usage: dump_node_table")                    \
20934 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
20935 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
20936 _(echo, "usage: echo <message>")                                \
20937 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
20938 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
20939 _(help, "usage: help")                                          \
20940 _(q, "usage: quit")                                             \
20941 _(quit, "usage: quit")                                          \
20942 _(search_node_table, "usage: search_node_table <name>...")      \
20943 _(set, "usage: set <variable-name> <value>")                    \
20944 _(script, "usage: script <file-name>")                          \
20945 _(unset, "usage: unset <variable-name>")
20946 #define _(N,n)                                  \
20947     static void vl_api_##n##_t_handler_uni      \
20948     (vl_api_##n##_t * mp)                       \
20949     {                                           \
20950         vat_main_t * vam = &vat_main;           \
20951         if (vam->json_output) {                 \
20952             vl_api_##n##_t_handler_json(mp);    \
20953         } else {                                \
20954             vl_api_##n##_t_handler(mp);         \
20955         }                                       \
20956     }
20957 foreach_vpe_api_reply_msg;
20958 #if VPP_API_TEST_BUILTIN == 0
20959 foreach_standalone_reply_msg;
20960 #endif
20961 #undef _
20962
20963 void
20964 vat_api_hookup (vat_main_t * vam)
20965 {
20966 #define _(N,n)                                                  \
20967     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
20968                            vl_api_##n##_t_handler_uni,          \
20969                            vl_noop_handler,                     \
20970                            vl_api_##n##_t_endian,               \
20971                            vl_api_##n##_t_print,                \
20972                            sizeof(vl_api_##n##_t), 1);
20973   foreach_vpe_api_reply_msg;
20974 #if VPP_API_TEST_BUILTIN == 0
20975   foreach_standalone_reply_msg;
20976 #endif
20977 #undef _
20978
20979 #if (VPP_API_TEST_BUILTIN==0)
20980   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
20981
20982   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
20983
20984   vam->function_by_name = hash_create_string (0, sizeof (uword));
20985
20986   vam->help_by_name = hash_create_string (0, sizeof (uword));
20987 #endif
20988
20989   /* API messages we can send */
20990 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
20991   foreach_vpe_api_msg;
20992 #undef _
20993
20994   /* Help strings */
20995 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
20996   foreach_vpe_api_msg;
20997 #undef _
20998
20999   /* CLI functions */
21000 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
21001   foreach_cli_function;
21002 #undef _
21003
21004   /* Help strings */
21005 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21006   foreach_cli_function;
21007 #undef _
21008 }
21009
21010 #if VPP_API_TEST_BUILTIN
21011 static clib_error_t *
21012 vat_api_hookup_shim (vlib_main_t * vm)
21013 {
21014   vat_api_hookup (&vat_main);
21015   return 0;
21016 }
21017
21018 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
21019 #endif
21020
21021 /*
21022  * fd.io coding-style-patch-verification: ON
21023  *
21024  * Local Variables:
21025  * eval: (c-set-style "gnu")
21026  * End:
21027  */